Swift Package Manager with iOSUsing
File > New > Project...
Package.swift file in your root project directory, add dependencies, then run
swift package fetch on the command line in the same directory. We’re not going to run
swift build because it will just complain.
Open the Xcode project and make sure it builds. Now we need to create a new Target for each dependency. Go to File > New > Target… and create a new “Cocoa Touch Framework” target for each dependency. Once your finished you should notice a bunch of new groups in your Project Navigator representing the new targets, I recommend placing these in a Dependencies group. You can also eliminate the ‘<target_name>.h’ files if you don’t need Obj-C support.
This step is a little tricky so read closely. We need to add all the files located in the dependency’s
Packages/DependencyName/Sources folder into our project. Select the dependency’s group in the Project Navigator and hold down ⌘ + ⌥ + A to add files, highlight all the files in the dependency’s Sources folder, click the options button in the bottom left to reveal the list of targets and be sure to add the files to the correct target before clicking Add. Also be sure to uncheck your project’s target so you don’t add them to both the dependency and your project, this is unnecessary.
Now we need to configure “Linked Frameworks and Libraries” for each dependency target. This requires knowing what dependencies depend on each other—the best way to understand this is to open up each dependency’s Package.swift file. Click through each Target in your project and go to General > Linked Frameworks and Libraries to click the + button. For your project target you will need to add all dependencies.
(Note: Dependencies are addative, meaning if Dep A requires Dep B and Deb B requires Deb C & D, you'll need to be sure Dep A has Deps B C & D in its Linked Frameworks and Libraries)
Everything should build at this point. If not then double check Linked Frameworks to ensure they are correctly added.
By creating all these new targets you’ve also added a bunch of folders to your project directory. Each one has a single
Info.plist file in them and I like to stuff these inside my project's
.xcodeproj file. Right click on the project file and choose Show Package Contents, then rename each
DependencyName_Info.plist and move them inside the project file. Then open
project.pbxproj in a text editor (not Xcode) and search for
INFOPLIST_FILE references. Replace:
INFOPLIST_FILE = DependencyName/Info.plist; with
ProjectName.xcodeproj/DependencyName_Info.plist;. The next time you open your Xcode project you will see red
Info.plist files in your dependency folders, you can delete those.
Problems with approach:
- This is a manual process prone to error—someone could probably write a script
🤔. Hopefully Apple will add iOS support to the
swift package generate-xcodeprojcommand-line utility.
- When you run
swift package updateyou’ll need to then manually examine all your dependency targets. If a file just changed it's fine, changes get picked up automatically but if new files were added or removed you'll need to account for those.
- This may not work as well for more complicated dependencies, I've only used it with very basic stuff.
Does this work? Any word on official SPM support for iOS soon? I really love SPM for macOS