Software Development Tips and Tricks


Introducing the Swift Package Manager

Linux Swift 2.2

Update: If you don’t have Swift installed yet, head on over to our Ubuntu Packages page and get the latest with apt-get install.

In today’s world any serious programming language is going to come with a package manager, an application designed to aid managing the distribution and installation of software “packages”. Ruby has a de jure package management system with the rubygems application, formally added to the language in Ruby 1.9. Python has various competing package management systems with pip, easy_install, and others. NodeJS applications and libraries are delivered via npm.

As a part of the open source release of Swift, Apple has released a Swift Package Manager designed for “managing distribution of source code, aimed at making it easy to share your code and reuse others’ code.” This is a bit of understatement of what the Swift Package Manager can do in that its real power comes in managing the compilation and link steps of a Swift application.

In our previous tutorial we explored how to build up a Swift application that relied on Glibc functions, linking against libcurl routines with a bridging header, and linking against a C function we compiled into an object file. You can see from the Makefile, there are a lot of steps and commands involved!

In this post we’re going to replace all that with a succinct and clean Swift Package Manager Package.swift manifest and simplify our code while we’re at it.


Package.swift is the equivalent of npms package.json. It is the blueprint and set of instructions from which the Swift Package Manager will build your application. As of this writing (December 8, 2015), Package.swift contains information such as:

  • the name of your application (package)
  • dependencies that your application relies on and where to retrieve them
  • targets to build

Unlike package.json however, Package.swift is Swift code, in the same way an SConstruct file is Python. As the Swift Package Manager evolves to meet the complex use cases of building large software packages it will undoubtedly grow to contain additional metadata and instructions on how to build your package (for example, package.json for NodeJS contains instructions on how to execute your unit tests).

There’s quite a bit of documentation available for the Swift Package Manager on Github, so I won’t rehash it here, but will rather dive right in to a working example of a Package.swift for our translator application.

Each Package.swift file starts off with import PackageDescription. PackageDescription is a new Swift module that comes with the binary distribution of Swift for the Ubuntu system. The class Package is provided, which we utilize on the next line.

Don’t let the “declarative” nature fool you, this is Swift code. package gets assigned a new Package object which we’ve created with the init(name: String? = nil, targets: [Target] = [], dependencies: [Dependency] = []) initializer.

The name attribute is self-explanatory, and dependencies is an array of package dependencies. Our application will rely on two packages, CJSONC (which is a wrapper around libjson-c), and CcURL (a wrapper around, you guessed it, libcurl).

The Swift Package Manager authors have devised an interesting mechanism by which to pull in package dependencies which relies on Git and git tags. We’ll get to that in a moment.

Directory Structure

The Swift Package Manager relies on the convention over configuration paradigm for how to organize your Swift source files. By this we simply mean, if you follow the convention the package manager expects, then you have to do very little with your Package.swift. Notice that we didn’t specify the name of our source files in it. We don’t have to because the package manager will figure it out by looking in expected locations.

In short, the Swift Package Manager is happiest when you organize things like this:


In our Sources directory we will place two files: Translator.swift and main.swift. Note: Our previous tutorial used lowercase filenames, such as translator.swift. This convention is used by NodeJS developers. It appears that the Swift community is going with capitalized filenames.

Translator.swift has changed a bit from our previous version. Here is the new version which leverages system modules rather than trying to link against C object files we created by hand.

Two new import statements have been added for CJSONC and CcURL, and a routine we did have in C is now in pure Swift. To be sure under the hood the compile and link system is relying on libraries that were compiled from C source code, but at the binary level, its all the same.

Now, here is where it gets really simple to build! Type swift build and watch magic happen:

# swift build
Cloning Packages/CJSONC
Cloning Packages/CcURL
Compiling Swift Module 'translator' (2 sources)
Linking Executable:  .build/debug/translator

That’s it! Our binary is placed in .build/debug and takes its name from our Package.swift file. By default a debug build is created; if we want a release build, just add -c release to the command:

# swift build -c release
Compiling Swift Module 'translator' (2 sources)
Linking Executable:  .build/release/translator

Running our application:

# .build/debug/translator "Hello world\!" from en to es
Translation:  ¡Hola, mundo!

System Modules

Let’s talk about the two dependencies listed in our Package.swift manifest. If you go to the Github repository of either “packages” you will find very little. Two files, in fact:

  • module.modulemap
  • Package.swift

and the Package.swift file is actually empty!

The format of the module.modulemap file and its purpose is described in the System Modules section of the Swift Package Manager documentation. Let’s take a look at the CJSON one:

module CJSONC [system] {
  header "/usr/include/json-c/json.h"
  link "json-c"
  export *

All this file does is map a native C library and headers to a Swift module. In short, if you create a modulemap file you can begin importing functions from all manner of libraries on your Linux system. We’ve created a modulemap for json-c which is installed via apt-get on an Ubuntu system.

The authors of the Swift Package Manager, in the System Modules documentation state:

The convention we hope the community will adopt is to prefix such modules with C and to camelcase the modules as per Swift module name conventions. Then the community is free to name another module simply JPEG which contains more “Swifty” function wrappers around the raw C interface.

Interpretation: if you’re providing a straight-up modulemap file and exposing C functions, name the module CPACKAGE. If at a later date you write a Swift API that uses CPACKAGE underneath, you can call that module PACKAGE. Thus when you see CJSONC and CcURL above you know that you’re dealing with direct C routines.

Creating a System Module

There are several examples of creating system modules in the documentation, but we’ll add one more. Creating a system module is broken down into 3 steps:

