Excluir pod ao portar para mac com catalisador

14

Portar aplicativos para o Mac é finalmente possível graças ao Catalyst , o problema é que vários pods não suportam o AppKit. O mais comum seria o 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

Como é um tópico recente, não consegui encontrar documentos sobre como remover um pod da minha compilação para o macOS, mas mantê-lo para iOS e iPadO S.

É possível usar no código:

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

Mas essa parte do problema, a outra parte é vincular o pod apenas para iOS ...

Qual seria o melhor / mais fácil curso de ação quando a biblioteca não é vital para o macOS, mas ainda é desejada no iOS?

AncAinu
fonte

Respostas:

12

Após a resposta @ajgryc, consegui fazer uma solução elegante:

No seu podfile, adicione

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

Desde 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

E, em seguida, na fase de criação do script de execução do Fabric:

if [[$ARCHS != "x86_64"]]; then
  "${PODS_ROOT}/Fabric/run" [your usual key]
fi
AncAinu
fonte
3
Isso funciona bem para impedir que todos os CocoaPods sejam vinculados no MacCatalyst. Mude a terceira linha para if target.name.start_with?("Pods")para pegar todos os alvos de pod.
William Denniss
Isso não parece mais trabalhar com CocoaPods 1.8.4
tmm1
11
Eu tentei nos dois sentidos "se target.name.start_with? (" Pods ")" não funciona para mim também com cocoapods 1.8.4, fiquei abaixo do erro, qualquer um pode me orientar. em /Users/ios/Desktop/xxxxxx/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector(FIRConnectorUtils_d79571aba36a7d46e5c6ca87a6fec1c1.o) / arquivo de usuários do iOS para desktop / para Mac, mas para o arquivo Sim Catalyst, / para o objeto Sim, para o arquivo Mac Catalyst, / para iOS /xxxxxx/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector 'para arquitetura x86_64
Ankur Patel
11
Para o script de execução, você também pode usar:if [[ ${IS_MACCATALYST} != "YES" ]]; then "${PODS_ROOT}/Fabric/run" fi
Honghao Zhang
Você pode atualizar uma resposta para incluir um link para um problema nas vagens de cacau, para que as pessoas que estão lendo uma resposta possam fazer uma votação positiva? Isso deve ser suportado fora da caixa na minha opinião. github.com/CocoaPods/CocoaPods/issues/9364
KleMiX
8

Abra o arquivo Pods- $ projectname.release.xcconfig no diretório Pods do seu projeto e localize a linha OTHER_LDFLAGS. Adicione [sdk=iphone*]imediatamente após o nome da variável (por exemplo, o meu agora se parece com isso):

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

Isso define condicionalmente as opções de link apenas ao criar variantes do iphone, impedindo que o pod seja vinculado no OSX. É claro que você menciona, isso precisa ser combinado com #if !targetEnvironment(macCatalyst)e #endifem torno do código chamando o pod ou você vai ter erros vinculador.

Isso me permitiu superar o mesmo problema. (E caso você esteja se perguntando que outras coisas legais, além de variáveis ​​condicionais, você pode adicionar aos seus arquivos .xcconfig, veja uma referência que encontrei: https://pewpewthespells.com/blog/xcconfig_guide.html )

ajgryc
fonte
11
Eu dei a você a recompensa, mas aceitei minha própria resposta, pois dou uma solução pronta para facilitar a vida das pessoas, muito obrigado!
precisa saber é o seguinte
desculpe, mas onde está um arquivo Pods- $ projectname.release.xcconfig. Eu não sou capaz de encontrá-lo.
Ankur Patel 01/01
Na minha configuração, está em <Diretório do Projeto> / Pods / Arquivos de Suporte ao Destino / Pods- <Nome do Projeto>
ajgryc
esta solução não é recomendada, pois o xcconfig sempre se cria em todos os pod install. Eu recomendaria ler esta resposta de Fernando Moya de Rivas para a melhor alternativa
Oz Shabat
6

Com cocoapods 1.8.4, tive que adaptar a excelente resposta do @ AncAinu da seguinte maneira:

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
fonte
Para sua informação, a versão mais recente do Crashlytics agora é de código aberto e, portanto, compila diretamente para o Catalyst quando necessário. Esse hack não é mais necessário no caso do Crashlytics, mas pode ser útil com outros pods herdados.
tmm1 15/01
acima Nome da parte do projeto, temos que escrever o nome do arquivo do projeto? if target.name == "Pods- [MyProjectExample]". algo assim ou basta colar a resposta? porque doest trabalho para mim
Bartu Akman 16/01
Sim, você deve substituir pelo nome do seu projeto.
tmm1 17/01
Eu fiz tudo certo. if target.name == "Pods- [VPNoid]" limpa e constrói meu projeto novamente. mas ainda assim o erro está reclamando. Você tem alguma ideia?
Bartu Akman 17/01
11
Remova o[]
tmm1 17/01
3

Tenho uma solução atualizada que funciona para mim com os seguintes pods do Google:

  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
fonte
Estou tentando usar esta solução, pois parece a mais limpa, mas recebo este erro: 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_64uso exatamente o que você tem acima, menos o GoogleMobileAdse Google-Mobile-Ads-SDK. Por que estou recebendo isso?
fphelp
Não tenho certeza. Neste ponto, é hora de remover o tecido, não é? Não concordo que o Google tenha o direito de comprá-los, mas eles o fizeram e estão encerrando-o, então ...
Andy
Infelizmente, o uso do 'pod Crashlytics' instala automaticamente o Fabric (1.10.2). Não sei por que isso acontece e sou cauteloso ao usar o pod 'Firebase / Crashlytics' porque o Google diz que ainda está na fase beta :(
fphelp
3

Para a melhor abordagem de manipulação de estruturas de suporte não suportadas para o Catalyst, vocês devem ler a solução de Fernando Moya de Ri .

Ele basicamente disse que você só precisa definir uma matriz de todas as libs você não deseja instalar no Mac OSX, como este: ['Fabric', 'Crashlytics', 'Firebase/Core', ...].

Em seguida, seu arquivo pod pode parecer simples assim:

# 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
fonte
2
Obrigado! Esta deve ser uma solução muito completa!
WildCat 28/03