Introduction


Last year Apple introduced Swift at WWDC 2014. Here at AiT we’ve started to adopt it as our main language for new iOS work. I’ve noticed that there is a lack of tutorials or instructions for using Swift for Pebble iOS companion apps so I thought I’d write a simple introduction.

Creating a project


First of all make sure you have the latest Xcode installed. At the time of writing this is Xcode 6.2.

  1. Start the Create a new Xcode project process
  2. You can choose any iOS project type. For this guide I’m using a Single View Application
  3. Give it a name and change the language to Swift
  4. Choose a location and you should have a new project to work with

Cocoapods

I prefer to use cocoapods for managing third party integrations. They’ve recently been working on full support for Swift and Pebble have published their SDK as a cocoapod.

First we need to make sure cocoapods is up to date

Note, if you’re using a Ruby manager such as RVM, drop the sudo from the next command.

  1. Open a terminal up
  2. sudo gem install cocoapods
  3. enter your password if prompted
  4. pod —version to confirm it installed correctly

Back in Xcode:

  1. Right click on your project root in the left hand bar
  2. Select New File
  3. Choose Other
  4. Then Empty
  5. Name the file Podfile, untick all of the targets at the bottom and make sure it saves to the root of the project

In your new Podfile add the following line:

pod 'PebbleKit'

We now need to install the pod:

  1. Close Xcode completely
  2. Open a terminal window and change directory to the root of your new project
  3. pod install
  4. Once that is finished open the project folder in Finder (quick tip: open . will do this)

The Bridging Header

The pod should be installed but now we need to make it available in Swift. All Swift symbols within a target are automatically made available to each other, unfortunately this doesn’t include Objective-C symbols. To do this we need something called a Bridging Header

Here’s how to do it:

  1. Now open the file ending in .xcworkspace
  2. Again right click on the project root in the left hand bar
  3. Select New File
  4. Now Source
  5. Then Header File
  6. You can name this anything you like. The convention is normally [ProjectName]-Bridging.h
  7. Delete all the code below the comments and replace it with #import "PebbleKit.h"
  8. Now select the project root in the left hand side
  9. Make sure the main target is selected and go to Build Settings
  10. Scroll down to Swift Compiler - Code Generation
  11. Change the value of Objective-C Bridging Header to be the name of the bridging header you created earlier
  12. Build the project to make sure it compiles without errors

Creating a Pebble watchapp to connect to

Before we can connect to a watchapp, we need to create a quick demo one.

  1. Open a terminal window again and navigate to the root of the project
  2. pebble new-project Swift
  3. cat Swift/appinfo.json to view the app settings
  4. Make a note of the uuid value. In my case it’s acde6706-633f-404d-b99a-1fc57842593a

Now build and deploy the watch app to your Pebble so that we’re able to make use of it later.

Setting up the connection

Now we can get our hands dirty with some Swift.

First open the AppDelegate.swift

Below var window: UIWindow? add:

 var watch: PBWatch? {
     didSet {
         if let watch = watch {
             watch.appMessagesLaunch({ (_, error) in
                 if error != nil {
                     println("App launched!")
                 }
             })
         }
     }
 }

This is a variable to keep a reference to the watch. When it’s set to a non-nil value it’ll attempt to launch the watch application on the Pebble.

Now in application(didFinishLaunchingWithOptions..), add the following few lines before the return statement (replacing the uuid with the one from your project):

 let pebble = PBPebbleCentral.defaultCentral()
 pebble.delegate = self
         
 var uuidBytes = Array<UInt8>(count:16, repeatedValue:0)
 let uuid = NSUUID(UUIDString: "acde6706-633f-404d-b99a-1fc57842593a")
 uuid?.getUUIDBytes(&uuidBytes)
 pebble.appUUID = NSData(bytes: &uuidBytes, length: uuidBytes.count)

 watch = pebble.lastConnectedWatch()

This previous bit of code is perhaps the bit which is hardest to figure out. In Objective-C land uuidBytes would be of type uuid_t that’s a typedef of __darwin_uuid_t which is in turn a typedef of an array of 16 unsigned chars. In Swift this translates to an array of unsigned 8bit integers. Fortunately arrays in Swift allow you to create pre-initialised arrays of a fixed size for exactly this kind of purpose.

At this point Xcode will be complaining about the AppDelegate not conforming to the PBPebbleCentralDelegate interface. At the bottom of the file add the following code to fix this:

extension AppDelegate: PBPebbleCentralDelegate {
     func pebbleCentral(central: PBPebbleCentral!, watchDidConnect watch: PBWatch!, isNew: Bool) {
         if self.watch != watch {
             self.watch = watch
         }
     }
 }

This implements the delegate interface and sets the watch property we declared earlier.

Finally, make sure the watch app isn’t running on the Pebble and then build and run the iOS app. You should find the watch app launches and you now have a working connection.

Conclusion

This is the bare bones of how to get started with Swift. In a future post I'll be demonstrating how to use Swift to interpret C structures sent via the DataLogging interface.

As always, please ask any questions via the comments or you can find me on Twitter as @earltedly.

7 Comments