TL;DR: CocoaPods 1.1.0 has been released, and it comes with improved support for extensions, frameworks, and new Swift versions, as well as Xcode 8 support and error handling improvements.
CocoaPods 1.1.0 has been released! This release features improvements for integrating extension targets into your projects, as well as support for the latest from Apple: Xcode 8, new extensions types, and the latest iOS. Specifically for those of you working with extension targets, this means smoother App Store submissions. For Xcode 8 and iOS 10, this release has support for the new Swift version settings when building your project and distributing your pods, and it has support for new target types like messages extensions and messages applications. Finally, we've integrated some new error recovery tooling to help when you encounter an unexpected error using CocoaPods, and we've made some performance improvements to
pod install when running it for large projects.
This update improves support for integrating extension and framework targets. Extensions targets are a bit different than application targets because they require a host app. For CocoaPods, this means that
pod install has to locate any host targets, in which the extension belongs, to integrate those extension targets' dependencies there. This seems counterintuive at first because Xcode has no problem installing frameworks into extensions the same way that it installs them into application targets. But, when you go to submit your app with its extensions to the App Store, you will probably get some combination of these responses:
Invalid Bundle. The bundle at 'MyApp.app/PlugIns/MyExtension.appex' contains disallowed nested bundles.
Invalid Bundle. The bundle at 'MyApp.app/PlugIns/MyExtension.appex' contains disallowed file Frameworks.
It turns out that Apple expects extensions to have their framework dependencies installed in their host apps: at launch time, extensions look into their host apps' bundles to find the frameworks they need. CocoaPods 1.1.0 understands this, and it integrates your extension target's dependencies into the right place.
Frameworks work about the same way. A framework's dependencies must also be installed alongside that framework, into whichever targets that are going to consume that framework. There are a few new frameworks scenarios, of which CocoaPods 1.1.0 is now mindful. In each scenario below, the framework is listed in the Podfile and has some pods:
- Framework(s) in your application-type project
- Framework(s) in your application-type project, where the framework may live in a sub-project (i.e. an Xcode project within your Xcode project)
- Framework(s)-only projects (for doing framework development)
In every case,
pod install looks through each of your project's non-framework target's "Target Dependencies" build phase to find where the framework is meant to be integrated (same for extensions as well). For framework-only projects, if CocoaPods can tell that your project only contains framework targets, then it assumes that the project must be a framework-only project (for doing framework development) and emits a warning about this assumption. In that case, CocoaPods doesn't have much to do except ensure your project's targets have the headers to build properly.
Xcode 8 and iOS 10
Xcode 8 is here! It brings support for iOS 10, macOS Sierra, new versions of Swift, and new challenges for CocoaPods. The first is the ability to support Swift 2.3 and 3.0 projects. In CocoaPods 1.1.0, setting the version of Swift when linting and pushing your pod is supported in following ways:
- It defaults to Swift 3.0, if your pod uses Swift.
- It uses the setting from your
.swift-versionfile if present (inspired by swiftenv).
--swift-versionflag can be used to specify a version of Swift to use. This overrides the version set in the
Finally, iOS 10 makes some new extension and application types available. In particular, CocoaPods has been updated to recognize the messages extensions and application product types.
About Supporting Multiple Swift Versions in the Podspec
Because Swift doesn't use semantic versioning, supporting the Swift language version used by a pod as part of the podspec is tricky. There are a few different options we considered, but we ultimately decided not to add any new podspec dsl for this release. Here are some examples of options we considered:
We could add a
swift_versionoption to indicate which version of Swift the pod supports. This would force authors to push new versions of their pods to update this setting when new versions of Swift come out, even if the new version of Swift is backwards compatible. This isn't ideal.
This could be helped by instead supporting a
min_swift_versionoption to indicate the minimum Swift version the pod supports. This wouldn't force authors to update their pods when new versions come out, but it would break if a new version of Swift comes out that is not backwards compatible with the one used to build the pod.
We could add a
swift_version_rangeoption to indicate the range of Swift versions the pod supports, but this suffers from the same issues as option 2. There is no way to verify that a pod pushed today that claims to support up through Swift version 4 actually supports that version.
In this release of CocoaPods, you lint your pod against the version of Swift you intend to support. When integrating pods, CocoaPods generates pod targets that use the Swift version set in your project. This allows pod authors the flexibility to support multiple incompatible swift versions if they wish by using
#if swift() checks, while keeping the pod maintenance burden light across Swift 3 versions.
Additionally, the version of Swift that was used to pass validation is baked into the podspec JSON file that is pushed to trunk. For tool authors, this makes it easy to use the database of pods on trunk to build reliable tooling that works with multiple versions of Swift.
Error Handling Improvements
Now when CocoaPods receives unexpected errors, it will highlight existing issues that might be related in the console. This makes it easier to find the answer to common issues. We do this by using gh_inspector, which you may have seen inside Fastlane too.
CocoaPods 1.1.0 was a huge release, so congrats to everyone! Checkout the Changelog to get the full list of changes.