How to Update Your Existing iOS Framework to Work With Swift Package Manager
Cocoapods, Carthage -> SPM
For the last couple of years, I’ve been managing an iOS framework created by me with small utilities that I kept reusing throughout my projects. It’s no big deal, but it’s a good exercise for me in creating, updating, documenting, and testing a framework.
This framework is available on GitHub as BartisUtilities (please excuse my narcissism). I didn’t see the need to publish it as Cocoapod or as a Carthage project, as I mostly use snippets from it, and only a single personal project imports it completely. This is no problem for a single project, to build a new version of the framework in Xcode and just replace it in the project that it’s used. But if I had to do it in multiple projects, it would be a hassle.
Enter the Swift Package Manager. Sure, it’s not new, but as we saw during this year's WWDC, it got really easy to create Swift packages directly from Xcode 11.
Now, this is a pretty easy and straightforward process that should take no more than 30 minutes, so let’s get started.
You will, of course, need Xcode 11 and an existing iOS Framework.
- First, let’s take a look at the existing project structure.
You can see that it’s mostly structured into two groups: the actual source and one for unit tests. There is also a
README.md in the actual folder, but it’s not imported into the project. Let’s do that now, as it’s required for a Swift package.
2. To make our lives easier, and if it’s possible for everyone, I like to organise the project as it’s described in Apple’s official documentation, by renaming the groups to contain the actual words Package and Tests.
Then move them to a
Hint: You might need to update the
Info.plist paths in the project settings.
2. Now that our structure is ready, let’s generate the manifest. Sure, we can create it manually based on Apple’s sample, but why should we, when we can use the Swift toolchain to do that for us?
Open a terminal window in the root of the project and run
swift package init — type library
You should see output like this:
Alex@Maculetz BartisUtilities % swift package init — type library
Creating library package: BartisUtilities
When you look into your project, you should see that
Package.swift has shown up for the party.
3. a. At this point, it’s time to close our existing Xcode because we’re going to generate a new
In the same terminal window, run
swift package generate-xcodeproj
You should see a successful output like this:
Alex@Maculetz BartisUtilities % swift package generate-xcodeproj
Let’s open the new project and take a look.
First thing you’ll notice is that you now have all your folders in your root mapped to the Xcode project. In my case, it also added the
SampleApp to the project and all the Jazzy-generated documentation. It’s not an issue for me, but if it is for you, you can clean up your project structure as normal.
3. b. At this step, if you run into issues generating the new
.xcodeproj (as I have the first time I did this), add the path to the source files in the manifest file, in the
4. Build the newly created scheme
5. Test the newly created scheme
If everything is building and testing fine, we’re on to the last part: publishing.
6. Commit. Push. Create a tag for your current version.
You can now go into another project, tap on the project in the Project Navigator, select Swift Packages, and tap on +. Now paste the
.git URL like so: https://github.com/trusk89/BartisUtilities.git
Then tap Next until it’s imported.