Laur Stefan
Laur Stefan

Reputation: 1589

WatchKit the Darwin Notification is not received on the watch

I am trying to send a notification from my iPhone to the Watch device using CFNotificationCenterAddObserver on the watch and CFNotificationCenterPostNotification.(I am NOT testing on the Xcode simulator).

This is my code in the iOS app:

#include <CoreFoundation/CoreFoundation.h>
...
- (void)sendLogOutNotificationToWatch{
    dispatch_async(dispatch_get_main_queue(), ^{
        CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), CFSTR("NOTIFICATION_TO_WATCH"), (__bridge const void *)(self), nil, TRUE);
    });
}

And this is how I use it on the apple watch extension app:

@implementation InterfaceController
.....
- (void)awakeWithContext:(id)context {

    [super awakeWithContext:context];
    ....
    [self registerToNotification];
}

- (void)registerToNotification
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@com.test.app" object:nil];
    CFNotificationCenterRemoveObserver( CFNotificationCenterGetDarwinNotifyCenter(), (__bridge const void *)( self ), CFSTR( "NOTIFICATION_TO_WATCH" ), NULL );

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userLoggedOut ) name:@"com.test.app" object:nil];
    CFNotificationCenterAddObserver( CFNotificationCenterGetDarwinNotifyCenter(), (__bridge const void *)( self ), didReceivedDarwinNotification, CFSTR( "NOTIFICATION_TO_WATCH" ), NULL, CFNotificationSuspensionBehaviorDrop );

}

void didReceivedDarwinNotification()
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"com.test.app" object:nil];
}


- (void)didDeactivate {
    [super didDeactivate];

    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"com.test.app" object:nil];
    CFNotificationCenterRemoveObserver( CFNotificationCenterGetDarwinNotifyCenter(), (__bridge const void *)( self ), CFSTR( "NOTIFICATION_TO_WATCH" ), NULL );
    [[NSNotificationCenter defaultCenter] removeObserver:self];

}
- (void)userLoggedOut{
    [self showAlertViewwithTitle:@"Notice" andMessage:@"User logged out on iPhone device!"];
}

Upvotes: 0

Views: 481

Answers (2)

Sorin Cioban
Sorin Cioban

Reputation: 2225

Is this on watchOS 2? As others suggested, you need to use WatchConnectivity. Darwin notification won't work since the watchOS 2 process no longer sits on the phone as it used to in watchOS 1. Besides, WatchConnectivity is so much more convenient.

Upvotes: 1

lehn0058
lehn0058

Reputation: 20257

You should use WatchConnectivity to send a message from the iPhone to the Apple Watch.

The API's are almost identical on both the Watch and iPhone. If your watch app is not running, or the screen is off you should use transferUserInfo. If your watch app is running and the screen is on you can use sendMessage. I normally wrap these calls, attempting to use sendMessage first and if it fails use transferUserInfo:

// On the iPhone
func trySendMessage(message: [String : AnyObject]) {
    if self.session != nil && self.session.paired && self.session.watchAppInstalled {
        self.session.sendMessage(message, replyHandler: nil) { (error) -> Void in
            // If the message failed to send, queue it up for future transfer
            self.session.transferUserInfo(message)
        }
    }
}

On the watch you will need to implement both session:DidReceiveMessage and session:didReceiveUserInfo. Note that I don't bother checking if the watch is reachable, because if it is not (or if it starts reachable and moves out of range after the check but before the transfer has finished) then the data will still get sent when it is back in range from transferUserInfo.

Upvotes: 1

Related Questions