Porting apps to mac is finally possible thanks to Catalyst, problem is, numerous pods don\'t support AppKit. Most common one would be Crashlytics / Firebase
Following @ajgryc answer, I was able to make a sleek solution:
In your podfile add
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
Since 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
And then in run script build phase for Fabric:
if [[$ARCHS != "x86_64"]]; then
"${PODS_ROOT}/Fabric/run" [your usual key]
fi
With cocoapods 1.8.4, I had to adapt @AncAinu's excellent answer as follows:
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
For the best approach of handling unsupported framweorks for Catalyst, you guys should read the solution of Fernando Moya de Rivas.
He basically said you just need to define an array of all of the libs you don't want to install on mac osx, like this: ['Fabric', 'Crashlytics', 'Firebase/Core', ...].
Then, your pod file can look simple as this:
# 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
Open your Pods-$projectname.release.xcconfig file in your project's Pods directory, and locate the OTHER_LDFLAGS line. Add [sdk=iphone*] immediately after the variable name (as an example, mine now looks like this):
OTHER_LDFLAGS[sdk=iphone*] = $(inherited) -ObjC -l"MailCore-ios" -l"c++" -l"iconv" -l"resolv" -l"xml2" -l"z"
That conditionally sets the link options only when building iphone variants, preventing the pod from being linked on OSX. Of course as you mention, this needs to be combined with #if !targetEnvironment(macCatalyst) and #endif surrounding the code calling the pod or you'll get linker errors.
This allowed me to get past the same problem. (And in case you're wondering what other cool things besides conditional variables you can add to your .xcconfig files, here's a reference I found: https://pewpewthespells.com/blog/xcconfig_guide.html )
I have an updated solution that works for me with the following Google pods:
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
Based on what has already been discussed here... here is my solution for projects with multiple targets. It basically is validating the usage of the libs on each target instead of following the target name.
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
It outputs something like this
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