  • Naming the module
  • Creating the module.modulemap file
  • Versioning the module

In this directory (CDB) add module.modulemap with the following contents:

Package dependencies in Package.swift are specified with URLs and version numbers. Version.swift lays out the current versioning scheme of major.minor.patch. We need a mechanism by which to version our system module, and the Swift Package Managers have developed a scheme by which you can use git tags.

Now, I’m not sure if git tags will be the only way to specify the version of your package; it does have the downside of tying one to using git for source control of your Swift code.

In our CDB directory.

git init # Initialize a git repository
git add . # Add all of the files in our directory
git commit -m"Initial Version" # Commit
[master (root-commit) d756512] Initial Version
 2 files changed, 5 insertions(+)
 create mode 100644 Package.swift
 create mode 100644 module.modulemap

And the crucial step:

git tag 1.0.0 # Tag our first version

Now we want to use our new module. In a separate directory named use-CDB, adjacent to our CDB directory, create a Package.swift file:

It’s important to note here your directory structure should look like this:


In use-CDB run swift build:

# swift build
Cloning Packages/CDB

What swift build has done here is read the package descriptor and “pulled in” the dependency on the CDB package. It so happens that this package is in your local filesystem vs. on a hosted Git repository like Github or BitBucket. The majorVersion is the first tuple of your git tag.

Now let’s say you made an error and needed to change up module.modulemap. You edit the file, commit it, and then run swift build again. Unless you retag you will not pick up these changes! Versioning in action. Either retag 1.0.0 with git tag -f 1.0.0 (-f is for force), or bump your version number with a patch level, like git tag 1.0.1.

To use our new system module we write a quick main.swift in use-CDB:

Use swift build and it will pull in our CDB module for us to use. The next step is to figure out how to use the myDatabase pointer to open the database!

Closing Remarks

It has been less than a week since Apple put Swift and the new package manager out on Github. It’s under heavy churn right now and will undoubtedly rapidly gain new features as time goes on, but it is a great start to being able to quickly build Swift applications on a Linux system!

Getting the Code

You can get the new version of our translator application which uses the Swift Package Manager on Github.

# git clone https://github.com/iachievedit/moreswift
# cd translator_swiftpm
# swift build
Cloning Packages/CJSONC
Cloning Packages/CcURL
Compiling Swift Module 'translator' (2 sources)
Linking Executable:  .build/debug/translator


More Swift on Linux

Editor’s Note: This article was written on December 6, 2015, days after Apple open-sourced Swift and made an Ubuntu distribution of the Swift compiler available. All of the techniques used below should be forward compatible, however, there may be easier ways of doing things in the future as the Foundation classes are implemented. Apple has posted a status page that outlines what works and what doesn’t.

Using Glibc Routines with Swift

As I mentioned in Swift on Linux!, the Foundation classes that Objective-C and Swift developers have come to know and love are only partially implemented. And by partially implemented I really mean hardly implemented. Okay, NSError is there and a few others, but no NSURL, NSURLSession, etc.

What is there is the wealth of routines from the GNU C Library, also known as Glibc. You know, the library of rotuines you’d look up with a man page. Functions like popen and fgets, getcwd and qsort. Swift won’t be displacing Python any time soon if this is all we’re left to work with, but you can do something useful and begin exploring the possibilities of intermixing C with Swift. In this tutorial we’ll do exactly that and write up some Swift code that uses popen to spawn wget to make up for the lack of NSURLSession.

So let’s get stuck in and write some Swift.

Swift cat

Create a file named swiftcat.swift and add the following code:

To get access to all of the Glibc routines we use import Glibc. Easy enough. Swift 2 brought us the guard construct, so we’ll use that to ensure that we have an argument to our script. Our first exposure to using a Glibc function is exit(-1). That’s right, nothing special about calling it, it is just the void exit(int status) function.

We’re going to cheat a bit and leverage the /bin/cat command to read the file and write to standard out. To call it though we’ll use popen which will pipe us a stream of bytes that we can read with fgets. There is one thing to notice here, and that is that Glibc routines which take const char* arguments can be given Swift Strings directly. Routines that take char*, as in the case of fgets require some finesse.

fgets does take a char*, so we cannot pass it a String, but rather will use a buffer allocated as a [CChar] (C char) array. The array has a fixed size of 1024 and is initialized with zeroes. Our while loop calls fgets with the stream pointer, and non-nil results contain a buffer from which we can create a Swift String.

Go ahead and save this to a file called swiftcat.swift and then run it!

# swift swiftcat.swift 
Usage:  swiftcat FILENAME

Pass it a file to get the equivalent of cat output!

Mixing in C

You aren’t limited to using Glibc routines with your Swift code. Let’s say we want to use libcurl to escape some strings and get them ready to be included in a URL. This is easy to do with libcurl.

In a file called escapetext.c put the following:

Make sure you have libcurl installed with apt-get install -y libcurl4-gnutls-dev.

Now, compile the file with:

clang -D__TEST__ -o escapetext escapetext.c -lcurl

We include the -D__TEST__ here to pick up the main function. In a minute I’ll show you how to take this routine and include it in a Swift application. Run the C application:

# ./escapetext "hey there\!"
Escaped text:  hey%20there%21

Easy enough. Now, we want to write a Swift application that uses our C routine escapeText. The first thing to do is compile an escapetext.o object file without the -D__TEST__ flag set. This will get rid of main().

clang -c escapetext.c

Now, create a file called escapetext.h and put the function prototype in it.

Write a new file called escapeswift.swift and add the following:

Compile this Swift code with:

swiftc -c escapeswift.swift -import-objc-header escapetext.h 

Notice that we included -import-objc-header escapetext.h. Without this header the Swift compiler won’t be able to find the prototype for escapeText and will subsequently fail with use of unresolved identifier.

Bringing it all together, we link our escapeswift.o and escapetext.o objects together, and pass in the Curl library.

swiftc escapeswift.o escapetext.o -o escapeswift -lcurl

And run it!

# ./escapeswift "how now brown cow"
Escaped text:  how%20now%20brown%20cow

Translator Application

This is a more complex example, but the principals are the same as those outlined above. We’re going to mix C objects and Swift modules together to write a command line application that translates strings from one language to another.

The REST API we’ll be using to do the actual translation returns results in JSON. Since NSJSONSerialization isn’t yet available in Foundation on Linux, we’ll use the libjson-c-dev library, so install it with apt-get install libjson-c-dev.


Two files make up our JSON-parsing routine, parsejson.c and its companion header parsejson.h.



We can easily compile this file with clang -c jsonparse.c.

Translator module

The workhorse of the translator application will be a Swift module called translator. To create this module and prepare it for inclusion with the rest of our project, start with the class file translator.swift:

Take a moment to read through the code. We’re including direct calls to the Curl library here, as well as popen and fgets, and our translatedText routine that is compiled into an object file created by clang.

In addition, create a bridgingHeader.h with the contents:

There are two steps to getting this ready to use in our application:

  • Create a shared library with the translator routine
  • Create a swiftmodule that describes the interface

I will confess, I didn’t understand this until I read on Stackoverflow:

The .swiftmodule describes the Swift module’s interface but it does not contain the module’s implementation. A library or set of object files is still required to link your application against.

First, compile the code into a .o and create a shared library:

swiftc -emit-library translator.swift -module-name translator -import-objc-header bridgingHeader.h
clang -shared -o libtranslator.so translator.o

Now, create the module:

swiftc -emit-module -module-name translator translator.swift -import-objc-header bridgingHeader.h

This leaves us with three files: libtranslator.so, translator.swiftmodule, and translator.swiftdoc.

Main Routine

Our main file, main.swift looks like this:

Again, we’ve made use of Foundation and Glibc, but we’re also using import translator. You must have a translator.swiftmodule in your module search path, which we add with -I.:

swiftc -I. -c main.swift -import-objc-header bridgingHeader.h

Let’s link everything together:

swiftc -o translate.exe jsonparse.o main.o -L. -ltranslator -lcurl -ljson-c -lswiftGlibc -lFoundation

The resulting binary is translate.exe because we intend to wrap a helper script around it to set the LD_LIBRARY_PATH to find the libtranslator.so shared library. Without the helper script (or using ldconfig to update the search path), you need to invoke the excecutable like this:

LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./translate.exe "Hello world\!" from en to es
Translation:  ¡Hola, mundo!

Let’s try Irish:

LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./translate.exe "Hello world\!" from en to ga
Translation:  Dia duit


It’s not clear how “interpreter” friendly Swift will become. Yes, one can create a single monolithic Swift script right now and run it with swift. In fact we did that above. Using bits of code from other Swift files though, without specifying everything on the command line, remains, well, impossible. Maybe I’m wrong and just haven’t figured out the magic incantation to have Swift greedily open up files searching for code to run.

At any rate, our translator application above needs a little help to build. There is a new Swift builder tool, but I found make could get the job done with some appropriate rules:

Getting the Code

You can get all of the code above from Github.

git clone https://github.com/iachievedit/moreswift

The swiftcat code is meant to be run with the swift command, where as escapetext has a simple build.sh script, and translate has a full-on Makefile.

If you’ve enjoyed this tutorial please follow us Twitter at @iachievedit! There will be more to come as Swift on Linux matures.


Writing an iBeacon App in Swift

Editor’s Note: This is Part Two of our series of articles on creating a Swift iBeacon application. By the end of the series you will have written a “game” in Swift called You’re Getting Warmer! which allows you to track down and find a beacon. Part One gets you up and running iBeacon with a Gimbal Proximity Beacon Series 10.

Before getting started with Part Two, you should have an operating iBeacon and know its UUID. If you don’t have an iBeacon start with Part One of this series!

If you’re working with iBeacon we’re just going to assume you known how to create a new Single View Application Swift project with Xcode. Go ahead and do that now. We named our project gettingwarmer.


Beacon Ranging

There are two methods of listening for iBeacons in iOS: monitoring and ranging. The difference between the two is that monitoring is an activity that can continue running in the background, while ranging is a foreground activity. Radius Networks wrote up a nice explanation describing the differences in detail. Apple’s iBeacon documentation uses the term ranging to describe the activity of determining the proximity of a given iBeacon. Our first application will make use of ranging as opposed to monitoring.


I have always preferred to use the singleton “manager” pattern for working with CoreLocation in iOS. We’ll create a class called BeaconManager which will be responsible for an instance of CLLocationManager as well as serving as our CLLocationManager delegate. To get started create a new file BeaconManager.swift in your gettingwarmer Xcode project and add the following implementation:

The class declaration and init routine should be self-explanatory. If you haven’t been working with Swift 1.2 you may have missed the introduction of the static keyword which allows for a quick implementation of the singleton pattern.

Let’s first implement the didChangeAuthorizationStatus method, because once we are authorized we want to start ranging.

Here’s our implementation:

If the OS can’t determine the authorization status (.NotDetermined), we’ll simply ask for it again (why not).

If we receive a callback that our status is .AuthorizedWhenInUse (what we requested) or .AuthorizedAlways (which will never be the case), we’ll call our startRanging method.

If on the other hand we receive .Denied or .Restricted, we’ll broadcast a notification with NSNotificationCenter that will be heard by our ViewController. The ViewController will then be responsible for raising a dialog indicating that location services are required for the app to operate properly.

Now, let’s take a look at our startRanging method.

Ranging begins with the startRangingBeaconsInRegion method, and in our case a region is identified as “being in the proximity of a beacon broadcasting a UUID of 788FA98B-871C-4C71-9944-88ADEC84A8DA”. It’s that simple. If iOS hears a beacon with this UUID, it is “in” that region.

It may be confusing at first that a “region” in this context is not geographical. Apple’s QuickHelp documentation explains it this way: “A CLBeaconRegion object defines a type of region that is based on the device’s proximity to a Bluetooth beacon, as opposed to a geographic location.

Once ranging starts we have to be prepared to receive didRangeBeacons calls on our CLLocationManager delegate. For now, we’ll add this implementation:

Before leaving ranging, it is important to draw the distinction between monitoring for regions and ranging beacons. Monitoring can run in the background with notifications sent to your app when the registered CLBeaconRegion is “entered” (that is, the beacon was heard). Ranging is for finer proximity detection and can only be used while the application is in the foreground. Again, reading the Radius Networks article is useful.

Rounding Out

Thus far we’ve implemented:

  • a BeaconManager class capable of requesting location services authorization
  • the didChangeAuthorizationStatus method to handle changes in location services authorization from the user
  • a startRanging method which will start listening for our iBeacon
  • the didRangeBeacons method which will be called when iOS hears our iBeacon

We have a few more things to do before running the application:

  • setting NSLocationWhenInUseUsageDescription in our Info.plist
  • creating an instance of the BeaconManager when our ViewController appears
  • intercepting LOCATION_DENIED notifications in the event the user declines location services authorization

In your Info.plist, create a new key called NSLocationWhenInUseUsageDescription like so:


Next, round out the ViewController code by adding the following:

When our view appears we want to create an instance of the BeaconManager which in turn will request authorization. Therefore we add our ViewController as an NSNotification observer for the LOCATION_DENIED notification. If this notification is received we pop up an alert dialog (UIAlertController) indicating that location services permission is required.

Run It!

If you’ve implemented everything you should now be able to run the application on your iOS device (note: this will not work in a simulator). After granting location services authorization and bringing out our iBeacon we see in the console:

Beacon ranged:  CLBeacon (uuid:<__NSConcreteUUID 0x1702224e0> 788FA98B-871C-4C71-9944-88ADEC84A8DA, major:1, minor:0, proximity:2 +/- 0.68m, rssi:-59)

What Could Possibly Go Wrong?

Software development can be rewarding and a lot of fun, but it can also drive you crazy when things don’t work right. In this series there are a lot of things that could go wrong that would prevent iOS from recognizing your beacon. If you’re having trouble, consider:

  • is your iBeacon programmed with the same UUID as your CLBeaconRegion?
  • is your iBeacon powered?
  • was the app granted location services permission?
  • is the iBeacon in range?
  • is Bluetooth enabled on your iOS device?

Getting the Code

The complete source code for this tutorial is available on BitBucket. The implementation for this article is available on the partTwo branch.

Next Up

We can now receive iBeacon messages in our application, but we aren’t doing anything with the information. In Part 3 of this series we’ll go through the various properties of the CLBeacon class, namely:

  • proximity
  • accuracy
  • rssi

We’ll then begin adding a user interface to our view controller for a nice game of You’re Getting Warmer!. Stay tuned!


Apple Watch Internationalization and Localization

There are plenty of articles on the blogosphere extolling the reasons why you, dear entrepreneur/product manager/software developer, need to consider internationalization (I18N) and localization (L10N) when designing your next killer application. Briefly, internationalization is the process of supporting more than one language in your application. Localization is the process of supporting local and regional differences in the display and formatting of times, dates, and currencies.

Your Apple Watch application is no different. Of course, every mockup and advertisement you’ve seen thus far has had the Apple Watch UI displaying English, but if you support multiple languages in your iPhone application and are designing an Apple Watch extension, you need to support those languages there as well.

In this article we’ll take a look at how to internationalize and localize your Apple Watch application. Our application will be a simple one and present a “Hello World!” label followed by the time (in localized format) and an appropriate time-based greeting. For example, at 9:00 AM the greeting would be “Good morning” in English.

iOS Simulator Screen Shot - Apple Watch Apr 19, 2015, 9.28.26 AM

As usual, we’ll begin with a starter application so you can jump right into internationalization and not spend time laying out the Apple Watch interface. Grab the zip file, extract, and open the applewatch18n project.

For this application we’re going to use two types of internationalization techniques with Xcode: internationalizing the storyboard, and creating a Localizable.strings file. Internationalizing the storyboard is a good technique to use when you want to provide for static labels to be displayed in the appropriate language. For example, if you have a button labeled Close and want to display Cerrar in Spanish, you likely want to use Storyboard internationalization. In our case the Hello world! label on the Apple Watch interface will be displayed as Hola mundo! in Spanish, so let’s go through the steps of creating an internationalized storyboard.

Note: While some application platforms separate the I18N and L10N steps, Xcode (and iOS/OS X) combines them into Localization. We’ll use the terms interchangeably.

The first step to adding localization to your application starts with the Localizations section of your project. Go to the applewatchi18n project in Xcode and find the Localizations section. Click on the + sign.


Choose Spanish (es) from the menu and you will be prompted to select the files you want localized. Although we won’t use Main.storyboard or LaunchScreen.xib in this example, leave them checked, and of course since we are interested in localizing our Apple Watch interface leave Interface.storyboard checked. Leave the Reference Language as Base.


Click Finish.

Notice now there is a disclosure triangle next to Interface.storyboard in the project explorer. Click on it to reveal:


Let’s take a look at Interface.strings (Spanish):

The gibberish strings you see are Xcode Object IDs assigned to the UI component when you add them to the storyboard in Interface Builder. Just think of them as a automatically generated unique identifier (because that’s what they are) for the UI components. That said, the object IDs you see when you run this tutorial in Xcode will be different.

Notice the line "neb-bX-Mot.text" = "Hello world!";. Here is where we’re going to apply our Spanish text for the label we want to display “Hello world!”. To change it, simply replace the Hello world text with Hola mundo.

Tip: The dot-notation .text indicates you are localizing the text property of the given UI element.

To test our new localization change we’re going to have to change the language of our iOS simulator from English to Spanish. This can be done by launching the simulator and going to Settings – General – Language & Region and selecting iPhone Language. Español should be the first selection. Select it and press Done in the upper-right. The simulator will prompt you to confirm that you want to change the language to Spanish, so press Change to Spanish.

Tip: This may sound obvious, but When changing the language on the iPhone it is a good idea to have a basic grasp of the iPhone terms in the target language. For example, Settings is Ajustes in Spanish. Although you can use context clues (such as the icon for Settings), when you need to drill down into multi-level menus and either don’t know the language or alphabet you’re working with, it can be difficult or time-consuming to navigate the interface.

Now that our simulator is in Spanish, run the WatchKit app. You should see something like:


Let’s move on now to localization of the time. Now I will be honest: when I see or hear time given in 24-hour (or “military time” as Americans refer to it) notation, my brain has no immediate understanding of the relative time-of-day. In the end, when I see something like 15:45 I subtract twelve from fifteen and understand it to be 3:45 PM, which instantly puts me in the afternoon. But, as I’ve discovered in my travels, many places in the world prefer and use 24-hour time.

Our goal will be to respect the localization/regionalization setting of the user’s iPhone and display the time in their preferred format. To accomplish this we’re going to add some code to our InterfaceController.swift file:

This routine looks up the iPhone’s current locale and then creates a formatted time string for the supplied date. Update InterfaceController.swift willActivate as follows:

Run the application. Assuming no changes were made to the simulator, you should see the AM/PM notation used for the label. We want to use the regional time format for Uruguay (which uses 24-hour notation), so, if your simulator is still in Spanish, go to Ajustes – General – Idioma y región – Región and select Uruguay.

Run the application again and notice that AM/PM is no longer displayed and the time is formatted in 24-hour notation.

Thus far we’ve looked at internationalizing static labels (with an Interface.strings file for our storyboard) and respecting the regional settings for the time. Now we’ll turn our attention to dynamic UI elements that can display different strings based upon the software’s logic.

To get started, let’s add a strings resource file called Localizable. Using Xcode File – New – File, select iOS – Resource and a Strings File template.


Click Next.

Name the file Localizable and ensure it is added to the WatchKit Extension target.


Now that we have the Localizable.strings file created, we need to configure it as a localized file. In Xcode select Localizable.strings that you just created and in the File inspector find the button that says Localize.

Click Localize and Xcode will ask whether or not you want to localize the file and allow you to select the base language. Select Base and click Localize.


The File Inspector pane will update and in place of the Localization button you will see the languages that the file has localization support for. The default selection will be Base (which is, in fact, English), and we want to add Spanish. Select the checkbox next to Spanish and like Interface.storyboard, Localizable.strings will get a disclosure triangle in the project navigator.


When working with localizable strings the base language string is used as the key from which to look up translations. For example, the following table lists the base strings (which happen to be in English) along with their Spanish translation.

Good morningBuenos días
Good afternoonBuenas tardes
Good eveningBuenas noches

To implement this table in the Localizable.strings file, select the Spanish version of the file and add:

Notice that you don’t necessarily have to add content to the base Localizable.strings file. The reason will become clear in a moment.

Add the following function to the InterfaceController:

The above code takes the supplied NSDate and extracts the hour component, and then derives an appropriate greeting. Now, let’s display this greeting in our interface with the following in willActivate:

The key function here is NSLocalizedString which returns the localized version of the supplied string. If there is a localized string available for the target language it is returned. If there isn’t one, the string supplied is returned. For example, if you forgot to provide a Spanish translation for “Good evening” in your Localizable.strings (Spanish) file then “Good evening” would be returned by the function. This is why technically speaking you did not have to provide a mapping for the English translation, the function greetingForTime is supplying it.

Note: The comment argument to the NSLocalizedString function is to provide a hint to human translators that are supplying translations. I have never made use of it and have only used a blank string in code.

Running our application with the simulator still set to Spanish we see:

iOS Simulator Screen Shot - Apple Watch Apr 19, 2015, 12.08.50 PM

Note: As you can see in the screenshot, there is a difference between the language and the time format. Although our phone is set to Spanish, our region was set to the United States.

Now that we have run our application in Spanish, we need to switch the simulator back to English and ensure it is functioning as expected. If you are writing applications that support multiple languages you will have to go through this process for each and every language. Nothing is as embarrassing as claiming you support a given language in your application only to let a typographical or grammatical error get published on the AppStore (it’s buenos días, not buenas dias!)

iOS Simulator Screen Shot - Apple Watch Apr 19, 2015, 12.18.40 PM

Get the Code

You can find a completed version of the application in this zip file. Try adding a German translation to the application!

Hello world!Hallo Welt!
Good morningGuten Morgen
Good afternoonGuten Tag
Good eveningGuten Abend


Multiple Build Schemes with Apple Watch

I frequently use Xcode schemes and configurations to manage building iPhone applications for specific environments. For example, let’s say you’re integrating with an API from another team, and they’ve set up two instances of the API: staging and production. Furthermore, you want to have two sets of builds for those environments: debug and release. All of this can be accomplished with Xcode and Swift, with details outlined in a previous blog post.

In this post I’ll show you how to extend this paradigm to work with an Apple Watch target that you’ve added to your project. We’ll start with an application that is already configured to support two schemes: debug and release, where the debug scheme enables logging. Download the starter project watchschemes. To ensure things are working properly, download the zip file and open the watchschemes.xcodeproj project, and then run the Debug Application scheme. You should get a nice log in the console:

Before we add the Apple Watch target, note our two files that facilitate logging: XCGLogger.swift and LogUtils.swift. They are currently grouped under Supporting Files of our watchschemes folder. When we add the Apple Watch target we’ll reorganize these files to highlight the fact that they are shared between the iPhone application and watch extension. If you haven’t had the pleasure of working with XCGLogger, see our post on using XCGLogger instead of Lumberjack for your Swift projects.

Now, let’s add our Watch target. Go to Xcode File – New – Target and select the Apple Watch “WatchKit App” template. Uncheck Include Notification Scene as we won’t be creating one.


You will notice that Xcode has created a new scheme titled watcheschemes WatchKit App. Xcode may ask if you want to activate that new scheme:


Click Activate.

You will also notice if you edit the scheme you will find that the Run action is associated with the Debug build configuration.


What we would like is to have two schemes for our WatchKit App, similar to the two schemes we have for the iPhone application. Let’s do that then by going to the Manage Schemes page. To get there, select the Scheme in Xcode and go down to Manage Schemes.


You should see the three schemes in the project:


The first thing we’ll do is rename the default WatchKit application scheme to Debug WatchKit Application and mark it as a shared scheme (sharing the scheme allows for multiple developers to share the scheme in their workflow, allow them to use all of the build configuration defines, optimizations, etc.). Then, we will duplicate that scheme and rename it to Release WatchKit Application.


When duplicating the scheme, rename it to Release WatchKit Application and change the build configuration for the Run action from Debug to Release. After duplicating the scheme mark the scheme as Shared.

Now that we have a Debug and Release WatchKit Application, let’s instrument logging into the WatchKit extension such that Debug has meaning. Open the InterfaceController.swift file (in the extension group) and ensure it looks like this:

Out of the box, with no changes to the extension target, this code will not compile. The WatchKit extension has no knowledge of the XCGLogger.swift and LogUtils.swift code that is a part of the iOS application. So let’s add them.

Tip: If you interested in how the ENTRY_LOG() and EXIT_LOG() routines work, see the LogUtils.swift file.

Go to the watchschemes WatchKit Extension target’s Build Phases pane and under the Compile Sources section add both XCGLogger.swift and LogUtils.swift. This simply instructs Xcode to consult these files when compiling the WatchKit extension.

Before adding the two Swift files you should see only the InterfaceController.swift file as a member of the Compile Sources list:


After adding you should have 3 files:


Although we’ve added our logging files to the extension target, and we’ve specified the Debug and Release build configuration for the two schemes, one still must configure the build configurations for the extension target. To put another way: Xcode does not copy the build configuration flags and settings from the iOS target to the extension target when it is created. You can verify this by looking at the Swift Compiler – Custom Flags for the WatchKit extension. Whereas our original application has -DDebug set for the Debug build configuration, the extension target does not. You should keep this in mind when creating your first Apple Watch target: if you have compile-time flags configured for your iOS build configurations, you’ll need to reproduce them in your extension target flags. This is what we have done here:


Once your build configuration flags have have been set you should be able to Run either the Debug or Release WatchKit Application. For instant gratification, select the Debug Watchkit Application scheme and run. You should see

in the console log for the Debug WatchKit Application scheme.

As you continue development of your WatchKit application you can use the debug configuration. Once you are ready to run the release version with no logging, switch over to the Release WatchKit Application scheme you created.

Tip: With the two build configurations and schemes you can build either a WatchKit application that includes debug logging, or one that doesn’t. I personally prefer to have additional configurations and schemes for targeting various installations of APIs or other backend services; the approach outlined above can be extended to accomplish this so you can support variations such as Debug Staging or Release Beta.

Tip: Don’t forget your Archive scheme actions! I frequently upload archive builds to either TestFlight or TestFairy that have logging instrumentation, test API keys, or are utilizing staging servers. You will want to ensure the Archive action for your scheme has the correct build configuration set.

Organizing Common Swift Files

As mentioned above, our XCGLogger.swift and LogUtils.swift files are utilized by both the iOS application and WatchKit extension. To facilitate making this explicitly obvious in the project, I’ve started to add a Common Sources group to my Xcode projects and placing the shared files there. In this project this looks like:


Getting the Code

The final version of the code for this tutorial is on the watchschemes branch of the BitBucket repository. To download a copy, grab this zip.


Bluetooth Low Energy, Arduino, and Xcode

In some ways Apple signaled what it sees as the future for home automation when it introduced HomeKit with support for 802.11 (Wifi) and Bluetooth Low Energy (also referred to as BTLE or Bluetooth Smart) as transport protocols. Notably absent were both Z-Wave and Zigbee. Sure, Apple provided for the implementation of a “bridge” device to these existing protocols, but every product announcement since then touting HomeKit support has been a Wifi or BTLE device. Don’t take my word for it, browse through this article outlining the devices showcased at CES this year. A brief lineup:

and more. Neither Z-Wave nor Zigbee is mentioned, which is not to say that either protocol or the the thousands of devices that are out there will simply go away, only that it’s clear Apple sees BTLE and Wifi as the future for home automation control. Whether that is true remains to be seen.

But this article isn’t about HomeKit, it’s about Bluetooth Low Energy itself and how to quickly integrate an Arduino-powered Adafruit BTLE board with your iPhone, all using an Arduino Xcode project. So let’s get started.

In our previous post we covered how to create an Arduino sketch using Xcode and the embedXcode project. The outcome of that process was a simple Arduino application that blinked two LEDs back and forth, and while cool, not exactly ground breaking. Let’s take it to the next level and integrate an Adafruit nrf8001 BTLE Breakout board with the Arduino and talk to it with our iPhone. Moreover, we’ll do all of this with our favorite IDE (well, mine at least), Xcode.

Before we get started, you’ll need to have the following on hand:

