Set deployment target for CocoaPods's pod - ios

I use CocoaPods to manage dependencies in my project. I've written Podfile:
target 'MyApp' do
platform :ios, '8.0'
# Uncomment this line if you're using Swift or would like to use dynamic frameworks
#use_frameworks!
# Pods for MyApp
pod 'KeepLayout', :git => 'https://github.com/iMartinKiss/KeepLayout', :tag => 'v1.6.0'
pod 'EasyMapping'
target 'MyAppTests' do
inherit! :search_paths
# Pods for testing
end
target 'MyAppUITests' do
inherit! :search_paths
# Pods for testing
end
end
This file works well with CocoaPods 0.x but I can't compile project after I've updated to CocoaPods 1.0. After I've run
pod update
I can't compile my project with error:
/Users/<...>/Pods/KeepLayout/Sources/KeepAttribute.m:195:1: Cannot synthesize weak property because the current deployment target does not support weak references
I've seen that every library is builded with different deployment target. For example KeepLayout is builded with 4.3 deployment target.
How I can determine build target for every pod dependency?

While some development versions of CocoaPods (as well as pre-1.0 versions) may have propagated the deployment target of the project down to the pods, this is no longer the case in 1.0. To work around this, the current developer recommends using a post-install hook.
Here's a brute force approach to force a hard-coded deployment target for every pod in the generated Pods project. Paste this at the end of your Podfile:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.2'
end
end
end

Since the Podfile uses a directive like platform :ios, '9.0' to specify "iOS Deployment Target" (aka IPHONEOS_DEPLOYMENT_TARGET) for the Pods/Pods.xcodeproj project, you just need to remove the Deployment Target info from each build target.
Do it by adding this to your Podfile
platform :ios, '9.0' # set IPHONEOS_DEPLOYMENT_TARGET for the pods project
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
end
end
end
Inspired by the github post and Alex Nauda's answer.

While the accepted answer by Alex Nauda is good, but letting the Pods inherit the target from the app might be a much better solution. 🚀
app_ios_deployment_target = Gem::Version.new('9.2') # Change to your current deployment target
platform :ios, app_ios_deployment_target.version
# Let Pods targets inherit deployment target from the app
# This solution is suggested here: https://github.com/CocoaPods/CocoaPods/issues/4859
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |configuration|
pod_ios_deployment_target = Gem::Version.new(configuration.build_settings['IPHONEOS_DEPLOYMENT_TARGET'])
if pod_ios_deployment_target <= app_ios_deployment_target
configuration.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
end
end
end
end

Here is the way to set deployment target permanently for pod targets.
Goto -> podfile -> Add below code
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = "12.0"
end
end
end

change target to "11.0"
platform :ios, '11.0'

1) Search for IPHONEOS_DEPLOYMENT_TARGET
2) Change the iOS Deployment Target

Related

CocoaPods ignoring minimum deployment target (IPHONEOS_DEPLOYMENT_TARGET) in post_install hook

I keep getting the following error from multiple pods when building my react native project in xcode. Some example pods include RNKeychain and RNSVG. Here’s an example from react-native-blur:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_RCTViewManager", referenced from:
_OBJC_CLASS_$_BlurViewManager in BlurViewManager.o
_OBJC_CLASS_$_VibrancyViewManager in VibrancyViewManager.o
I noticed some warnings about iOS versions such as 'UIBlurEffectStyleSystemChromeMaterial' is only available on iOS 13.0 or newer.
Digging into xcode, for some reason the "General -> Deployment Info" for each pod is set to iOS 11.0 but in my Podfile I have explicitly set the deployment target to platform :ios, '13.0'. It's widely accepted as the solution to add a post_install script to overwrite the deployment target of each individual pod, which I've done. See my Podfile below.
$RNFirebaseAsStaticFramework = true
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/#react-native-community/cli-platform-ios/native_modules'
platform :ios, '13.0'
target 'Foo' do
use_frameworks!
config = use_native_modules!
use_react_native!(
:path => config[:reactNativePath],
# to enable hermes on iOS, change `false` to `true` and then install pods
:hermes_enabled => false
)
target 'FooTests' do
inherit! :complete
# Pods for testing
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
end
end
react_native_post_install(installer)
__apply_Xcode_12_5_M1_post_install_workaround(installer)
end
end
I can fix the issue by manually adjusting the deployment target in xcode for each offending pod which complains with the error Undefined symbols for architecture x86_64:
What else could be overwriting the deployment info to ios 11.0? In case it's relevant using "react-native": "0.66.1",
The most infuriating thing is that every time I do pod install I have to manually tweak deployment info for each affected pod.

Build target MyNotificationService: Framework not found

