Using Cocoapods from Swift

If you’ve been writing iOS apps for any length of time chances are good you’ve come across CocoaPods, the community-developed dependency manager for Objective-C. You’d be hard-pressed to find a significant iOS library or control that’s not primarily distributed via CocoaPods, and even harder-pressed to find iOS developers who don’t swear by it.

Integrating CocoaPods-distributed libraries into Objective-C projects is dead easy; unfortunately, we have to do a little extra work to access those same libraries from Swift. To show you how, I’m going to add Jonas Gessner’s JGProgressHUD to an existing Swift app. For this example I’m going to start with an empty Swift iOS application from Xcode’s templates.

First step is to add a ‘Podfile’ to the project; this is a file where you’ll list all of the CocoaPods-provided dependencies and versions that you want to use. Create an empty text file called ‘Podfile’ in same directory as your app’s .xcodeproj and paste in the following:

Next step is to run the CocoaPods utility to actually download and unpack our requested pod. If you haven’t yet installed CocoaPods, now would be a good time to do that (the TL;DR version: sudo gem install cocoapods in your Terminal). Bring up a Terminal, change into the directory that contains the Podfile we just created, then run:

pod install

This should think for a bit, then print out something like the following:

Analyzing dependencies
Downloading dependencies
Installing JGProgressHUD (1.2.2)
Generating Pods project
Integrating client project

[!] From now on use Your-App.xcworkspace.

That last bit seems like good advice. Close your Xcode project, and open up the newly created .xcworkspace in its place. You should see two subprojects, one for your existing application plus a new one called, helpfully, ‘Pods’.

Pods. What a helpful name.

Open up the CocoaPods-created .xcworkspace instead of your previous .xcodeproj

At this point we can build and run the app, and we’ll technically be building an app with JGProgressHUD linked in. If we had any Objective-C code in the app we could now access our newly installed Pod from there, but if we want to do so from Swift we’ve got to set up two more things: a bridging header and custom header search paths.

A bridging header is just an Objective-C header file that exposes one or more Objective-C classes to the Swift compiler, making them accessible from our Swift code. Create a new Objective-C header in your app project, and call it ‘Bridging-Header.h’:

Call it 'Bridging-Header.h'.

Call it ‘Bridging-Header.h’.

Open up your newly bridging header and add in a single #import statement to bring in your JGProgressHUD headers:

To actually use this header we need to tell the Swift compiler where it is, so open up your project’s build settings and find the Swift Compiler — Code Generation section. Change the project-level setting for Objective-C Bridging Header and change the value to point to our new header (e.g. Cocoapods-Example/Bridging-Header.h for a project called ‘Cocoapods-Example’.).

Configuring a bridging header. Obviously.

Configuring a bridging header. Obviously.

One last thing while we’re mucking about with our build settings: we need to tell Xcode where to look for the header files we’re listing in our bridging header. Find the Search Paths section, and change the project-level setting for User Header Search Paths, adding a recursive entry for the ‘Pods’ directory.

Recursive Pods are the best kind of Pods.

We can now make use of our new, CocoaPod-provided progress indicator as if it was any other piece of Cocoa code. For example, we could show a dark, brooding spinner whenever our main view controller appears on the screen (ViewController.swift):

If you got stuck anywhere in this tutorial you can always download the example project from this tutorial. Finally, here’s our progress indicator running in the world’s least-exciting Swift app:

Possibly the least-exciting iOS application ever developed.

Possibly the least-exciting iOS application ever developed.

Blurring the scene in SpriteKit

You know what’s pretty cool? SKEffectNode, that’s what. In the game I’m currently hacking on I wanted to have the screen slowly blur out underneath my UI, and a little mucking about with SKEffectNode and Core Image turned up a really nice-looking solution:

The above code will work nicely with the 2D cameras in Swift post. Since my UI is rendered in a separate node attached directly to the scene (and not attached to world), it doesn’t get blurred and everything looks nice and slick.

Blurred background, crisp UI.

Blurred background, crisp UI.

2D Camera in SpriteKit

One thing I missed when I started working with SpriteKit is a proper camera system. In my old, OpenGL ES-based game framework I had a meticulously built 2D camera system that I used literally all of the time; full-on game engines like Unity or Unreal usually have a 2- or 3D camera as a first-order primitive.

Apple’s SpriteKit docs hint at a solution (and give a partial implementation in Objective-C) — attach an empty node to your world and keep the view centred on its position. Below is a complete Swift implementation that sets up a 2d world with its origin at the centre of the screen, plus a camera to move the view within the world and a fixed overlay for showing HUD elements:

Change what’s visible in the world by moving the camera:

Singletons in Swift

I often find myself using singletons when I’m writing iOS apps, especially in games. They’re a perfect pattern for passing state between game screens and making sure that things like player progress are always up-to-date. In Objective-C I’ve always implemented thread-safe singletons using dispatch_once:

Using Grand Central Dispatch to set up a singleton always felt incredibly low-level, so I was pleased to discover a much nicer implementation using computed properties whilst porting some old code into Swift:

Mark the instance static to make it global, and declare it with let to mark it as a constant. The only weird bit (to me, at least) is wrapping the instance in a struct; Swift doesn’t allow static variables inside computed properties, and wrapping the instance in an internal struct lets us get around that restriction.

You can access the (lazily-created, thread-safe) singleton instance through the sharedInstance getter: