Communicating to a backgrounded WatchOS application

I recently jumped into the WatchOS-specific SwiftUI ocean in order to add WatchOS capabilities to an existing iOS application., So I didn’t know what I didn’t know if you know what I mean. Learning on the fly. So I got iOS to WatchOS communication working well using sendMessage. Pretty simple cookie-cutter kind of stuff but its still quite magical. Its very snappy too which is wonderful – the Simulator does not hold a candle to it.

By accident I discovered that when my watch was backgrounded, the sendMessage just fails. Hmm. I am testing with an Apple Watch Series 4 – so it “sleeps” constantly. So what I did was search for an answer and didn’t find a whole lot online. I rolled up my own method into my project and I am sharing it here. You could always roll up and enum to support different message types.

On the iPhone side of the project

func sendMessage(msg: [String : Any])
{
    // session defined in the Class this resides in.
    if self.session.isReachable == false &&
       self.session.isPaired == true
    {
        self.session.transferUserInfo(msg)
    } else {
        self.session.sendMessage(msg, replyHandler: nil){ error in
            print(error.localizedDescription)
        }
    }
}

So when the WatchOS application is reachable, sendMessage is used. If not, transferUserInfo is used instead which will work in the background. When the watch application is made active again, your message will have already been delivered and the results implemented.

On the Watch side of the project

func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
    print(message)
    DispatchQueue.main.async {
        self.message = message["message"] as? String ?? "Unknown"
    }
}

func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any] = [:]) {
    print(message)
    DispatchQueue.main.async {
        self.message = userInfo["message"] as? String ?? "Unknown"
    }
}

The watch-side can receive messages sent either way. These are WCSessionDelegate methods. By default you need ro support didReceiveMessage,. so you need to add the didReceieveUserInfo in order to get messages in the background.

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.