Excluir pod al portar a mac con catalizador

14

La transferencia de aplicaciones a Mac finalmente es posible gracias a Catalyst , el problema es que numerosos pods no admiten AppKit. El más común sería 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

Dado que es un tema reciente, no pude encontrar un documento sobre cómo eliminar un pod de mi compilación para macOS, pero lo mantengo para iOS y iPadO S.

Es posible usar en código:

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

Pero esa parte del problema, la otra parte, es vincular el pod solo para iOS ...

¿Cuál sería el mejor / más fácil curso de acción cuando la biblioteca no es vital para macOS pero aún se desea en iOS?

AncAinu
fuente

Respuestas:

12

Siguiendo la respuesta de @ajgryc, pude hacer una solución elegante:

En su podfile agregue

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

Y luego, en la fase de compilación del script de ejecución para Fabric:

if [[$ARCHS != "x86_64"]]; then
  "${PODS_ROOT}/Fabric/run" [your usual key]
fi
AncAinu
fuente
3
Esto funciona bien para deshabilitar que todos los CocoaPods se vinculen en MacCatalyst. Cambia la tercera línea a if target.name.start_with?("Pods")para atrapar todos los objetivos de Pod.
William Denniss el
Esto ya no parece funcionar con cocoapods 1.8.4
tmm1
1
Intenté en ambos sentidos "si target.name.start_with? (" Pods ")" no funciona para mí también con cocoapods 1.8.4, obtuve el siguiente error, cualquiera puede guiarme. en /Users/ios/Desktop/xxxxxx/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector(FIRConnectorUtils_d79571aba36a7d46e5c6ca87a6fec1c1.o), compilando para el archivo de objeto de Mac / catalium / Desktop / Mac. /xxxxxx/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector 'para arquitectura x86_64
Ankur Patel
1
Para el script de ejecución, también puede usar:if [[ ${IS_MACCATALYST} != "YES" ]]; then "${PODS_ROOT}/Fabric/run" fi
Honghao Zhang
¿Puedes actualizar una respuesta para incluir un enlace a un problema en las vainas de cacao para que las personas que leen una respuesta puedan votarla? Esto debería ser compatible de fábrica en mi opinión. github.com/CocoaPods/CocoaPods/issues/9364
KleMiX
8

Abra su archivo Pods- $ projectname.release.xcconfig en el directorio Pods de su proyecto y ubique la línea OTHER_LDFLAGS. Agregue [sdk=iphone*]inmediatamente después del nombre de la variable (como ejemplo, el mío ahora se ve así):

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

Eso establece condicionalmente las opciones de enlace solo al crear variantes de iPhone, evitando que el pod se vincule en OSX. Por supuesto, como mencionas, esto debe combinarse #if !targetEnvironment(macCatalyst)y #endifrodear el código que llama al pod o obtendrás errores de enlazador.

Esto me permitió superar el mismo problema. (Y en caso de que se pregunte qué otras cosas interesantes además de las variables condicionales puede agregar a sus archivos .xcconfig, aquí hay una referencia que encontré: https://pewpewthespells.com/blog/xcconfig_guide.html )

ajgryc
fuente
1
Te he dado la recompensa, pero acepté mi propia respuesta, ya que doy una solución inmediata que facilitará la vida de las personas, ¡muchas gracias!
AncAinu
lo siento, pero ¿dónde está el archivo Pods- $ projectname.release.xcconfig? No puedo encontrarlo.
Ankur Patel
En mi configuración está en <Directorio de proyectos> / Pods / Target Support Files / Pods- <Nombre del proyecto>
ajgryc
esta solución no se recomienda ya que xcconfig siempre se construye en cada uno pod install. Recomendaría leer la respuesta de Fernando Moya de Rivas para la mejor alternativa
Oz Shabat
6

Con cocoapods 1.8.4, tuve que adaptar la excelente respuesta de @ AncAinu de la siguiente manera:

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
fuente
Para su información, la última versión de Crashlytics ahora es de código abierto y, por lo tanto, se compila directamente para Catalyst cuando es necesario. Este truco ya no es necesario en el caso de Crashlytics, pero puede ser útil con otros pods heredados.
tmm1
en la parte anterior Nombre del proyecto, tenemos que escribir el nombre del archivo del proyecto? if target.name == "Pods- [MyProjectExample]". algo así o simplemente pegar la respuesta? porque funciona para mí
Bartu Akman
Sí, debe reemplazarlo con el nombre de su proyecto.
tmm1
Hice todo bien. if target.name == "Pods- [VPNoid]" limpia y construye mi proyecto nuevamente. pero aún así el error se queja. ¿Tienes alguna idea?
Bartu Akman
1
Retire el[]
tmm1
3

Tengo una solución actualizada que funciona para mí con los siguientes pods de 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
fuente
Estoy tratando de usar esta solución, ya que parece la más limpia, pero aparece este error: 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 exactamente lo que tienes arriba menos el GoogleMobileAdsy Google-Mobile-Ads-SDK. ¿Por qué estoy recibiendo esto?
fphelp
No estoy seguro. En este punto, es hora de eliminar Fabric, ¿no? No estoy de acuerdo con que Google tuviera derecho a comprarlos, pero lo hicieron y lo están cerrando así que ...
Andy
Lamentablemente, el uso de 'pod Crashlytics' instala automáticamente Fabric (1.10.2). No estoy seguro de por qué sucede eso y soy cauteloso al usar el pod 'Firebase / Crashlytics' porque Google dice que todavía está en la etapa beta :(
fphelp
3

Para el mejor enfoque de manejo de framweorks no compatibles para Catalyst, deberían leer la solución de Fernando Moya de Ri .

Básicamente dijo sólo tiene que definir una matriz de todas las librerías que no desea instalar en Mac OS X, como esto: ['Fabric', 'Crashlytics', 'Firebase/Core', ...].

Entonces, su archivo pod puede verse simple como este:

# 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
fuente
2
¡Gracias! ¡Esta debería ser una solución muy completa!
WildCat