Exclure le pod lors du portage sur mac avec catalyseur

14

Le portage d'applications sur mac est enfin possible grâce à Catalyst , le problème est que de nombreux pods ne prennent pas en charge AppKit. Le plus courant serait Crashlytics / Firebase.

In [...]/Pods/Crashlytics/iOS/Crashlytics.framework/Crashlytics(CLSInternalReport.o), building for Mac Catalyst, but linking in object file built for iOS Simulator, file '[...]/Pods/Crashlytics/iOS/Crashlytics.framework/Crashlytics' for architecture x86_64

Puisqu'il s'agit d'un sujet récent, je n'ai pas pu trouver de document sur la façon de supprimer un pod de ma version pour macOS, mais le conserver pour iOS et iPadO S.

Il est possible d'utiliser en code:

#if !targetEnvironment(macCatalyst) 
// Code to exclude for your macOS app
#endif

Mais cette partie du problème, l'autre partie est de lier le pod uniquement pour iOS ...

Quelle serait la ligne de conduite la plus simple / la meilleure lorsque la bibliothèque n'est pas vitale pour macOS mais toujours souhaitée sur iOS?

AncAinu
la source

Réponses:

12

Suite à la réponse de @ajgryc, j'ai pu créer une solution élégante:

Dans votre podfile, ajoutez

post_install do |installer|
    installer.pods_project.targets.each do |target|
        if target.name == "Pods-[Name of Project]"
            puts "Updating #{target.name} OTHER_LDFLAGS to OTHER_LDFLAGS[sdk=iphone*]"
            target.build_configurations.each do |config|
                xcconfig_path = config.base_configuration_reference.real_path
                xcconfig = File.read(xcconfig_path)
                new_xcconfig = xcconfig.sub('OTHER_LDFLAGS =', 'OTHER_LDFLAGS[sdk=iphone*] =')
                File.open(xcconfig_path, "w") { |file| file << new_xcconfig }
            end
        end
    end
end

Depuis Cocoapods 1.8.4

post_install do |installer|
  installer.pods_project.targets.each do |target|
    if target.name == "Pods-[Name of Project]"
      puts "Updating #{target.name} to exclude Crashlytics/Fabric"
      target.build_configurations.each do |config|
        xcconfig_path = config.base_configuration_reference.real_path
        xcconfig = File.read(xcconfig_path)
        xcconfig.sub!('-framework "Crashlytics"', '')
        xcconfig.sub!('-framework "Fabric"', '')
        new_xcconfig = xcconfig + 'OTHER_LDFLAGS[sdk=iphone*] = -framework "Crashlytics" -framework "Fabric"'
        File.open(xcconfig_path, "w") { |file| file << new_xcconfig }
      end
    end
  end
end

Et puis dans la phase d'exécution du script de construction pour Fabric:

if [[$ARCHS != "x86_64"]]; then
  "${PODS_ROOT}/Fabric/run" [your usual key]
fi
AncAinu
la source
3
Cela fonctionne bien pour désactiver tous les CocoaPods d'être liés dans MacCatalyst. Remplacez la troisième ligne par if target.name.start_with?("Pods")pour attraper toutes les cibles du pod.
William Denniss
Cela ne semble plus fonctionner avec les cocoapods 1.8.4
tmm1
1
J'ai essayé dans les deux sens "si target.name.start_with? (" Pods ")" ne fonctionne pas pour moi aussi avec les cocoapods 1.8.4, j'ai obtenu une erreur en dessous, n'importe qui peut me guider. dans /Users/ios/Desktop/xxxxxx/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector(FIRConnectorUtils_d79571aba36a7d46e5c6ca87a6fec1c1.o), fichier de construction pour Mac Catalyst, mais iOS /xxxxxx/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector 'for architecture x86_64
Ankur Patel
1
Pour le script d'exécution, vous pouvez également utiliser:if [[ ${IS_MACCATALYST} != "YES" ]]; then "${PODS_ROOT}/Fabric/run" fi
Honghao Zhang
Pouvez-vous mettre à jour une réponse pour inclure un lien vers un problème dans les cabosses de cacao afin que les personnes qui lisent une réponse puissent le voter? À mon avis, cela devrait être pris en charge dès le départ. github.com/CocoaPods/CocoaPods/issues/9364
KleMiX
8