  • Arduino Uno board and USB programming cable
  • Breadboard and 8 male-to-male jumper cables
  • Adafruit nrf8001 BTLE Breakout board
  • Arduino application installed on your Mac
  • embedXcode installed on your Mac
  • an iPhone and access to the AppStore

For the last two items, see our previous post for instructions on installing.

The nrf8001 breakout board does not come out of the box with the header pins soldered on, so you’ll need to do that step. Luckily the instructions are provided by Kevin Townsend’s excellent nrf8001 article.

Assuming you the breakout board soldered and in your breadboard, wire it per the instructions found on Adafruit:


From the Adafruit nrf8001 article


Don’t take wiring lessons from me

Once the wiring is completed, we need to install the Adafruit BLE UART software into our Mac’s Arduino user library folder. There is a distinction between system libraries and user libraries that will become apparent in a moment.

To install the Adafruit BLE UART software as a user library click on this download link. A folder named Adafruit_nRF8001-master will be created in your Downloads folder. Rename this folder to Adafruit_BLE_UART and then drag-and-drop it into your ~/Documents/Arduino/libraries folder:


Now, let’s create our Xcode project. Open Xcode and use File – New – Project to create a new embedXcode Sketch. We’ve named our project nrf8001 and targeted the Arduino Uno board.


To walk this through in stages, open the nrf8001.ino file in your project and delete its contents and then add following to it:

This code is actually found in the Adafruit_BLE_UART folder you downloaded earlier, under the examples folder in a file called echoDemo.ino.

In Xcode click the Run (play) button using the All target. You should get a Build Failure with an error:

Shell Script Invocation Error SPI.h: No such file or directory

Recall that we are dealing with C++ when working with Arduino, and a header inclusion failure is likely the result of failing to specify that we are using some library. In this case we are wanting to use the Arduino SPI system library and didn’t tell Xcode in our Makefile. So open the Makefile and find the lines:

Change the APP_LIBS_LIST line to APP_LIBS_LIST = SPI and try to compile again. The error now should be a failure to find Adafruit_BLE_UART.h, which is a part of a user library. Looking back at the Makefile we see a USER_LIBS_LIST definition, so change it to

Run again and you should see a terminal screen pop up like this:


If you are seeing the same output, congratulations! You’re almost there.

Now, let’s grab an application for our iPhone to connect to our Bluetooth module! On your iPhone search for the nRF UART application from Nordic Semiconductor. Download and open the app on your iPhone and, of course, ensure Bluetooth is enabled!

The nRF UART app isn’t fancy – a button to Connect to the Adafruit BTLE board, a Console showing you what’s going on, and a text field for sending text.


Bring your Adafruit terminal log into focus on your Mac and then press the Connect button on the nRF UART app on your iPhone. If everything is working properly (all of your pins are wired to the right spot and the application is running) you should see Connected! on your Mac terminal and the console log on the iPhone indicating that a connection was successful.


Now, type some text in the textfield on the iPhone app and press Send. If everything is working properly you should see the text you typed in your phone show up in your Arduino application console!


From the iPhone…


To Arduino!

Get the Code

The complete Xcode project for working with the Adafruit nrf8001 is on Bitbucket. Remember, you must have the Adafruit_BLE_UART library installed in your Arduino user library folder.


This post is really made possible by Kevin Townsend and his article on Adafruit. As I’m quickly learning, much of Arduino magic comes from the fact that it just works. For example, although I know SPI and some BTLE protocol details, I didn’t have to lean on that knowledge to put this tutorial together or get my iPhone and Arduino/Adafruit BTLE communicating!


Using Carthage with Alamofire

I have never been a fan of CocoaPods due to its intrusiveness in the build process and insistence on creating Xcode project workspaces. Unfortunately managing dependencies through the use of Git submodules is no better. How many times have you told yourself, “Okay, I understand submodules now” only to be met with fatal: reference is not a tree: when trying to do a git submodule update? Perhaps I’m dense, but I shouldn’t have to turn to Google every time I check out a project which uses submodules.

In the tutorial HTTP JSON Request with Swift and Alamofire we used the git submodule approach to add the Alamofire framework as a dependency to our Xcode project. Let’s now look at a new approach to managing framework dependencies with Carthage.

Carthage was developed to make framework dependency management in your Xcode projects just a bit easier. Luckily for us, Alamofire now supports using Carthage, and we can leverage that support in our project to get rid of the git submodule approach.

To get started with Carthage, you’ll first need to install Homebrew. If you have never used Homebrew before, you’re in for a real treat. To install Homebrew open a terminal and paste:

Follow the prompts and once Homebrew is properly installed then you can install carthage with brew install carthage.

==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/carthage-0.5.2.yosemite.bottle.tar.gz
Already downloaded: /Library/Caches/Homebrew/carthage-0.5.2.yosemite.bottle.tar.gz
==> Pouring carthage-0.5.2.yosemite.bottle.tar.gz
🍺 /usr/local/Cellar/carthage/0.5.2: 157 files, 34M

Now, let’s look at how to add Alamofire to our project using Carthage. The first step is to create a Cartfile in our project folder. The Cartfile is what you might expect: a list of dependencies (and where to fetch them from) for our project. Our Cartfile will contain a single dependency on Alamofire.

Run carthage update. Carthage will now check out and build Alamofire.

% carthage update
*** Fetching Alamofire
*** Checking out Alamofire at "2f39b8634ab85cd6b3a55bbcfdec8cbb6463a6ee"
*** xcodebuild output can be found in /var/folders/yn/ljzrn5hd4g3fxsj4klwkhbkm0000gp/T/carthage-xcodebuild.wAPiQR.log
*** Building scheme "Alamofire iOS" in Alamofire.xcworkspace
*** Building scheme "Alamofire OSX" in Alamofire.xcworkspace

Once completed you should see a new file and new folder in your project directory: Cartfile.resolved and Carthage, respectively.

You are going to want to check in both Cartfile and Cartfile.resolved, so add them to your repository.

git add Cartfile
git add Cartfile.resolved

You do not need to add the Carthage folder, so you can add it to your .gitignore file if you like.

Now, let’s add the build output from Carthage to our project. First, go to your project’s General tab and locate the section Linked Frameworks and Libraries. You can either drag-and-drop the built framework from the Finder, or use the + button and navigate to the folder in Xcode.


You should see the framework added to the list:


Now, go to Build Phases and create a new Run Script phase. The script contents will be:

Then add an Input File as the framework you want to copy, i.e., Alamofire.framework.

That’s it! With your Xcode project set up to pull in the built framework that Carthage created, you’re ready to build and run! Much easier than using than CocoaPods or git submodules.


If you are iOS developer that likes to stay on the bleeding edge you undoubtedly have both the release and beta versions of Xcode installed on your Mac. If you build your projects solely within Xcode there’s typically no conflict between the two, but since Carthage builds your frameworks from the command-line, the version of Xcode selected by xcodebuild matters. For example, if your xcodebuild is set to use the release version of Xcode and you run carthage update and then include that framework in an Xcode beta project, you will likely get the error Module file was created by an older version. To resolve this use xcode-select to switch xcodebuild to use the beta version of Xcode:

As of February 28, 2015, the Alamofire main branch hasn’t been updated to support Xcode 6.3 (and by extension, Swift 1.2). To continue working with Alamofire in your Xcode 6.3 projects, update your Cartfile to specify a branch dependency:

Run carthage update and Carthage will checkout the xcode-6.3 branch of Alamofire and compile it. If you get a build failure make sure you’re using the right xcodebuild!

% xcodebuild -version
Xcode 6.3
Build version 6D520o

Get the Code

You can check out our example application (for details on the application, see our post here)of using Alamofire and Carthage on Bitbucket. There are two branches, carthage and carthage-xcode-6.3.

If you’re using Xcode 6.1 then you will want to use the carthage branch:

If you’re using Xcode 6.3 (which is beta at the time of this writing):

Note! If you open the translator project and try to build and are met with No such module 'Alamofire' you didn’t build Alamofire with carthage update first!


Introducing Bondi

iAchieved.it LLC is happy to announce the release of Bondi on the Apple AppStore in both English and Spanish. If you ever have the fortune to visit the city of Montevideo, Uruguay, make sure you have Bondi at your side.

Bondi is Spanish slang for city bus and is the term used by Montevideo locals to refer to their urban busses. Our Bondi app presents all of the Montevideo urban stops on a map and then allows you to select and then view all of the bus lines running through that stop. You can then filter those lines for time of day and type of day (the busses run on different schedules on weekdays vs. Saturday and Sunday).


Here come the bondis!

One question that pops up on Reddit /r/iOSProgramming frequently is “are there production applications written only in Swift?” and we can definitely (and proudly!) say, Bondi is written only in Swift! We’ve had nothing but great success with the Swift programming language and have included frameworks such as XCGLogger and Alamofire in our development.

During the process of developing Bondi we learned a few tips and tricks that we’d like to share; one for iAd presentation and the other for the frosted background effect when presenting a modal view controller. We’ll be writing up posts to describe both of these techniques soon!


Building an Apple Watch App for Location-Aware Weather

Editor’s Note: This is a tutorial on how to use iOS 8.2 with Xcode 6.2 to develop an Apple Watch app. It is not an exhaustive overview of WatchKit. I recommend reading the following first in this order:

By the time you’ve finished reading these tutorials you should have a basic understanding of the architecture of a WatchKit app and the application lifecycle of a WatchKit Extension (the app component that runs on your iPhone).

While I’ve tried to provide plenty of step-by-step detail, this tutorial does make an assumption that you have a basic understanding of iOS application development and are comfortable navigating in Xcode. You will of course require an iOS developer’s account to obtain Xcode 6.2 and the iOS 8.2 simulator included.

A Current Conditions WatchKit App

Starter Application

It should have been clear from reading the Apple WatchKit Programming Guide that your Watch app is an extension of an existing iPhone application. That is, there is no such thing as an Apple Watch-only application. One of the examples given on Apple’s website is that of an American Airlines watch app that shows flight updates, boarding notifications, etc. The American Airlines watch app cannot be used without downloading and installing the iPhone app, as that is where the code for the Watch app will reside.

Rather than walk through how to create an application from scratch we’ll begin with a starter application and add an Apple Watch app to it. Ours is a basic weather app that provides a brief look at the weather in your current location. To keep things simple we’ll provide:

