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])

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.

This site uses Akismet to reduce spam. Learn how your comment data is processed.