24
votes

Exclure le pod lors du portage sur Mac avec Catalyseur

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.

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

Comme il s'agit d'un sujet récent, je n'ai pas trouvé de doc sur la façon de supprimer un pod de ma version pour macOS, mais je le garde pour iOS et iPadO S.

Il est possible d'utiliser dans le code:

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

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

Quel serait le plan d'action le plus simple / le meilleur lorsque la bibliothèque n'est pas vitale pour macOS mais toujours recherchée sur iOS?


1 commentaires

Hey op! Ce serait formidable de savoir si ma réponse vous a aidé! si c'est le cas, veuillez marquer la réponse comme la bonne réponse


6 Réponses :


12
votes

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 (par 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, ce qui empêche le pod d'être lié sur OSX. Bien sûr, comme vous le mentionnez, cela doit être combiné avec #if !targetEnvironment(macCatalyst) et #endif entourant 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 )


4 commentaires

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!


désolé, mais où est un fichier Pods- $ projectname.release.xcconfig. Je ne parviens pas à le trouver.


Dans ma configuration, il se trouve dans <Répertoire du projet> / Pods / Fichiers de support cible / Pods- <Nom du projet>


cette solution n'est pas recommandée car xcconfig se construit toujours à chaque pod install . Je recommanderais de lire cette réponse de Fernando Moya de Rivas pour la meilleure alternative



18
votes

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

Dans votre fichier pod, ajoutez

if [[$ARCHS != "x86_64"]]; then
  "${PODS_ROOT}/Fabric/run" [your usual key]
fi

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 de création du script d'exécution pour Fabric:

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


5 commentaires

Cela fonctionne bien pour empêcher tous les CocoaPod d'être liés dans MacCatalyst. Remplacez la troisième ligne par if target.name.start_with?("Pods") pour capturer toutes les cibles de pod.


Cela ne semble plus fonctionner avec les cocoapodes 1.8.4


J'ai essayé les deux sens "si target.name.start_with? (" Pods ")" ne fonctionne pas pour moi aussi avec les cocoapods 1.8.4, j'ai eu une erreur en dessous, n'importe qui peut me guider. dans / Users / ios / Desktop / xxxxxx / Pods / FirebaseAnalytics / Frameworks / ‌ FIRAnalyticsConnecto‌ r.framework / FIRAnaly‌ ticsConnector (FIRCon‌ nectorUtils_d79571ab‌ a36a7d46e5c6ca87a6fe‌ c1c1.o), construit pour le fichier d'objet Mac Catalyst, mais construit pour pour iOS Simulator, fichier '/ Users / ios / Desktop / xxxxxx / Pods / FirebaseAnalytics / Frameworks‌ / FIRAnalyticsConnect‌ ou.framework / FIRAnal‌ yticsConnector' pour l'architecture x86_64


Pour le script d'exécution, vous pouvez également utiliser: if [[ ${IS_MACCATALYST} != "YES" ]]; then "${PODS_ROOT}/Fabric/run" fi


Pouvez-vous mettre à jour une réponse pour inclure un lien vers un problème dans les cabosses de cacao afin que les personnes lisant une réponse puissent la voter? Cela devrait être pris en charge hors de la boîte à mon avis. github.com/CocoaPods/CocoaPods/issues/9364



7
votes

Avec les cocoapodes 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


5 commentaires

Pour info, la dernière version de Crashlytics est désormais open-source et 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.


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


Oui, vous devez le remplacer par le nom de votre projet.


J'ai tout bien fait. if target.name == "Pods- [VPNoid]" nettoyez et reconstruisez mon projet. mais l'erreur se plaint toujours. Avez-vous une idée?


Supprimer le []



9
votes

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

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
  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'


6 commentaires

J'essaie d'utiliser cette solution car elle semble la plus propre, mais j'obtiens 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_64 j'utilise exactement ce que vous avez ci-dessus moins GoogleMobileAds et Google-Mobile-Ads-SDK . Pourquoi est-ce que je reçois ça?


Je ne suis pas sûr. À ce stade, il est temps de supprimer Fabric, n'est-ce pas? Je ne suis pas d'accord pour dire que Google avait le droit de les acheter, mais ils l'ont fait et sont en train de le fermer, alors ...


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 :(


Est-ce que quelqu'un obtient un échec de construction avec l'erreur «contenu non scellé présent dans la racine du bundle» en faisant cela?


Tu es incroyable. Une bouée de sauvetage absolue.


@ user13138159 J'essaye la solution ci-dessus mais cela me donne l'erreur ld: in / Users / <name> / Desktop / <app> / Pods / GoogleAnalytics / Libraries / l‌ ibGoogleAnalytics.a (‌ GAITrackerImpl.o), building pour Mac Catalyst, mais lien dans le fichier objet construit pour iOS Simulator, fichier '/ Users / <nom> / Desktop / <app> / Pods / GoogleAnalytics / Libraries / ‌ libGoogleAnalytics.a‌' pour l'architecture x86_64 clang: erreur: linker la commande a échoué avec le code de sortie 1 (utilisez -v pour voir l'invocation) qu'ékzactly vous avez fait?



15
votes

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

Il a dit en gros que vous avez juste besoin de définir un tableau de toutes les bibliothèques que vous ne voulez pas installer sur mac osx, comme ceci: ['Fabric', 'Crashlytics', 'Firebase/Core', ...] .

Ensuite, votre fichier pod peut paraître 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


3 commentaires

Merci! Cela devrait être une solution très complète!


Je pense que cela devrait être la réponse acceptée maintenant. Notez simplement que je pense qu'il nécessite Ruby 2.6.3 pour éviter une erreur lorsqu'il appelle filter


Je suis maintenant passé à la réponse acceptée, car cela semble être le consensus :)



