Reputation: 15247
I have an iOS app that communicates with the paired watch using WatchConnectivity. In most cases, it works without problems, on the simulators and on the devices.
The problem:
During development on the simulators, I get now and then the following communication error when I try to send a direct message from iOS to watchOS using WCSession.default.sendMessage(_:replyHandler:errorHandler:)
:
Error Domain=WCErrorDomain Code=7007
"WatchConnectivity session on paired device is not reachable."
I have read this related post, but it does not apply to my case, because my app does work normally.
My questions:
How can it be that the watch simulator becomes not reachable while the app is running on the iOS simulator?
Does it make sense just to retry sendMessage
after a while?
Is there any workaround?
Upvotes: 5
Views: 4164
Reputation: 15247
As a workaround, I modified the sendMessage
function so that in case of this error the transfer is retried a number of times. Since then, all sendMessage
transfers are executed successfully.
func sendMessage(_ message: [String: AnyObject],
replyHandler: (([String: Any]) -> Void)?,
errorHandler: ((Error) -> Void)?) {
guard let communicationReadySession = communicationReadySession else {
// watchOS: A session is always valid, so it will never come here.
print("Cannot send direct message: No reachable session")
let error = NSError.init(domain: kErrorDomainWatch,
code: kErrorCodeNoValidAndReachableSession,
userInfo: nil)
errorHandler?(error)
return
}
/* The following trySendingMessageToWatch sometimews fails with
Error Domain=WCErrorDomain Code=7007 "WatchConnectivity session on paired device is not reachable."
In this case, the transfer is retried a number of times.
*/
let maxNrRetries = 5
var availableRetries = maxNrRetries
func trySendingMessageToWatch(_ message: [String: AnyObject]) {
communicationReadySession.sendMessage(message,
replyHandler: replyHandler,
errorHandler: { error in
print("sending message to watch failed: error: \(error)")
let nsError = error as NSError
if nsError.domain == "WCErrorDomain" && nsError.code == 7007 && availableRetries > 0 {
availableRetries = availableRetries - 1
let randomDelay = Double.random(min: 0.3, max: 1.0)
DispatchQueue.main.asyncAfter(deadline: .now() + randomDelay, execute: {
trySendingMessageToWatch(message)
})
} else {
errorHandler?(error)
}
})
} // trySendingMessageToWatch
trySendingMessageToWatch(message)
} // sendMessage
Upvotes: 3