platform :ios, '9.0'
use_frameworks!
abstract_target 'default_pods' do
pod 'AFNetworking', '~> 3'
target 'example'
end
pod install
or pod update
AFNetworking is installed with a Deployment Target of iOS 9.0.
AFNetworking is installed with a Deployment Target of iOS 8.0, which causes noticeable warnings like _/Users/coeur/example/Pods/AFNetworking/AFNetworking/AFURLSessionManager.m:163:30: 'setResumingHandler:' is only available on iOS 9.0 or newer_
Even if I manually change the Pods project Deployment Target to iOS 9.0, a simple pod update
will reset it to iOS 8.0.
I found the following workaround, adding a post_install hook:
platform :ios, '9.0'
use_frameworks!
abstract_target 'default_pods' do
pod 'AFNetworking', '~> 3'
target 'example'
end
post_install do |pi|
pi.pods_project.targets.each do |t|
t.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0'
end
end
end
Can you please provide a sample project and use the template given to you when you file a new issue?
@dnkoutso Done, with a screenshot.
@Coeur still dont think its a CocoaPods bug. The podspec of AFNetworking sets deployment target to 7.0 but I think because you are using Xcode 9.2 which does not contain iOS 7.0 it defaults to the next available version.
Podspecs can define their own deployment target which gets set by the CocoaPods library.
I do not see any particular issue with CocoaPods library here. Will close this one but please reply here if you feel strongly there is an issue here...
Yes, Xcode 9 drops iOS 7.0 support so that's why you get iOS 8.0 instead despite the podspec mentioning 7.0
@dnkoutso , you mean that in a Podspec, I can only forcibly define an _exact_ Deployment Target, I can't simply define the _minimal_ supported Deployment Target?
When I write a Podspec, I use platforms.ios to define what is _at least_ required to build, not to define what _must_ be built.
In all case, no matter the Podspec, it is an integration bug from CocoaPods to build for iOS 8+ when we want an iOS 9+ project.
@dnkoutso @Coeur
How to specify two different platforms in a pod,
I have two target, respectively, support for iOS 8 and iOS 9, how to distinguish?
I do not think this is supported currently.
@Jinxiansen , it doesn't even work for one single platform as described by this bug report. But if one day there is support for multi platforms, then the documentation will tell you. One suggestion could be:
abstract_target 'default_pods' do
target 'One' do
platform :ios, '8.0'
end
target 'Two' do
platform :ios, '9.0'
end
end
It's pure suggestion for the future: this is in no way a working piece of configuration in 2018
@Jinxiansen don't forget you have to do pod install
(or pod deintegrate && pod install
) to get the post_install to execute at least once. It will not work with only pod update
.
I think the deployment target version should be equal to the user target version.
If the pod target's deployment version is equal to iOS 9 which define by user target, the dependency will use their new api if they check the deploy version:
#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1100)
configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:configurationIdentifier];
#else
configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:configurationIdentifier];
#endif
The code from the AFNetworking
. In the podspec, there is a platforms":{"ios":"7.0","osx":"10.9","tvos":"9.0"}
. So the pod target is deploy to iOS 7.0, and the macro will always be false! AFNetworking
will always use the old api.
@dnkoutso
So, I have UICKeychainStore in Pods.xcodeproj.
Pods.xcodeproj has deployments targets:
Pods (Project) -> 9.0
UICKeychainStore -> 8.0
My App deployment target -> 9.3
I would like to keep them in sync in case of aesthetics.
@Coeur
If you can't reopen issue and it have not solved yet, it is time to make open-radar for CocoaPods.
+1
I was hoping the deployment target would be defined according to the platform specified.
platform :ios, '9.0'
Coeur's multiple platforms script seems wrong. I write a new one.
post_install do |pi|
# https://github.com/CocoaPods/CocoaPods/issues/7314
fix_deployment_target(pi)
end
def fix_deployment_target(pod_installer)
if !pod_installer
return
end
puts "Make the pods deployment target version the same as our target"
project = pod_installer.pods_project
deploymentMap = {}
project.build_configurations.each do |config|
deploymentMap[config.name] = config.build_settings['IPHONEOS_DEPLOYMENT_TARGET']
end
# p deploymentMap
project.targets.each do |t|
puts " #{t.name}"
t.build_configurations.each do |config|
oldTarget = config.build_settings['IPHONEOS_DEPLOYMENT_TARGET']
newTarget = deploymentMap[config.name]
if oldTarget == newTarget
next
end
puts " #{config.name} deployment target: #{oldTarget} => #{newTarget}"
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = newTarget
end
end
end
Add this to the Podfile
, then pod install may generate output like
...
Generating Pods project
Make the pods deployment target version the same as our target
AFNetworking
Release deployment target: 7.0 => 9.0
Debug deployment target: 7.0 => 9.0
Alpha deployment target: 7.0 => 9.0
FLEX
Release deployment target: 8.0 => 9.0
Debug deployment target: 8.0 => 9.0
Alpha deployment target: 8.0 => 9.0
...
@BB9z, I'm unsure what you mean by "seems wrong", as I'm successfully using the 7 lines workaround from my January 8th post.
But best thing would be to have the fix at CocoaPods level, so if you're confident you should make a pull request to fix CocoaPods regarding this.
@Coeur assume we had a podfile:
target 'One' do
platform :ios, '8.0'
pod 'A' # A has a deployment target 6.0, we want it build with 8.0
pod 'B' # B has a deployment target 7.0, we want it build with 8.0
end
target 'Two' do
platform :ios, '9.0'
pod 'A' # A has a deployment target 6.0, we want it build with 9.0
pod 'B' # B has a deployment target 7.0, we want it build with 9.0
end
In my options, your script will define the deployment targets for "One" and "Two" respectively. But actually, you change nothing. t.name
is the name of the pod target, not our application.
pi.pods_project.targets.each do |t|
# t is pod target, not our app target
p t.name # will log A and B
end
@BB9z The workaround from my January 8th post (second post of this thread) is certainly not for mixing deployment targets: it's for the issue reported in the preceeding post (first post of this thread), with a single desired deployment target (iOS 9 for instance).
I don't understand why people are diverging the discussion on supporting multiple deployment target when it doesn't even work correctly for one single unique deployment target: if the target is built for 9.0, then the Pods should build for 9.0, not for 8.0. That's all there is in this issue report.
It's nice to want to support more stuff, but it should come as fixes to the actual CocoaPods gem, not as complex workarounds in people's Podfile. This is an issue ticket, not a StackOverflow post. :)
It seems that it would make sense to bump the deployment target to the user project's value if it is higher than the podspec's deployment target. @dnkoutso can you think of any issues that may arise from doing that?
@amorde If person has one project/workspace for several targets ( for example, several "typical" targets ), these targets could be out of sync in "deployment target dimension", but Pods are shared between these "typical" targets.
Typical targets are either app extensions or cloned apps ( some teams have clones of their main app for rebranding reasons before "big daddy money income").
ah, I forgot that a target can specify a deployment target _lower_ than the project one. bummer.
There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates.
I believe the issue is duplicated with this one: https://github.com/CocoaPods/CocoaPods/issues/8069 but for my opinion current issue is better described
There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates.
@stale please keep it open.
Could somebody tell me why the CP use the min deployment version which be defined in the podspec. I could not find the reason.
Any ETA on a fix for this? It's extremely frustrating to have this revert every time we do a pod install or pod update.
@GiantBlue76 with a post_install
hook, as shown in the second post of the thread, the configuration is kept even after pod install
or pod update
.
And no, there won't be any ETA until someone gets their hands at a pull request. Could be you, could be anyone.
@GiantBlue76 with a
post_install
hook, as shown in the second post of the thread, the configuration is kept even afterpod install
orpod update
.And no, there won't be any ETA until someone gets their hands at a pull request. Could be you, could be anyone.
Thank you! This is a sufficient workaround. Much appreciated!
We should be treating this as a _minimum_, but there are certain situations this isn't handled properly.
I'll have a PR up for this relatively soon - targeting 1.8.0 release for this
I updated the script mentioned in this comment for those who:
generate_multiple_pod_projects
featureTo use this script run
pod deintegrate
pod install
source 'https://cdn.jsdelivr.net/cocoa/'
# This is your app's deployment target version
DEPLOYMENT_VERSION = '12.0'.freeze
DEPLOYMENT_TARGET_KEY = 'IPHONEOS_DEPLOYMENT_TARGET'.freeze
# All pods will have at least this version to prevent Xcode warnings
PODS_MIN_DEPLOYMENT_VERSION = '8.0'.freeze
platform :ios, DEPLOYMENT_VERSION
use_modular_headers!
install! 'cocoapods',
generate_multiple_pod_projects: true,
incremental_installation: true
target 'YourTarget' do
# Insert your pods
target 'YourTargetTests' do
inherit! :complete
# Insert your test pods
end
end
def fix_deployment_targets(installer)
installer.generated_projects.each do |project|
project.targets.each do |target|
target.build_configuration_list.build_configurations.each do |config|
if config.build_settings[DEPLOYMENT_TARGET_KEY].to_f < PODS_MIN_DEPLOYMENT_VERSION.to_f
config.build_settings[DEPLOYMENT_TARGET_KEY] = PODS_MIN_DEPLOYMENT_VERSION
puts "Successfully set #{DEPLOYMENT_TARGET_KEY} of target #{target.name} for config #{config.display_name} to #{PODS_MIN_DEPLOYMENT_VERSION}"
end
end
end
end
end
post_install do |installer|
fix_deployment_targets installer
end
My 2 cents: CocoaPods should not change a defined minimum deployment target. There is no bug here other than user error: trying to use a library with an unsupported minimum deployment target. The correct answer to this problem is for AFNetworking to drop support for iOS 7. FWIW it looks like they did do this recently: https://github.com/AFNetworking/AFNetworking/commit/b3c4a78aca208f4dae596968b3dffb39bb44efa6
Edit to add: On further thought, I'd almost consider it a bug that CocoaPods set the deployment target to 8 to begin with, if the podspec said 7. It should either fail to pod install
altogether or correctly set the version to 7 and let Xcode fail to compile (refusing to pod install
would be "nicer" IMO).
After thinking about this some more I agree with the above. CocoaPods is doing the right thing by following what the podspec claims to support, and if pod consumers want to change that they can do so using a post_install hook. At this point I don't consider this a bug.
@amorde The first line of the Podfile being platform :ios, '9.0'
, setting the xcconfig for an older version of iOS is the issue.
@Coeur that is the target platform for your project, not for each Pod that you want to include. It informs CocoaPods which compatible versions of dependencies to pull in.
There seems to be a misconception among folks in this thread about what a minimum deployment target means and the effects of setting one.
There are runtime API availability checks that can be used to properly support multiple versions of iOS in a single executable. The minimum deployment target lets a library or application run correctly on that version or higher. Furthermore updating the minimum deployment target can cause complication to fail (for deprecated methods that are removed), therefore it is not a good idea for a tool like this to change it.
@icecrystal23 please give us an example of such compilation failure when raising the minimum deployment target up.
If we (@amorde, @icecrystal23) consider it's not a bug, then we should change the documentation of platform
in the Podfile to be clear that platform :ios, '9.0'
isn't going to do what many people want.
We could write something like:
platform
Specifies the platform for which a static library should be built, but NOT the deployment target for which it should be built (the number in
platform :ios, '9.0'
is only to find a compatible version of the pod). The actual deployment target will be lower than specified, will have unused symbols and will cause you a lot of headache. To properly set the minimum deployment target, please always manually add a workaround like:post_install do |pi| pi.pods_project.targets.each do |t| t.build_configurations.each do |bc| bc.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0' end end end
where '9.0' is your actual minimum deployment target.
Looks like the most common error I see is actually a warning, but we tend to have "Treat warnings as errors" enabled so it causes failures in our libraries. Example, when moving the deployment target from 10 to 11:
'bottomLayoutGuide' was deprecated in iOS 11.0: Use view.safeAreaLayoutGuide.bottomAnchor instead of bottomLayoutGuide.topAnchor
Note that this will cause the behavior to be wrong even if it doesn't actually cause compilation to fail (ie, if you treat it as a warning instead of an error).
+1 to updating the documentation, however I still disagree with the assumption that the behavior you want is the behavior many people want. Either way, the documentation should be correct and clear about what the setting actually does.
+1 to this is a bug.
I write a SDK, and it supports iOS 6 and later. But I don't hope that user compile it with iOS 6, and I hope the user compile it with the latest iOS version ( or they support deploy version, eg: iOS 10).
I did many things to support new api to get better development way. But now, the CocoaPods will never compile the Pods target to use new api. As a SDK owner, I could not let my user use new api, it is too bad.
And, I am a developer for a app, too. I still hope use new api, but the CocoaPods could not support it. It is too bad.
Of cause, I could write a post_install
to fix it. But It is not a good way. I have 3 app targets with different deploy target version, it is too hard to write a hook.
Maybe, we could have a dsl to choice the way to user.
@icecrystal23
Am I right that you are talking about these two sets:
|Pod Deployment target|SDK Version|App Deployment Target|
|---|---|---|
|10.0|12.3|11.0|
|11.0|12.3|11.0|
Next, you are talking that behavior will be different if you switch these settings from set 1 to set 2 ( by updating dependency deployment target version to your app deployment target. ).
Is it correct now?
Next, in these assumptions, your app will be installed on devices with OS version _greater than or equal_ to App Deployment Target.
So, if an old framework has small deployment target and uses old symbols that _are_ removed or _obsoleted_ or _deprecated_ in newer OS versions, it _will compile_ and perfectly linked to your project?
But if you increase deployment target of this framework, it will cause errors and warnings and will block further development in case of deprecated/removed/obsoleted old stuff?
@lolgear mostly yeah. The point is that the library was developed using a specific minimum deployment target in mind. It will compile and link and work fine in an app with a higher minimum deployment target.
I did a little testing with a sample app and changing the minimum deployment target around. It appears that bottomLayoutGuide
seems to function correctly no matter which target is chosen. Changing the minimum deployment target to something higher seems to have no effect other than causing compilation warnings.
I don't understand what benefit would be gained from updating the minimum deployment target to something higher than what the library was written for. New APIs can still be accessed using availability APIs, like this:
if #available(iOS 11.0, *) { /* do new stuff */ } else { /* do old stuff */ }
@icecrystal23
I don't understand what benefit would be gained from updating the minimum deployment target to something higher than what the library was written for. [...]
I've posted this in #4859, but it seems very relevant here:
Since I have a deployment target of iOS 12 in my main app, my app doesn't build arm 32-bit code, but since some of the pods have a much lower deployment target they do. This leaves me with linking errors when I'm trying to archive the app, and the only fix I've found is to bump the deployment target to 12 on all my pods as well.
I think it would be very neat if CocoaPods could always propagate my platform :ios, '12.0' down to the individual pods deployment target. That way all pods would be optimized to run for the appropriate platform!
https://github.com/CocoaPods/CocoaPods/issues/4859#issuecomment-500838635
@LinusU you are then consuming the Pods in a way not intended by the authors. You can choose to apply that workaround, but it is not a good general policy that should be blindly applied to all pods.
@icecrystal23 you're probably wrong about that: pod authors may support MULTIPLE versions of iOS, while the podspec only let us define the minimum one.
[...] but it is not a good general policy that should be blindly applied to all pods.
I don't really see how that is sustainable, should I _only_ use pods that specifically targets iOS 12? That seems quite strange. Surely there should be no ill effects by compiling with a newer deployment target? 馃
You guys are still acting like you can't run a library built for iOS 8 on iOS 12. You can. It is a minimum deployment target. Meaning the library supports iOS 8 and newer.
I don't know what linker errors you are getting, but in general you can compile and link with older minimum targets just fine.
@LinusU A workaround for the specific issue of dropping 32-bit code when targeting iOS 11+ is to set ARCHS = "$(ARCHS_STANDARD_64_BIT)"
in your app target. CocoaPods _does_ automatically copy this setting to all Pods targets. (Xcode will give an "update to recommended settings" warning about this, but that seems like a lesser evil.)
@Westacular that's amazing, thanks!!
edit: I haven't been able to trigger this, would you mind elaborating on when it does that?
Xcode will give an "update to recommended settings" warning about this, but that seems like a lesser evil.
edit2: Ahhhh, read that the other way around, I thought that Xcode would ask me to go to ARCHS_STANDARD_64_BIT
if I targeted iOS 11+ 馃槃
Hmm, I wonder why it doesn't use ARCHS_STANDARD_64_BIT
for iOS 11+ then 馃
There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates.
This issue will be auto-closed because there hasn't been any activity for a few months. Feel free to open a new one if you still experience this problem :+1:
Most helpful comment
I found the following workaround, adding a post_install hook: