Watch-Phone communication when Phone app is in background

There doesn't seem to be a background mode that will allow an iPhone app to run in the background in order to communicate with its watch app, which is running in the foreground on the watch. Have I missed something?

Related but not quite the same: say the iPhone app can run in the background to get location updates. But it only wants to do so when the watch app is running. Is there a way that the watch app can wake, or even start, the iPhone app, and for the iPhone app to then enable location updates?

(I have previously implemented Bluetooth background modes - I think I could achieve both of the above if I had the watch and the iPhone communicate using my own BTLE protocol, rather than using Watch Connectivity. Is this true?)

Did you try sendMessage(_:replyHandler:errorHandler:)? Calling this method from your watchOS app while it is active and running wakes up the corresponding iOS app in the background and makes it reachable, which I believe is what you are looking for.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Interesting, thanks for the suggestion. I'll investigate.

Did you try sendMessage(_:replyHandler:errorHandler:)? Calling this method from your watchOS app while it is active and running wakes up the corresponding iOS app in the background and makes it reachable, which I believe is what you are looking for.

Consider a simple phone speedometer app. I use CoreLocation to get GPS data and show the speed on the phone screen. It doesn't need to do anything in the background.

Now I want to add watch support, sending the speed data from the phone to the watch using the applicationCOntext. (Let's ignore the possibility that the watch app could do this using its own GPS.)

Now we need the phone app to run in the background, so that the watch can continue to show the speed when the phone is sleeping. So I enable the location background mode for the phone app and turn on CLLocationManager.allowsBackgroundLocationUpdates.

This works but isn't ideal, because for users who don't have a watch etc. we are wasting power on the phone. So we really want to turn allowsBackgroundLocationUpdates on only when the watch app is in use.

You suggest that I could use sendMessage(...) to have the watch tell the phone that it is in use. So, on the phone I would implement didReceiveMessage and change allowsBackgroundLocationUpdates.

But... is it allowed for an app that has "when in use" location permission to turn on background location updates when it is already in the background? I guess it probably is, but I'll need to check.

So when exactly do I want the watch to send its "I'm in use, send data" and "I'm no longer in use, stop sending data" messages? I guess I send them from appropriate WKApplicationDelegate methods. But I don't think I want the phone to turn its location updates on and off every time the user raises or lowers their arm. I guess I can send the messages that frequently, and have the phone app decide whether or not to turn updates off, perhaps with a timeout.

Ziqiao, any thoughts about this? Thanks.

is it allowed for an app that has "when in use" location permission to turn on background location updates when it is already in the background? I guess it probably is, but I'll need to check.

I haven't tried exactly that either. I can't think of any reason that it shouldn't be allowed though.

I guess I send them from appropriate WKApplicationDelegate methods. But I don't think I want the phone to turn its location updates on and off every time the user raises or lowers their arm. I guess I can send the messages that frequently, and have the phone app decide whether or not to turn updates off, perhaps with a timeout.

This sounds reasonable to me. Note though that sendMessage can only be called while the Watch Connectivity session (WCSession) is active.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

is it allowed for an app that has "when in use" location permission to turn on background location updates when it is already in the background?

This does seem to work.

I guess I send (messages from the watch to the phone) from appropriate WKApplicationDelegate methods

Sending a message from applicationDidBecomeActive doesn't work because the phone isn't reachable yet, but I can send the message from WCSessionDelegate.sessionReachabilityDidChange, shortly later. applicationWillResignActive works OK. So now the phone knows when the watch app is alive and it's useful to send state updates, even when it (the phone app) is in the background.

I think what I have is probably equivalent to watching sessionReachabilityDidChange from the phone, except that that doesn't wake up the phone app. Maybe it should?

Thanks.

sessionReachabilityDidChange ... doesn't wake up the phone app.

Or maybe it does... this stuff is all horribly difficult to debug!

Watch-Phone communication when Phone app is in background
 
 
Q