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])
via
WatchConnectivity
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 = preset.name 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.