Sign in
Log inSign up

Migrate Your iOS Project From Carthage To Swift Package Manager

Matheus Cardoso's photo
Matheus Cardoso
·Dec 2, 2020·

6 min read

Since Swift 5 and Xcode 11 were released, SPM became a viable dependency manager for many iOS projects. It's also been heavily improved upon in Xcode 12 with the support of binary frameworks and resource files such as storyboards, nibs, localization folders, asset catalogs, and core data models. It's now possible to use it in most if not all iOS projects. And most actively maintained dependencies such as Stream Chat support it.

Image shows Carthage logo with an arrow pointing to a Swift Package Manager logo

A Twitter poll showed that, while CocoaPods is number one at 46.5%, 11.4% of iOS developers still use Carthage as their preferred dependency manager. Swift Package Manager, though released most recently, is just behind with 42.1%.

Twitter poll shows 11.4% of Carthage usage, 46.5% of CocoaPods, and 42.1% of Swift Package Manager

It's clear that SPM, with all its recent updates and deep integration with the official iOS toolchain, will soon take over the other options. In this article, I'll present a process that you can use to fully migrate your projects from Carthage to Swift Package Manager. If you're also interested in migrating from CocoaPods, here's a CocoaPods version of this article: Migrate Your iOS Project From CocoaPods To Swift Package Manager.

Remove Carthage

Unlike CocoaPods, removing Carthage is an entirely manual process. You'll delete files and remove settings in your Xcode projects that reference Carthage. Most of these, you or someone on your team created manually, so what you must change can vary slightly.

Before you remove Carthage, it's important to note each dependency in your project and their versions. In my case, I was only using Stream Chat in version 2.5.0.

Now, let's remove Carthage from your project. After you took note of the contents of your Cartfile, you can remove it alongside Cartfile.resolved and the Carthage folder using the rm -rf command. In my case, I also had an Xcode 12 workaround script called carthage-build.sh that I won't be needing anymore.

Screen shows the terminal with Carthage related files being deleted using the rm command

Those commands removed all the Carthage-related folders and files but didn't remove the Carthage-related settings in your .xcodeproj.

Now, let's open the Xcode project and remove all frameworks in "Frameworks, Libraries, and Embedded Content" in your targets.

Screenshot shows Xcode with frameworks selected and an arrow to a minus sign

Your .xcodeproj likely contains an additional Build Phase for Carthage to copy the frameworks. You should remove it as well.

Screenshot shows Xcode with the Build Phases tab selected and an arrow pointing to an x where the Carthage build phase is

After you're done with these steps, you likely removed all Carthage references from your project. There could be more since the usage of Carthage can vary per project. Thank you, Carthage; you've been a good friend. 😢

Add SPM

After you've mourned the loss of Carthage, let's replace it with Swift Package Manager. Hopefully, you've taken notes of all the dependencies you had before.

Open your .xcodeproj, choose the option "Add Package Dependency" in File > Swift Packages, and paste the URL of your dependency's git repository. For example: "github.com/getstream/stream-chat-swift".

Screenshot shows Xcode with the Add Package Dependency dialog opened and Stream Chat iOS SDK GitHub URL in the input field

After pressing next, Xcode will look for the repository and automatically select the latest version tagged. If this version is compatible with the one you were using, you can press next. Otherwise, type the version you were using. After that, Xcode will download the dependency.

Screenshot shows an Xcode screen selecting a dependency version and an Xcode screen downloading that dependency

A repository may contain multiple targets. If that's the case, you should select only the ones you use.

Screenshot shows an Xcode screen with dependency targets to be selected

After you press finish, it's done! Though, you must repeat this process for each dependency you had.

It's possible that a dependency doesn't provide a Package.swift. In that case, it can't be used with Swift Package Manager. However, you can clone the repository and add Package.swift yourself or request the maintainers to do so. For example, see the commit adding SPM support to the Stream Chat iOS SDK.

Conclusion

I hope you were successful in transitioning your project to the future. It's only getting better from now on. If you need any help converting your project from Carthage to Swift Package Manager, feel free to reach out to me on Twitter: @cardosodev.