I have a React Native app "MyApp" that has a "MyNotificationService" attached (i.e. NotificationService.appex embedded under the Frameworks, Libraries and Embedded Content in Xcode in target "MyApp").
Up until this point everything fine.
Now I want to add another pod to "MyApp" naming pod 'Google-Mobile-Ads-SDK', which does not have anything to do with MyNotificationService. I just want to install it, so I can access the Google-Mobile-Ads-SDK in "MyApp".
My Podfile looks like this
target 'MyApp' do
use_unimodules!
config = use_native_modules!
use_react_native!(
:path => config[:reactNativePath],
:hermes_enabled => false
)
# Additional Dependencies
...
pod 'Google-Mobile-Ads-SDK'
target 'MyNotificationService' do
use_native_modules!
inherit! :complete
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'NO'
# deletes each pods deployment target definition and instead uses the definition of the main project
config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
end
end
end
end
However, after I ran pod install, I tried to build the debug version of MyApp using XCode, but XCode complains:
Build Target MyNotificationService
Link MyNotificationService (arm64)
Directory not found for option '-F/Users/.../Library/Developer/Xcode/DerivedData/MyApp-abcabcabcabcabc/Build/Products/Debug-iphoneos/XCFrameworkIntermediates/GoogleAppMeasurement'
Directory not found for option '-F/Users/.../Library/Developer/Xcode/DerivedData/MyApp-abcabcabcabcabc/Build/Products/Debug-iphoneos/XCFrameworkIntermediates/GoogleMobileAds'
Directory not found for option '-F/Users/.../Library/Developer/Xcode/DerivedData/MyApp-abcabcabcabcabc/Build/Products/Debug-iphoneos/XCFrameworkIntermediates/UserMessagingPlatform'
But MyNotificationService has nothing to do with these Frameworks GoogleAppMeasurement, GoogleMobileAds and UserMessagingPlatform - those belong to the Google-Mobile-Ads-SDK and only the main target MyApp should need them.
How can I tell MyNotificationService that it should not care about these frameworks?
Did solve the problem with an abstract target, that has both "MyApp" and "MyNotificationService" as subtargets defined in it. The abstract target is not an actual Xcode target but rather a placeholder or a folder that defines the pods that both the "MyApp" and "MyNotificationService" should both have shared. To get "MyNotificationService" ignore everything related to the 'Google-Mobile-Ads-SDK', the pod 'Google-Mobile-Ads-SDK' is only defined in the subtarget "MyApp".
abstract_target 'Shared' do
use_unimodules!
config = use_native_modules!
use_react_native!(
:path => config[:reactNativePath],
# to enable hermes on iOS, change `false` to `true` and then install pods
:hermes_enabled => false
)
# Additional Dependencies
...
target 'MyApp' do
# no inherit statement means that target MyApp has all pods from the parent "Shared" accessible
pod 'Google-Mobile-Ads-SDK'
end
target 'MyNotificationService' do
# no inherit statement means that target MyNotificationService has all pods from the parent "Shared" accessible
use_native_modules!
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'NO'
# deletes each pods deployment target definition and instead uses the definition of the main project
config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
end
end
end
end

Change target ios version when installing new pod

Whenever I install a new pod project, and for example I install firebase libraries I always get installed libraries to be targeted for projects 8.0 or and I start changing them manually to be 9.0 or 14.0 because of the warning that I'm Getting.
Here it is the Podfile content:
platform :ios, '14.0'
target 'TestProject' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for TestProject
pod 'SDWebImageSwiftUI'
pod 'lottie-ios'
pod 'Firebase/Auth'
pod 'Firebase/Firestore'
end
How it is possible to update target iOS all at once, so I won't be updating all the libraries one by one?
Add this to your Podfile and then pod install.
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '14.0'
end
end
end
This will update all the Pod targets at once to your desired version.
Depending on your Podfile, Warren's answer might not be enough to set all targets to the new deployment target. I recommend using this post-install handler:
deployment_target = '14.0'
post_install do |installer|
installer.generated_projects.each do |project|
project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = deployment_target
end
end
project.build_configurations.each do |bc|
bc.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = deployment_target
end
end
end
This addition becomes important when you use options like install! 'cocoapods', :generate_multiple_pod_projects => true

Unable to build project with Stream Chat iOS SDK

I'm trying to use the new Stream iOS Chat SDK and am unable to get it to build after I install it via Cocoapods. The project was building with the other pods listed before we added StreamChat. I am using Xcode 10.2 (Does not work with 10.1), Swift 4.2, and Cocoapods version 1.7.4. We used the pod install command listed on Stream's website:
pod install --repo-update
Our Podfile looks like this:
platform :ios, '11.0'
inhibit_all_warnings!
target 'Project-iOS' do
use_frameworks!
# Pods for Project-iOS
pod 'ReachabilitySwift', '4.3.0'
pod 'SwiftKeychainWrapper', '3.2.0'
pod 'CropViewController'
pod 'StreamChat'
target 'Project-iOSTests' do
inherit! :search_paths
# Pods for testing
end
target 'Project-iOSUITests' do
inherit! :search_paths
# Pods for testing
end
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '4.2'
end
end
end
*Note that I tried this with and without the post_install bit at the end - but was having to manually change the pods to 4.2 since for many 5.0 isn't supported yet.
These are the errors I'm seeing when I try and build:
Edit: I also tried to get this running in a new blank project with just the StreamChat pod targeting iOS 11 (Basically just as the instructions on the site state for the ChatDemo) and ran into the same type of issues.
Related to your first question be sure to use Xcode 10.2 or later and Swift 5.
No need force pods to Swift 4.2. Try to remove these lines from your Podfile, then your project should compile without any errors:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '4.2'
end
end
end

Get App-Target(s) or Appname on CocoaPod post_install

Is there any way to access the apps target names (and NOT the pods target name) within the post_install cocoa-pods script?
platform :ios, '9.0'
target 'MyProject' do
pod '...'
end
post_install do |installer|
# i need my application target 'MyProject' here
end

Resources