WCSession fails to sendMessage

Hi

Using Watch OS 3 beta 3 here. My watch app which previously worked with Watch OS 2 seems to be having connectivity issues.


When trying to send a message using


  [[WCSession defaultSession] sendMessage: ...


the error handler returns an error WCErrorDomain code 7014, WCErrorCodeDeliveryFailed.


The message is only attempted to be sent if the session is reachable, which it is at this point. However when I inspect the session object I can see that while reachable is true and the activationState is 2 (WCSessionActivationStateActivated), other properties such as paired and watchAppInstalled are actually false.

I am guessing these conflicting properties are connected to the problem.


Interestingly, when I inspect the session object when it is initially activated from the iOS app, the paired and watchAppInstalled values are true.


I have tried looking into the Watch console logs but there is literally so much going on there it is hard to pinpoint where the issue might be.


Has anyone else encountered this issue with Watch OS 3? Or can anyone point me towards what I should be looking for in the watch's console logs? Thanks.

Replies

were you ever able to find a solution to this? I keep getting the same error. Is this a bug with apples code or a bug in my code?


[WC] __67-[WCSession onqueue_sendResponseData:identifier:dictionaryMessage:]_block_invoke failed due to WCErrorCodeTransferTimedOut->IDSErrorTypeTimedOut->IDSResponseTimedOut

Have you found an answer to this issue yet? or a work around??


I'm having the same problem.



[WC] -[WCSession _onqueue_notifyOfMessageError:messageID:withErrorHandler:] 62AEA538-8E8A-446A-B4E3-65BB07315EBB errorHandler: NO with WCErrorCodeTransferTimedOut->IDSErrorTypeTimedOut->IDSResponseTimedOut

Im having the same problen using iOS 10.2, WatchOS 3 and Xcode 8.3.2 (8E2002).

But only when using the simulator, if i use a physical device this error does not happen.


WatchKit Extension[6128:479936] [WC] __33-[WCXPCManager onqueue_reconnect]_block_invoke error reconnecting to daemon due to NSXPCConnectionInterrupted
could not send message: Error Domain=WCErrorDomain Code=7012 "Message reply took too long." UserInfo={NSLocalizedDescription=Message reply took too long., NSLocalizedFailureReason=Reply timeout occured.}

For anyone still having this issue, if none of the previously mentioned solutions helped you, perhaps you have a similar issue to what I had.

My delegates were setup correctly and my messages were being passed along with the proper casting.

My issue ended up being related to the way I was creating my watch communication delegate objects and I think the main problem was having multiple instances of these objects being passed around.

I ended up created a watch communication singleton and using that for communication, which fixed my issue.

Here's a sample of the WatchCommunication singleton ( doesn't contain my full login / logout code since that is project specific ):

    import Foundation
    import WatchConnectivity
    
    class WatchCommunication: NSObject, WCSessionDelegate {
        static let shared = WatchCommunication()
        var watchSession: WCSession!
        
        override init() {
            super.init()
            
            if (WCSession.isSupported()) {
                print ("iOS WCSession.isSupported()")
                if (watchSession == nil) {
                    print ("iOS watchSession == nil")
                    watchSession = WCSession.default
                    watchSession!.delegate = self
                    watchSession!.activate()
                }
            }
        }
        
        func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
            print ("iOS activationDidCompleteWith")
        }
        
        func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
            print ("iOS didReceiveMessage")
        }
        
        func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {
            print ("iOS didReceiveMessage with replyhandler ")
    
            // DO SOMETHING HERE THEN REPLY
    
            replyHandler(message as [String: Any])        
        }
        
        func sessionDidBecomeInactive(_ session: WCSession) {
            print ("sessionDidBecomeInactive")
        }
        
        func sessionDidDeactivate(_ session: WCSession) {
            print ("sessionDidDeactivate")
        }

        func doLogin() {
            // Do something for login
        }
    }

For example when my phone logs in and I want to tell my watch, I just call:

    WatchCommunication.shared.doLogin()