Extension delegate does not implement delegate method

In XCode 8 Beta 4, I'm seeing these logs generated by my Simulated watch app extension delegate.


Extension[67345:31900928] [WC] __66-[WCSession onqueue_handleDictionaryMessageRequest:withPairingID:]_block_invoke delegate ExtensionDelegate does not implement delegate method


Is there a WCSession delegate method I'm missing? I think I have them all covered. Can I safely ignore these logs?


Thanks.

Answered by Developer Tools Engineer in 170416022

yea, a nil replyHandler is ok but in that case your WCSession delegate should be implementing:

- (void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *, id> *)message;

which I'm guessing you weren't, and instead you had implemented:

- (void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *, id> *)message replyHandler:(void(^)(NSDictionary<NSString *, id> *replyMessage))replyHandler;


Either way it sounds like you figured it out. I apologies if the documentation didn't make things clear enough, and that you had to spend so much time debugging.

That log indicates that your WCSession delegate is receiving a dictionary message that expects a reply, but it hasn't implemented:

- (void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *, id> *)message replyHandler:(void(^)(NSDictionary<NSString *, id> *replyMessage))replyHandler;


Perhaps you mistakingly (only) implemented:

- (void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *, id> *)message;

?

My extension delegate does indeed implement the proper method, Viking. My code transfers the logic to the InterfaceController here.


- (void)session:(WCSession *)sess didReceiveMessage:(NSDictionary<NSString *, id> *)message
   replyHandler:(void(^)(NSDictionary<NSString *, id> *replyMessage))replyHandler
{
    [myInterface session:sess didReceiveMessage:message replyHandler:replyHandler];
}

But it seems to occur after each time

-(void)session:(nonnull WCSession *)sess  didReceiveApplicationContext:(nonnull NSDictionary<NSString *,id> *)applicationContext
{
    [myInterface session:sess didReceiveMessage:applicationContext replyHandler:nil];
}

completes.
The main app sends the watch an ApplicationContext periodically.

After further research, it seems that the warning message is logged because the iOS app originally supplied a nil replyHandler to its sendMessage method, which I've now modified in lines 2-4 below.

        [session sendMessage:WatchMessage
         replyHandler:^(NSDictionary<NSString *,id> * _Nonnull replyMessage) {
            NSLog(@"reply from watch received");
         }
         errorHandler:^(NSError *__nonnull error) {
             NSLog(@"error sending to watch %@",error);
         }
        ];

My code masked this by immediately issuing an updateApplicationContext, regardless of whether sendMessage succeeded.

[session updateApplicationContext:WatchMessage error:nil];


In any event, this behavior should not occur. A replyHandler is optional as per the documentation.

Accepted Answer

yea, a nil replyHandler is ok but in that case your WCSession delegate should be implementing:

- (void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *, id> *)message;

which I'm guessing you weren't, and instead you had implemented:

- (void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *, id> *)message replyHandler:(void(^)(NSDictionary<NSString *, id> *replyMessage))replyHandler;


Either way it sounds like you figured it out. I apologies if the documentation didn't make things clear enough, and that you had to spend so much time debugging.

I think I understand. I did not notice this behavior in WatchOS 2.2.


If I send a message via

A) "sendMessage session:message:replyHandler:non-nil" the receiver side has to implement the "didReceiveMessage session:message:replyhandler:" overload.


but if I send via

B) "sendMessage session:message:replyHandler:nil", the receiver side has to implement the "didReceiveMessage session:message" overload


Yes, I did not implement (B). Rather, I implemented (A) and conditionally executed the replyHandler only if it was non-nil. I wouldn't have thought two overloads would be necessary, nor did I notice the alternate in the documentation.

Extension delegate does not implement delegate method
 
 
Q