Ouvrez votre fichier Pods- $ projectname.release.xcconfig dans le répertoire Pods de votre projet et recherchez la ligne OTHER_LDFLAGS. Ajoutez [sdk=iphone*]immédiatement après le nom de la variable (à titre d'exemple, le mien ressemble maintenant à ceci):

OTHER_LDFLAGS[sdk=iphone*] = $(inherited) -ObjC -l"MailCore-ios" -l"c++" -l"iconv" -l"resolv" -l"xml2" -l"z"

Cela définit conditionnellement les options de lien uniquement lors de la création de variantes d'iphone, empêchant le pod d'être lié sur OSX. Bien sûr, comme vous le mentionnez, cela doit être combiné avec #if !targetEnvironment(macCatalyst)et #endifentourer le code appelant le pod ou vous obtiendrez des erreurs de l'éditeur de liens.

Cela m'a permis de surmonter le même problème. (Et au cas où vous vous demandez quelles autres choses intéressantes en plus des variables conditionnelles que vous pouvez ajouter à vos fichiers .xcconfig, voici une référence que j'ai trouvée: https://pewpewthespells.com/blog/xcconfig_guide.html )

ajgryc
la source
1
Je vous ai donné la prime, mais j'ai accepté ma propre réponse car je donne une solution prête à l'emploi qui facilitera la vie des gens, merci beaucoup!
AncAinu
désolé, mais où se trouve un fichier Pods- $ projectname.release.xcconfig. Je ne peux pas le trouver.
Ankur Patel
Dans ma configuration, il se trouve dans <Répertoire de projets> / Pods / Fichiers de support cible / Pods- <Nom du projet>
ajgryc
cette solution n'est pas recommandée car xcconfig se construit toujours dans chaque pod install. Je recommanderais de lire cette réponse de Fernando Moya de Rivas pour la meilleure alternative
Oz Shabat
6

Avec les cocoapods 1.8.4, j'ai dû adapter l'excellente réponse de @ AncAinu comme suit:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    if target.name == "Pods-[Name of Project]"
      puts "Updating #{target.name} to exclude Crashlytics/Fabric"
      target.build_configurations.each do |config|
        xcconfig_path = config.base_configuration_reference.real_path
        xcconfig = File.read(xcconfig_path)
        xcconfig.sub!('-framework "Crashlytics"', '')
        xcconfig.sub!('-framework "Fabric"', '')
        new_xcconfig = xcconfig + 'OTHER_LDFLAGS[sdk=iphone*] = -framework "Crashlytics" -framework "Fabric"'
        File.open(xcconfig_path, "w") { |file| file << new_xcconfig }
      end
    end
  end
end
tmm1
la source
Pour info, la dernière version de Crashlytics est désormais open-source et se compile donc directement pour Catalyst en cas de besoin. Ce hack n'est plus nécessaire dans le cas de Crashlytics, mais peut être utile avec d'autres pods hérités.
tmm1
ci-dessus Nom de la partie projet, nous devons écrire le nom du fichier projet? if target.name == "Pods- [MyProjectExample]". quelque chose comme ça ou simplement coller la réponse? parce que ça marche pour moi
Bartu Akman
Oui, vous devez remplacer par le nom de votre projet.
tmm1
J'ai tout bien fait. if target.name == "Pods- [VPNoid]" nettoyer et reconstruire mon projet. mais l'erreur continue de se plaindre. Avez-vous une idée?
Bartu Akman
1
Supprimer le[]
tmm1
3

J'ai une solution mise à jour qui fonctionne pour moi avec les pods Google suivants:

  pod 'FirebaseUI/Auth'
  pod 'FirebaseUI/Phone'
  pod 'FirebaseUI/Email'
  pod 'Firebase/Auth'
  pod 'Firebase/Analytics'
  pod 'Fabric', '~> 1.10.2'
  pod 'Firebase/Crashlytics'
  pod 'Firebase/AdMob'
post_install do |installer|
  installer.pods_project.targets.each do |target|
    if target.name.start_with?("Pods")
        puts "Updating #{target.name} to exclude Crashlytics/Fabric"
      target.build_configurations.each do |config|
        xcconfig_path = config.base_configuration_reference.real_path
        xcconfig = File.read(xcconfig_path)
        xcconfig.sub!('-framework "FirebaseAnalytics"', '')
        xcconfig.sub!('-framework "FIRAnalyticsConnector"', '')
        xcconfig.sub!('-framework "GoogleMobileAds"', '')
        xcconfig.sub!('-framework "Google-Mobile-Ads-SDK"', '')
        xcconfig.sub!('-framework "GoogleAppMeasurement"', '')
        xcconfig.sub!('-framework "Fabric"', '')
        new_xcconfig = xcconfig + 'OTHER_LDFLAGS[sdk=iphone*] = $(inherited) -framework "FirebaseAnalytics"  -framework "FIRAnalyticsConnector"  -framework "GoogleMobileAds" -framework "GoogleAppMeasurement" -framework "GoogleUtilities" "-AppMeasurement" -framework "Fabric"'
        File.open(xcconfig_path, "w") { |file| file << new_xcconfig }
      end
    end
  end
end
Andy
la source
J'essaie d'utiliser cette solution car elle a l'air la plus propre, mais je reçois cette erreur: ld: in /Users/<name>/source/<app>/Pods/Fabric/iOS/Fabric.framework/Fabric(Fabric.o), building for Mac Catalyst, but linking in object file built for iOS Simulator, for architecture x86_64j'utilise exactement ce que vous avez ci-dessus moins le GoogleMobileAdset Google-Mobile-Ads-SDK. Pourquoi est-ce que je reçois ça?
fphelp
Je ne suis pas sûr. À ce stade, il est temps de supprimer Fabric n'est-ce pas? Je ne suis pas d'accord que Google avait le droit de les acheter, mais ils l'ont fait et le ferment donc ...
Andy
Malheureusement, l'utilisation de «pod Crashlytics» installe automatiquement Fabric (1.10.2). Je ne sais pas pourquoi cela se produit et je suis prudent quant à l'utilisation du pod 'Firebase / Crashlytics', car Google dit que c'est encore au stade bêta :(
fphelp
3

Pour la meilleure approche de la gestion des cadres non pris en charge pour Catalyst, vous devriez lire la solution de Fernando Moya de Ri .

Essentiellement , il a dit que vous avez juste besoin de définir un tableau de tous les libs que vous ne souhaitez pas installer sur Mac OS X, comme ceci: ['Fabric', 'Crashlytics', 'Firebase/Core', ...].

Ensuite, votre fichier pod peut sembler simple comme ceci:

# Podfile
load 'remove_unsupported_libraries.rb'
target 'My target' do
   use_frameworks!
   # Install your pods
   pod ...
end

# define unsupported pods
def unsupported_pods
   ['Fabric', 'Crashlytics', 'Firebase/Core', ...]
end

# install all pods except unsupported ones
post_install do |installer|
   configure_support_catalyst installer, unsupported_pods
end
Oz Shabat
la source
2
Merci! Cela devrait être une solution très complète!
WildCat