Thanks to modern Swift tools, each library can live in its own repository and can be edited as a separate Xcode project. Let’s imagine a standard package like this:
├── Package.swift ├── Sources │ ├── Additions │ │ ├── Array+Additions.swift │ │ └── String+Additions.swift │ └── NativeKit │ └── Result.swift └── Tests ├── Additions │ ├── ArrayTests.swift │ └── StringTests.swift └── NativeKit └── ResultTests.swift
To create a project for editing this package in Xcode, we should run a short command like this:
$ swift package generate-xcodeproj
Not easy to remember but after 3-5 times you can type these words without looking into your Terminal history. What about more arguments though? Let’s assume we need to enable code coverage. Here is a necessary modification:
$ swift package generate-xcodeproj \ --enable-code-coverage
A bit more text but this still can be remembered. Wait, eventually you will need a custom configuration for Xcode:
$ swift package generate-xcodeproj \ --enable-code-coverage \ --xcconfig-overrides NativeKit.xcconfig
Now things are starting to get messy. This line is quite hard to remember but we really need it, because we want to use the latest and greatest build settings for the Xcode project, and it is better to avoid putting it under version control.
Of course such long commands should be automated, for example with a Bash script. However, in addition to the Xcode project generation, we would need to have another script for the cleanup, and even more if we use Carthage or CocoaPods.
A more convenient way for managing such sofisticated commands is to use Makefiles. Many developers avoid them, but in their simplest form these scripts are very easy to write and even easier to run. For instance:
$ make clean // Remove .xcodeproj $ make xcode // Generate and open .xcodeproj
To enable this feature for your Swift package, just create a new file in the package folder named
Makefile without any extension and copy-paste there something like this:
PRODUCT := $(shell basename $(PWD)) PROJECT := $(PRODUCT).xcodeproj .PHONY: clean xcode clean: rm -rf $(PROJECT) $(PROJECT): clean swift package generate-xcodeproj \ --enable-code-coverage xcode: $(PROJECT) open $(PROJECT)
Please note, each target is basically a Terminal command, which is easy to play with and polish for your needs.
If you prefer AppCode, add one more target:
.PHONY: clean xcode appcode appcode: clean $(PROJECT) open -a "AppCode" $(PROJECT)
And now you have another convenient shortcut:
$ make appcode
Next time I will explain how to manage multiple swift packages within a single Xcode workspace. Stay tuned!