1

I'm working on extension for the Apple Watch and I need to communicate with the containing app.

MMWormwhole seems like a nice approach for this type of communication. The problem is that my messages are not delivered to the containing app when it is running in background, when opened from openParentApplication.

Is there any way make the MMWormwhole to receive messages while in background mode?

aumanets
  • 3,703
  • 8
  • 39
  • 59

2 Answers2

1

I use the wormhole the other way: communicating from the app to the watch extension. It seems likely that instead of using the wormhole you could pass your message in the userInfo parameter of the openParentApplication call you're already making.

However, if there's a complex reason where you want to pick up some other message or whatever you could manually check in the application: handleWatchKitExtensionRequest: reply: method. Something like:

    if let updatedMessage: AnyObject = wormhole.messageWithIdentifier(updatedKey) {
            processUpdatedWormholeMessage(updatedMessage)
    }

should work even when the app is in the background.

Timothy Sanders
  • 206
  • 3
  • 7
1

Yes, it is possible. But you have to ensure that the main app on the iPhone is not suspended before it can send its reply. This can be done by starting a background task in handleWatchKitExtensionRequest as specified in the documentation.

Code in the app delegate of the main app on iPhone:

- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void ( ^)( NSDictionary * ))reply
{
   __block UIBackgroundTaskIdentifier watchKitHandler;
   watchKitHandler = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"backgroundTask"
                                                               expirationHandler:^{
                                                                 watchKitHandler = UIBackgroundTaskInvalid;
                                                               }];

   if ( [[userInfo objectForKey:@"request"] isEqualToString:@"getData"] )
   {
      // get data
      // ...
      reply( data );
   }

   dispatch_after( dispatch_time( DISPATCH_TIME_NOW, (int64_t)NSEC_PER_SEC * 1 ), dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
       [[UIApplication sharedApplication] endBackgroundTask:watchKitHandler];
   } );
}
Pang
  • 9,564
  • 146
  • 81
  • 122
John
  • 8,468
  • 5
  • 36
  • 61
  • Can you tell me if there is any duration limitation? – aumanets May 03 '15 at 10:39
  • It depends but your app can read the property backgroundTimeRemaining of UIApplication to find out: NSLog(@"Time Remaining: %f", [[UIApplication sharedApplication] backgroundTimeRemaining]); See http://developer.radiusnetworks.com/2014/11/13/extending-background-ranging-on-ios.html – John May 03 '15 at 13:37
  • I just tried it and I got a very, very large value when the app on my iPhone was active (as expected). When it was not active, the value was 179.942669. That means that the system would kill the background task after about three minutes. – John May 03 '15 at 13:41
  • Is there any way to extend those 3 minutes? I need the app to be active for around 10/15 minutes, because it schedules events that are sent to the watch in varied intervals. – aumanets May 03 '15 at 14:45
  • You can create a new background task every time your watch app calls openParentApplication. However, if your watch app does not call, I think you cannot have the iPhone app run longer than three minutes in the background without a server initiating a background task to start. – John May 03 '15 at 14:48
  • This totally answers my question. Thank you very much. – aumanets May 03 '15 at 19:01