WatchOS 2.2.2 Debug Symbols A.W.O.L.


On Jul 18th Apple released several operating system updates. WatchOS 2.2.2 was one of those released updates. Four days ago.

Since installation I have been unable to debug watch extensions on my real device since Xcode looks for, attempts to install, and fails to install WatchOS 2.2.2 debugging symbols.

I have filed Radar # 27470205. Other developers have as well. Here is a thread about the situation on Apple’s developer forum (under Xcode/iOS Simulators and Devices). Here is a StackOverflow question about the situation.

So far there are no answers or solutions for this situation. I don’t know what is going on at Apple, but it would be nice if one person spent a few minutes and posted the DMG up so Xcode could consume and apply the debugging symbols. I know they are jamming on the Fall releases, but there has to be a DMG somewhere for the symbols right?

Relegated to debug in the Simulators.

WatchConnectivity gotcha. willActivate()

This may seem simple for many who have been busy developing Watch extensions for the Apple Watch, but it stumped me for about a minute. Not long, but long enough for me to slap my forehead.

I have several WKInterfaceControllers with each implementing WCSessionDelegate for communication between iOS application and watch extension. No problem. However when navigating back to my initial WKInterfaceController (using the back arrow the watch OS provides after having pushed:

pushControllerWithName("presetView", context: thisList[currentIndex])

My communication to the iOS application was broken. I thought it might have something to do with the button @IBAction method or something… but since we don’t have a setTarget for WKInterfaceButtons, that wasn’t it.

I initially set all that up the communication in the awakeWithContext method. Guess what? When you navigate back, that’s been purged. If you also set it up in willActivate, you’ll be good.

So in both my override func willActivate() and override func awakeWithContext(context: AnyObject?) I have this code (supporting class variable):

if WCSession.isSupported() {
    session = WCSession.defaultSession()
    session.delegate = self

Problem solved. When navigating back, the session object is created again as it needs to be for calls on session to operate.

Swift: When you have an Optional String you need to remove

Screen Shot 2016-07-21 at 10.09.57 AM

Recently I have been developing an iOS app that comes with a companion Apple Watch extension. I wanted to play with the communication between iOS and WatchOS using

func session(session:WCSession, didReceiveMessage message:[String:AnyObject])



It was working well and I thought I had it nailed down. Nope.

At one point my watch extension makes a request to the iOS app for a preset index. That’s so I can display the preset number in an alert on the watch at another point. I was setting the title of the alert to display something like “Preset 2”. Instead I was getting “Preset Optional(2)”. Not good.

I thought the problem was in unwrapping an Optional on the watch extension side. I tried all sorts of things that did nothing. How can you unwrap a String since they are not Optional?

Finally I printed the full watch extension message and found the Optional was already in the String when it arrives. So I had to look at the iOS ViewController that created the message to send to the watch extension.

Here is a breakdown (simplified) of what it looks like for the iOS application.

func session(session: WCSession, didReceiveMessage message: [String : AnyObject])
        if let info = message as? Dictionary<String,String>
            if let s = info["needPresetData"]{
                let index = Int(s)
                let preset:Preset = self.presetObjectArray[useIndex]
                let p1 =
                let p2 = preset.source
                let window = UIApplication.sharedApplication().keyWindow
                let vc = window?.rootViewController as! ViewController
                let dict:[String:String] = ["description":"\(index)_\(p1)\n\n(p2)"]
                vc.session.sendMessage(dict, replyHandler: {(_: [String:Anyobject])-> Void in
                }, errorHandler: {(error ) -> Void in

I think the braces balance (I typed this by hand). They should anyway. Do you see anything obvious in there? I didn’t for a while until I posted to StackOverflow and the comments came pouring in. There was an optional being injected into the constructed string prior to being sent (as I discovered later).

The solution was an explicit unwrapping of something I didn’t think was an Optional to begin with.

let dict:[String:String] = ["description":"\(index!)_\(p1)\n\n(p2)"]

Look at that. index!

This solved the problem on the other end where I was splitting the index off the String (into an array and used the number for the alert title). I was going mad, but the answer should have been more obvious.

Thanks to those on StackOverflow that helped me go through it. I don’t have code reviews for prototypes I usually build at work and that one sailed right by me for a while.

G. Gerlach Enigma with diver’s bracelet


It took me an email with G. Gerlach and about 20 minutes of using their supplied spring bar tool to install. It’s a sun blasted stainless steel (316L type) at 22mm. The tool Gerlach supplies with each watch isn’t bad, just a little small. I have a tool that I ordered a long time ago that’s larger and more robust and has a small regular screw tip on one end.

It took at least 15 minutes just to get the new bracelet on the watch. I then had to remove 4 links and then tweak on the diver’s clasp area.

Previously because the fit is so tight, I emailed Gerlach about sending another bracelet because I thought the one they supplied didn’t properly align. They told me if I couldn’t get it on (it should fit Enigma) to send the watch and bracelet to them in Poland and they would install it. Reading that as a nice brush off, I tried again with more vigor.  Which paid off for me. And them.

Why did I change from the default canvas/leather?

Honestly, the supplied canvas/leather that came on the Enigma is a great strap. It buckles easily, looks perfectly retro, doesn’t have metal tabs to hold the band down, wears wonderfully, and is a joy.

However, if I am going to be in and out of the water as I plan this summer, that canvas and leather are not going to be able to keep up with me. That’s why I ordered the stainless with the watch.

It does dress the watch up and now I don’t need to worry about water at all. It also adds some heft which is nice.

Tagged : /

Enigma has landed.

A review to follow but spot on delivery by G. Gerlach. Gorgeous. 

I took delivery while on vacation so I had to wait as the timepiece waited on my desk at work. I picked it up this evening. 

The wooden presentation box is excellent. Beside it was the mesh stainless band. Very heavy and nice. Heavier than the piece itself. I am not sure if I’ll install it because the default canvas and leather strap is so nice and retro. 

The only downside I see is the lume. It’s quite pedestrian if not mime. The rest is quite nice, especially the attention to detail. It’s quite light in my opinion. The dimensions are all spot on for my wrist. 

I’ve been wearing for few hours and I’m still catching glances here and there to see if I still like it. Tomorrow morning I shall know for certain. It’s always the way. 

Gerlach is a great new player ink the affordable watch market. You get more than you pay for. My Enigma shall endure hours of pool time for the 4th of July. 


Lots of time of hard swimming no problem. The canvas band held up well too when wet and dry on repeat. Watch is pretty great. It’s no Rolex but it’s pretty great. This will replace my Seiko diver.