Use Swift Package Manager directly from within Xcode, w/o the cmdline
Breaking News from WWDC 2019: Xcode 11 is finally supporting Swift Package Manager. Rendering this project obsolete.
Use Swift packages directly from within Xcode, w/o having to jump to the Terminal. With swift builds, in a non-annoying way. Build large dependencies once, not for every project. Do not require an Internet connection just to create a new project.
... finally got sherlocked at WWDC 2019!
Too much text? Want a GIF? Here you go.
Goal (duration: a few seconds):
Package.swift
and build.State of the art (duration: some minutes or more):
mkdir MyProject
. Do a cd MyProject
.swift package init
, kitura init
, or something similar.swift package generate-xcodeproj
to create the Xcode project.MyProject.xcodeproj
, find and select the right schemeCalling swift build
as a tool is somewhat expensive.
Goal:
Instead of doing calling swift build
on every build,
do a swift build
only if the Package.swift
changes.
Produces a static library (pretty big, bundles up all the packages),
which is directly linked against the Xcode target.
State of the art: When you create a new Swift Package Manager project, for instance a Kitura endpoint, the initial setup takes a long time:
For a plain Kitura HelloWorld this is about 3-5 minutes before you can get going, even on a fast machine.
But worse: This has to be done every single time you create a new project! Want to create HelloKitten? Another 3mins lost. HelloCow? Again.
Goals, alongside goal 1:
Internet is only required when you install an image, once. After that, the bundled image is available and as many projects as desired can be created.
brew tap swiftxcode/swiftxcode
brew install swift-xcode
swift xcode link-templates # <-- important!
Images are pairs of Xcode templates and precompiled Swift packages (used by those templates). The precompilation happens when you install a Homebrew image formula (or manually using the GIT repo) and can take some time. Afterwards you can create new Xcode projects using those templates, without having to wait for the SPM bootstrap (fetch and compilation of the dependencies).
Find it here: SwiftXcode/SwiftNIO_XcodeImage.
brew install swift-xcode-nio
swift xcode link-templates # <-- important!
Find it here: SwiftXcode/Kitura_XcodeImage.
(One time) compile time: ~5 minutes. Image size: ~100MB. Fresh project setup from create to run: 3 seconds.
brew install swift-xcode-kitura
swift xcode link-templates # <-- important!
Find it here: SwiftObjects/SwiftObjects_XcodeImage.
brew install swift-xcode-wo
swift xcode link-templates # <-- important!
Find it here: SwiftXcode/RxSwift_XcodeImage.
(not in Homebrew)
Here is the basic version:
cows
import cows
, do print(cows.vaca())
The functionality can be added to any existing project, there is no requirement to use the templates.
Steps:
Package.swift
in your project,
DO NOT ADD it to the Xcode targetswift xcode build
(optionally prefixed by an SPM_IMAGE=ImageYouWantToUse
)HEADER_SEARCH_PATHS
$(SRCROOT)/$(PRODUCT_NAME)/.buildzz/.build/Xcode/$(PLATFORM_PREFERRED_ARCH)-apple-$(SWIFT_PLATFORM_TARGET_PREFIX)$($(DEPLOYMENT_TARGET_SETTING_NAME))/$(CONFIGURATION)
SWIFT_INCLUDE_PATHS
$(SRCROOT)/$(PRODUCT_NAME)/.buildzz/.build/$(PLATFORM_PREFERRED_ARCH)-apple-$(SWIFT_PLATFORM_TARGET_PREFIX)$($(DEPLOYMENT_TARGET_SETTING_NAME))/$(CONFIGURATION)
LIBRARY_SEARCH_PATHS
$(SRCROOT)/$(PRODUCT_NAME)/.buildzz/.build/Xcode/$(PLATFORM_PREFERRED_ARCH)-apple-$(SWIFT_PLATFORM_TARGET_PREFIX)$($(DEPLOYMENT_TARGET_SETTING_NAME))/$(CONFIGURATION)
OTHER_LDFLAGS
-lXcodeSPMDependencies
If you do this a lot and you don't want to use the templates,
create an xcconfig
file to carry the settings,
and just add that to your project.
We also provide an xcconfig you can use/include:
/usr/local/lib/xcconfig/swift-xcode.xcconfig
.
Supposed to work fine, patches welcome!
Note that swift-xcode
is not really a package manager on its own.
The package manager is still the official
Swift Package Manager,
just enhanced a little.
So you inherit a lot of its limitations. For example it cannot deal with resources, produce frameworks, or bundles. Yet, you can still build reusable modules with it.
So is it a replacement for Cocoa Pods or Carthage? In some cases it can be. In other cases it can't :-)
Brought to you by The Always Right Institute and ZeeZide. We like feedback, GitHub stars, cool contract work, presumably any form of praise you can think of.