3
votes

Sur la base de ce qui a déjà été discuté ici ... voici ma solution pour les projets à cibles multiples. Il valide essentiellement l'utilisation des bibliothèques sur chaque cible au lieu de suivre le nom de la cible.

Generating Pods project

Found 'Google-Mobile-Ads-SDK' on target 'Pods-TheApp'
Found 'FirebaseAnalytics' on target 'Pods-TheApp'
Preparing 'Pods-TheApp' for Catalyst

Found 'Google-Mobile-Ads-SDK' on target 'Pods-TheApp-TheAppTests'
Found 'FirebaseAnalytics' on target 'Pods-TheApp-TheAppTests'
Preparing 'Pods-TheApp-TheAppTests' for Catalyst

Found 'Google-Mobile-Ads-SDK' on target 'Pods-TheApp-TheApp_iOS_UI_Tests'
Found 'FirebaseAnalytics' on target 'Pods-TheApp-TheApp_iOS_UI_Tests'
Preparing 'Pods-TheApp-TheApp_iOS_UI_Tests' for Catalyst

Found 'Google-Mobile-Ads-SDK' on target 'Pods-TheAppIntentsExtension'
Found 'FirebaseAnalytics' on target 'Pods-TheAppIntentsExtension'
Preparing 'Pods-TheAppIntentsExtension' for Catalyst

Found 'Google-Mobile-Ads-SDK' on target 'Pods-TheAppTodayExtension'
Found 'FirebaseAnalytics' on target 'Pods-TheAppTodayExtension'
Preparing 'Pods-TheAppTodayExtension' for Catalyst

Il produit quelque chose comme ça

post_install do |installer|
    
    installer.pods_project.targets.each do |target|
        
        # handle non catalyst libs
        libs = ["FirebaseAnalytics", "Google-Mobile-Ads-SDK"]
        
        target.build_configurations.each do |config|
            xcconfig_path = config.base_configuration_reference.real_path
            xcconfig = File.read(xcconfig_path)
            values = ""
            
            libs.each { |lib|
                if xcconfig["-framework \"#{lib}\""]
                    puts "Found '#{lib}' on target '#{target.name}'"
                    xcconfig.sub!(" -framework \"#{lib}\"", '')
                    values += " -framework \"#{lib}\""
                end
            }
            
            if values.length > 0
                puts "Preparing '#{target.name}' for Catalyst\n\n"
                new_xcconfig = xcconfig + 'OTHER_LDFLAGS[sdk=iphone*] = $(inherited)' + values
                File.open(xcconfig_path, "w") { |file| file << new_xcconfig }
            end
        end
    end
end



0 commentaires