Communication between iPhone and Apple Watch breaks down occasionally

Originator:florian.goessler
Number:rdar://30104132 Date Originated:19. Jan 2017
Status:Open Resolved:
Product:watchOS + SDK Product Version:3.X
Classification: Reproducible:Sometimes
 
Summary:
Occasionally our watch app does not show updates from the phone anymore. This is visible by having no or outdated data.
The problem resolves itself usually within 5 to 10 minutes and communication starts to work again. Sometimes also an app restart seems to help.
During this the watch did never show a "disconnected to phone" state, bluetooth and wifi was on and phone and watch were in close proximity (< 0.5 meters). They were also connected to the local wifi most of the time.

To transmit data to the watch we are sending messages to it using the WatchConnectivity framework. If this problem occurs we can see from our logs that the watch app does not receive messages anymore. On the phone side the error handler is occasionally called but not reliably. If it’s called there are different error messages: timeout or even “watch not reachable”. These error messages happen although the WatchConnectivity framework (WCSession) still reports the watch as reachable. Interestingly the watch can still successfully send messages to the phone. The communication only breaks in one direction - phone to watch.

Steps to Reproduce:
There’s no reliable way to reproduce it but repeating the following procedure eventually leads to the broken state:
1.) Kill the watch app
2.) Start the phone app and hard kill it. Do this AFTER the watch app is dead such that it isn’t relaunching the phone app in the background immediately through a message.
3.) Lock the phone (optional but seems to increase the failure rate)
4.) Start the watch app
5.) Observe if you get messages on the watch from the phone app

Expected Results:
The watch app receives messages from it's phone app. Meaning delegate callbacks being called and so on.

Actual Results:
The messages that the phone app sends are not received. Occasionally the error handler on the phone side is called but not reliably.

Version:
We saw this with different Watches and iPhones running watchOS 3.X and iOS 10.X - also the latest versions as of this writing (iOS 10.2 and watchOS 3.1.1). 

Notes:
Things we tried that did not help:
- Trying to “reactivate” the WCSession via “activateSession” whenever we detect a problem (error handler called).
- Use the application context mechanism to transmit the information instead of the message mechanism. Didn’t help since both seem to break simultaneously.
- Sending messages from the watch to the phone in a regular interval and use the reply handler to get the latest state information. Didn’t help since the replies get lost as well if messages and application context don’t work.
- Reducing the amount of communication between watch and phone.
- Add a pinging from the watch to the phone to keep the phone app more alive in the background.
- Retry to send messages if the error handler is called.
- Add a reply handler to each message and retry to send it if we don’t get the reply within a certain timeframe.

Configuration:
Used iPhones: iPhone 6S and iPhone 7
Used watches: original Apple Watch and Series 2 Apple Watch
We are building against watchOS 3.0 and up and iOS 10.0 and up only. Using Swift 3 of course and Xcode 8.2.1.

Comments

4 years later, still broken

In 2021 I am still battling this problem on a daily basis. Sometimes it works, sometimes like today I have to troubleshoot for literally 3 hours before it starts working again https://openradar.appspot.com/FB9053529

Probably not a bug on Apple's side since they refuse to admit it, it's most likely a feature.

By mss.geoteach at June 20, 2021, 10:31 p.m. (reply...)

Additional note:

We also saw some occasions where the phone is clearly not reachable (flight mode enabled and wifi and bluetooth off) and the reachable property of the WCSession reported true.

Seems to me like this flag is just totally broken and should be ignored by app developers...

By florian.goessler at Feb. 17, 2017, 10:57 p.m. (reply...)

Update from ticket author

Apple responded and also asked for more logs. I also provided them with an update of our investigation that can be found below:

We were able to further identify the problem (the one on watchOS 3.1.3) and have a workaround for now. The problem seems to be that the registered WCSessionDelegate's sessionReachabilityDidChange method is NOT called for every reachability change. Therefore our app isn't notified when the state switches from "not reachable" to "reachable". This seems to happen in the following cases: - After initial session activation. Only the session:activationDidCompleteWith: method is called but not sessionReachabilityDidChange. We already handled that case before. - Sometimes when the watch app wasn't active for a while on relaunch of the app ("warm start") the sessionReachabilityDidChange method is called before even the ExtensionDelegate's applicationDidBecomeActive method is called to notify us that the reachability state is now false. After that however often times it's not called again to notify us that the phone is reachable again. The state just switches silently to true within a second after applicationDidBecomeActive.

Our workaround now is to check the session reachability every time we try to send a message. We cannot rely on the sessionReachabilityDidChange invocation to start and stop our send message communication.

This reachability issue is only on watchOS 3.1.3 for now - we haven't tested under 3.2.0 beta yet. We will attach the required logs as soon as possible - for both pre watchOS 3.1.3 and with watchOS 3.1.3.

Probably these are independent issues and for now we couldn't see the initially reported issue with watchOS 3.1.3 anymore.

By florian.goessler at Jan. 31, 2017, 6:17 p.m. (reply...)

Update from ticket author after watchOS 3.1.3 release:

After updating to watchOS 3.1.3 the problem appearance slightly changed.

Now the session's reachable status changes more often and goes to false on the watch (phone not reachable) when we are seeing the communication breakdown. However it now also switches to false in cases where the communication still works. Also the reachable flag on the watch and the phone are not always in sync - sometimes the phone says the watch is reachable but the watch reports the phone unreachable. This still happens although other communication between phone and watch seem to work (e.g. loading apple map data) and the watch never shows the disconnected status icon.

Still this unreachable status persists for varying timeframes - between 30sec to 5 or even 10 minutes. Also the occurrence rate differs. On some devices/ during some test session we see the issue nearly 80-90% of the time in an half hour session and sometimes only once within an session.

By florian.goessler at Jan. 25, 2017, 11:59 p.m. (reply...)

Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!