Search code examples
iosobjective-cwatchkit

Can you wake the phone from WatchKit 1.0 app?


I am developing a client app that has geofences to notify users when they approach one of the app's vendors.

When the location manager fires, it invokes a local notification with a fireDate of the current date.

If the user's iPhone is locked and they have a paired Apple watch, it displays a custom notification on the watch. The user can either close the notification, or tap on a custom action button.

I would like the custom action button to wake up the phone and display the vendor's page in the app. Sort of an automatic handoff. The user expresses their desire to go to the vendor page by clicking the "view vendor" page on the watch.

Is it possible? I'm currently using the +[WKInterfaceController openParentApplication:reply:] method to try to invoke the parent iOS application. However, if the phone is locked, nothing happens. The iPhone screen stays dark, no sound, nothing.

If you unlock the phone before tapping the action button on the watch, it does invoke the app and send it the message that displays the vendor page.

As a second question, is it possible to set up my watch app so that when the user clicks the notification button the watch app passes a message to the iPhone app and then close the watch app? Right now my client doesn't have anything running on the watch OTHER than a custom notification that takes the user to the vendor page. The watch app's main screen is only a placeholder at this point, and it looks stupid when you click the custom action button and get that empty screen.

(As an aside, I'm aware that in watch kit 1.0 the watch app's code actually runs on the iPhone, but it runs as a separate process, so it's useful to talk about the watch sending a message to the iPhone, even though that's not exactly what's going on.)


Solution

  • The answer to this is apparently no, and no.

    Apple views waking the phone as something that the user has to do directly from the phone.

    What I did was to have the openParentApplication:reply:error: message from the watch to the phone look for a reply dictionary from the iPhone that includes a key/value pair wasInBackground containing a bool YES or NO.

    if wasInBackground == YES, it displays a modal message telling the user that they need to open the app on their phone in order to see the contents.

    If wasInBackground == NO, then the phone was awake and the app was frontmost, so the app was able to display the content from the user.

    Then, on the phone side, if the message from the watch comes in while in the background, I check the type of action the watch is requesting. If it's a request to display driving directions, I create a block that has the code to display driving directions, and set it in a "blockToRunOnReturnToForeground" property of the app delegate. Then, when the app delegate gets a applicationWillEnterForeground message, it checks for a non-nil "blockToRunOnReturnToForeground", and it there is one, invokes it and nils it out.

    The result is that when the user finally returns the app to the foreground, it then issues the request for driving directions.

    The user experience isn't quite a seamless as I would like, but at least the user isn't left totally confused as to why nothing happens when they click one of the action buttons on the watch.