  • the name of the current location (for example, New Orleans, LA)
  • a weather icon depicting the current conditions
  • a brief description of the current conditions
  • the current temperature

Even though this is a simple app in its functionality, it does provide a good example of how we will leverage third-party SDKs and the CoreLocation framework to provide location-aware weather information to an Apple Watch app. Warning: If you thought this was going to be a “How do I write a simple WatchKit app in 10 minutes?” tutorial, try out the Bitcoin Price Tracker app first. Ours is a bit more involved.

Download the starter application from BitBucket and open the project in Xcode.

To get started with the app you’ll need to change your aerisweather target bundle identifier. In this example we’ve changed it to com.yourcompany.aerisweather.


We will be using the Aeris Weather API from HAMweather.com, so you will need to register for the service and create some API keys. You may want to review our previous post on signing up.

Create a new application in the HAMweather portal by filling out your Application Name and Application Domain/Identifier.


Click Register to register your application and receive your API keys.


Configure your keys by creating a property list file called ApiKeys.plist. This can easily be done through Xcode with File – New – File selecting the iOS Resource item and then Property List. Again, name it ApiKeys.


If Xcode has two ApiKeys.plist files listed in the project navigator, select one of them, right-click, and Delete and choose Remove Reference (not Trash!).

Add two items to the property list file,AERIS_CLIENT_ID and AERIS_APP_SECRET, and set them to the values of the keys that were created when you registered your application in the Aeris portal.

Stop and build the iOS application at this point in the iOS simulator for either the iPhone 5, 5s, 6, or 6 Plus. If Xcode complains about the lack of a provisioning profile click the Fix Issue button to generate an appropriate provisioning profile.


The simulator should prompt you requesting location access. Click Allow. Hopefully you see something like this in your simulator.


Simulating Location

We are using significant location change monitoring which relies primarily on recognizing locations of Wifi networks and cell towers rather than GPS. We use this rather than GPS because we don’t require the same level of accuracy for providing the current weather. Of course in large urban areas where cities blend together your app may show you to be in Dallas when in reality you are in Richardson. To simulate significant location changes in the simulator select the Debug menu and choose Location – Freeway Drive. At this point you can stop the application. As long as the Freeway Drive location simulation is running we will have data for us in our Watch app.

Note: If the app is not receiving location updates (and correspondingly you see a screen that has default label text), go to Hardware – Location and select None. Then, go back to Hardware – Location and select Freeway Drive.

Adding the Watch App

Let’s add a watch app to our weather app! I assume you have the aerisweather project open and you’ve already added API keys for Aeris and have run the starter app in the simulator. If you haven’t, do so, the remainder of the tutorial builds upon these steps.

Now, to add a Watch App target in Xcode go to File – New – Target and select Apple Watch.


Take a moment to note what the Watch App template does: This template builds a Watch App with an associated WatchKit app extension. It bears repeating that there are two items about to be added: the watch app itself which runs on the Apple Watch and the watchkit app extension which runs on the iPhone.

Click Next. When choosing your target options make sure for this tutorial to uncheck Include Notification Scene and Include Glance Scene. We will not be including either a notification or glance scene in this tutorial. Also ensure your Language is set to Swift. Click Finish.


Notice on this screen also there is a new bundle identifier. If you used com.yourcompany.aerisweather for your bundle identifier above, the new identifier for the watch app will be com.yourcompany.aerisweather.watchapp. As you will see below there is also a third bundle identifier for the app extension named com.yourcompany.aerisweather.watchkitextension.

Again, two new targets have been added, along with a new scheme. The targets are the watch app extension and watch app, and the scheme is aerisweather Watch App.


When first working with WatchKit it was confusing understanding how to simulate the Watch. The answer is by using the new scheme Xcode created, in our case it is named aerisweather Watch App. You must use the simulator for now; that is, you cannot run the app and app extension on your physical iPhone and simulate the watch.

Let’s lay out our watch interface using the Xcode storyboard created for us. Go to the file Interface.storyboard in the aerisweather Watch App folder. Like our iPhone app we will have a label for our last known location, a weather icon, current conditions label, temperature label, and at the bottom a last updated string. Here is our layout:


Laying items out on a watch interface is a bit easier than for an iOS device. For one reason we don’t have to use constraints! There are a few things to note. First, our layout was created by adding, in this order:

  • Label with a horizontal position of center
  • Group
  • Image inside the group with a horizontal position of Left and size of 64×64
  • Label inside the group with a horizontal position of Right
  • Label with a horizontal position of center
  • Label with a horizontal position of center

Second, we are using Avenir Next for our font, and have set the currentTemperature label to 30-pt, and the lastUpdated label to 10-pt. The remaining labels are 16-pt.

We now need to wire our elements up to the InterfaceController. Notice that the controller is in our extension and not in the Watch app itself! But if you click on Interface.storyboard and then the Assistant Editor icon (the joined circles), Xcode will place the storyboard and controller side-by-side in the editor.


Just as with building iOS applications, simply CTRL-click from the UI element and drag over to the InterfaceController class to insert the Outlet. To be consistent with our iPhone interface we’ll name these:

  • currentLocationLabel
  • currentWeatherIcon
  • currentTemperatureLabel
  • currentConditionsLabel
  • lastUpdatedLabel

After adding our IBOutlets

It is possible to run the watch app at this point and see the labels displayed. To run the app select the aerisweather Watch App scheme and click Run. To see the Apple Watch display go to the simulator and in the Hardware menu find External Displays and select one of the two Apple Watch displays.

Note: I’ve frequently had trouble with the simulator and watch kit extensions running properly. If you see in your Xcode debug navigator waiting to attach to your process and it never attaches, simply stop the application and run again. One more than one occasion I’ve had to restart the simulator altogether.

App Groups

To display the weather on the Apple Watch we’re going to need to fetch it from Aeris, but to fetch it from Aeris we’re going to need to obtain the last known location.

We need to stress that our app extension does not have access to iOS CoreLocation, thus it cannot retrieve the location and update the weather. Why? Because Apple warned us not to use it. From Apple’s WatchKit guidelines: “Avoid using technologies that request user permission, like Core Location. Using the technology from your WatchKit extension could involve displaying an unexpected prompt on the user’s iPhone the first time you make the request. Worse, it could happen at a time when the iPhone is in the user’s pocket and not visible.” So there you go.

To obtain the location we leverage sharing application data between our iOS application and our app extension. Select your project in the project navigator and select the aerisweather WatchKit Extension target. Then select the Capabilities page and scroll down to App Groups. Enable it and select groups.aerisweather.


Now, let’s add some code! Open InterfaceController.swift and add the following to the willActivate function:

Run your watch app again and you should see in your console log something like:

If the log instead says No last location you haven’t launched and run your iOS application. Remember, our watch application (and its corresponding extension) does not run CoreLocation, so it cannot directly obtain the user’s location. Only the iOS application requests and receives location information.

What exactly did we just do? By enabling app groups we are allowing our iOS application and our watchkit extension to share information. When our iOS application receives a new location from CoreLocation it reverse-geocodes the coordinate and then writes that information to a file in the app group group.aerisweather. When you launch your watch app it reads that information from the file in the app group. Check out the CoreLocationController‘s didUpdateLocations function to see where the information is being written.

Note that we must enable App Groups in each app that is granted permission to read and write in the shared group.aerisweather group.

Adding Aeris

Now, let’s get to adding Aeris to our watch app. To be more precise, we are adding Aeris to the watchkit app extension, as no Aeris code runs on the watch itself. As such, and this is key, we need to register another application in the HAMweather.com portal. Because we will be executing Aeris routines inside an application with a different bundle ID (remember, our extension has a bundle identifier of com.yourcompany.aerisweather.watchkitextension we need to register it.


Add your new secret to the ApiKeys.plist file as AERIS_EXTAPP_SECRET. In the property list you should now have three different keys: AERIS_CLIENT_ID (which is shared by all the applications in your account), AERIS_APP_SECRET and AERIS_EXTAPP_SECRET.


Next we need to configure our Objective-C bridging header for the watchkit extension target. If you’ve been working with Swift and Objective-C in the same projects you should be accustomed to this step by now.


Set the bridging header to $(SRCROOT)/bridgingHeader.h (you will see it is actually already a part of the overall project since we use it for our iOS application as well).

Now let’s add the Aeris.framework itself. Select the aerisweather WatchKit Extension target and then Build Phases. Click the disclosure triangle for Link Binary With Libraries and click the + icon. When presented with the Choose frameworks and libraries to add dialog, click Add Other. Locate the Aeris.framework item in your project directory, select it, and click Open.


We’ll be using the ApiKeys.swift in the watch kit extension, so we need to add it to the compile sources. You should already be in the Build Phases panel for the watch kit extension, so click the disclosure triangle for Compile Sources and then click the + icon. Find the ApiKeys.swift file, select it, and click Add.


Now, add the ApiKeys.plist to the Copy Bundle Resources list. In the same area, Build Settings, disclose the Copy Bundle Resources area, click +, and add the ApiKeys.plist.


The Aeris framework also requires us to add -ObjC to Other Linker Flags in the Build Settings (if you don’t you’ll get a nasty crash with -[__NSCFString awf_URLEncodedString]: unrecognized selector sent to instance). Go ahead and add it.


Adding AFNetworking

We are going to compile our AFNetworking code into our target (rather than using a pre-compiled framework), so we need to add all of the required AFNetworking files to our Compile Sources. Go back to Compile Sources in the Build Settings panel for the extension target, click the + icon, and find the AFNetworking folder. Select each of the .m files in the AFNetworking and UIKit+AFNetworking folders and add them. This can be done quickly by holding down the Option key while selecting each file.


There are iOS routines that are not available to app extensions. In particular sharedApplication is referenced in AFNetworking code and it is not available. If you tried to compile now, you will see an error like 'sharedApplication' is unavailable: not available on iOS (App Extension). The AFNetworking authors recognized this issue and added a flag AF_APP_EXTENSIONS that can be defined to not call on unavailable routines. For an example see Github, and here is a screenshot of what the error looks like:


To set the AF_APP_EXTENSIONS define go to your aerisweather WatchKit Extension Build Settings page and type preprocessor in the search box and locate the section headed Preprocessing. We will be building the Debug configuration in this tutorial so add AF_APP_EXTENSIONS=1 underneath the DEBUG=1 define.


Rebuilding at this point will still result in an error regarding iOS App Extensions and sharedApplication because a routine inside the Aeris SDK uses AFNetworkActivitityIndicatorManager. The offending routine in AFNetworkActivityIndicatorManager.m is

To resolve the issue simply wrap the contents of the method with #if !defined(AF_APP_EXTENSIONS) and #endif:

One more file needs to be touched: UIAlertView+AFNetworking.m. There are calls to UIAlertView in the methods showAlertViewForTaskWithErrorOnCompletion and showAlertViewForRequestOperationWithErrorOnCompletion. Wrap both calls to the UIAlertView with #if !defined(AF_APP_EXTENSIONS) and corresponding #endif.

Take a moment to compile and run your watch app: there should be no unresolved errors at this point!

Updating willActivate

Now that we have everything configured properly for using Aeris, let’s fill out our routine to include the following in the willActivate routine after we receive our location. This block of code goes immediately following the line println("Last location: \(city), \(state), at \(lastUpdatedAt)") in InterfaceController.swift.

The full willActivate routine should now look like this:

Running the Watch App

Running now you should see something like this in the logs:

and our corresponding watch app will show:


Oops! We need to add some assets to our app! Our iOS application currently contains a folder named Images.xcassets with all of our weather icons. We’ll leverage this and include them into our watch app. To do so right-click on Images.xcassets in the aerisweather folder and select Show in Finder.

Now select your Images.xcassets icon in the aerisweather Watch App folder (there are three folders named Images.xcassets in your project, make sure and select the right one here!) and then drag-and-drop the contents of the folder in the Finder into Xcode in the icon pane of your Images.xcassets. To be clear on this one: our existing iOS application contains all of the icons we need, but we need them on our watch as well. Using Show in Finder we expose the contents of our Images.xcassets so we can drag-and-drop the resources into the Watch App’s Images.xcassets!


Run the watch app again and you should see something like:


Get the Code on BitBucket

BitBucket contains two versions of the application:

  • The starter application which does not include the Apple Watch target. Download this file if you want to go through the above tutorial from start to finish.
  • The Apple Watch application which includes both the iPhone and Apple Watch apps. Download this file if you want to see the completed Apple Watch application.

Warning! Neither version comes with the ApiKeys.plist file which contains the Aeris SDK API keys. You have to create this file yourself and obtain your own API keys from HAMweather.com!

You can also obtain fork us on BitBucket, just go to the main project page.

Final Thoughts

It’s been fun putting together this tutorial on creating an Apple Watch app. If you install and run the aerisweather app on your iPhone it does take a toll on the battery over the course of the day using the significant location change monitoring feature of CoreLocation. I’m a bit disappointed in that, but have become somewhat accustomed to recharging the iPhone every day. It will be interesting what types of applications are available for Apple Watch on launch day and what iOS features they take advantage of!

Questions or Comments

I’ve been through the tutorial a number of times starting with the aptly named starter application. If you have any difficulty going through the tutorial please send a tweet to @iachievedit!


Using Swift in an Existing Objective-C Project

It’s clear from the Swift tutorials out there (including ours), that folks ask the question “How do I include Objective-C frameworks in my Swift project?” more often than “How do I include Swift code in my Objective-C project?” That’s understandable. Swift is new and shiny and we want to start off playing with Swift first and then mix in some Objective-C when we have to (which if you are using popular frameworks such as AFNetworking, Parse, etc., you have to quickly).

Since there’s plenty of Objective-C bridging header tutorials out there already, I thought I’d share my experience with the reverse direction: adding Swift code to an existing Objective-C project. I’d love to say it was easy and painless, but the reality is it was a pain in the ass (read this Stackoverflow thread to see why!).

Let’s start off the basic rule: Don’t add any Swift files to your project without reading this first. If you have already added Swift files and are scratching your head why things won’t work (namely that your -Swift.h can’t be found), delete them from your project and just start over and follow these steps:

Update Your Project Build Settings

Your project’s (not the target) build settings need to have the flag Defines Module set to YES. Go to your project build settings page and type Packaging in the search field and then set Defines Module to YES.

Screenshot 2014-11-26 16.04.46

Make Note of Your Product Module Name

Did you even know you had a product module name? I didn’t. To find it go to your target’s (not the project) build settings and again search for Packaging. Make note of the Product Module Name. In our case it is testing.

Screenshot 2014-11-26 16.10.33

Create Your Swift File

Create your Swift file with Xcode File – New – File. If Xcode asks whether or not you want to create a bridging header, you can if you like, but it’s not strictly required for what we’re trying to accomplish (Swift in Objective-C not the other way around, which is what the bridging header is for).

The Rules

There are rules around what’s required to get Swift objects living in harmony in your Objective-C code. For a complete overview see Apple’s documentation, but here’s what I’ve found to be true:

  • You have to #import <productModuleName-Swift.h> in every Objective-C class you plan to use your Swift classes in
  • The @objc declaration on a Swift class isn’t good enough – inherit from NSObject

The Header File

What others have pointed out in the Stackoverflow post referenced early is that unlike the the Objective-C bridging header the Swift bridging header is not a file you can see in your project, but is automatically generated in the build chain. That is, the compiler creates it as a temporary file prior to compiling your Objective-C. Even still, you have to #import it and if Xcode complains that it isn’t available you either don’t have Defines Module set to YES, or you named the header incorrectly (it is productModuleName-Swift.h, where productModuleName is your product module name), or (and here’s the irritating part) you added a Swift file to your project prior to setting Defines Module to YES.

The Swift Class Definition

Trying to use only @objc as an indicator that you’re going to use the Swift class in Objective-C code results in ARC complaints about alloc not being defined. Here’s a screenshot of declaring our Swift class like this:

Unfortunately we cannot compile due to the annoying No known class method for selector 'alloc' error:

Screenshot 2014-11-26 16.26.26

Changing our class to:

and the compilation proceeds and we can access our Swift class.

From there things proceeded relatively well. Our final test included the following Swift code:

with our delegate header including

and using it in our Objective-C application delegate:

As expected, our output:


If you can’t get Swift classes mixed into your Objective-C code on your first attempt, you’re aren’t an idiot. Future versions of Xcode one would hope will fix the annoying feature of failing to generate a -Swift.h header file if you didn’t do things in exactly the right order. In the meantime, follow these steps and definitely pore back over the Stackoverflow thread in case you missed something.