Before you can use WatchConnectivity, WCSession
has to be activated on iOS as well as on watchOS (Apple suggests that you check first that the device supports WatchConnectivity).
Activation is done asynchronously. When finished, func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?)
is called in the delegate of the session object (which has to be set when the activation is initiated).
If activation was successful, the activationState is now .activated
. Only then can any transfer be initiated.
There are several kinds of transfer. Some require .isReachable
to be true, and some not.
updateApplicationContext(_:)
sends a dictionary to the counterpart device. It will be received when the device is active. If this function is called multiple times before the counterpart device is active, only the last dictionary is received. This transfer does not require .isReachable
.
transferUserInfo(_:)
sends also a dictionary, but all dictionaries are delivered if the function is called multiple times. This transfer does also not require .isReachable
.
sendMessage(_:replyHandler:errorHandler:)
sends also a dictionary, and again all dictionaries are delivered if the function is called multiple times. This transfer does require .isReachable
.
If replyHandler
is specified, it must be ensured that it is actually available when the system tries to call it. (It can happen that the app calls this function, goes to background before the reply is sent, and is then terminated by the system. If the reply is then called, the thread will crash.).
There are other kinds of transfers for data, files, and complications, see the docs.
Now .isReachable
is handled differently on iOS and watchOS.
iOS: .isReachable
is true
, if a paired and active watch is in range, the corresponding WatchKit extension is running, and the WatchKit extension’s .isReachable
property is true
.
watchOS: .isReachable
is true
, if the WatchKit extension is running in the foreground or is running with a high priority in the background, and the iOS device is within range. Please note that the iOS app is not required to be active. If the watch starts a transfer and the iOS app is not active, it is launched into background and can handle the communication.
You mentioned that .isReachable
is always false
.
So if this relates to the watchOS app, the reason may be that the activation of the WCSession was not finished successfully, or the iOS device is not within range.
If this relates to the iOS app, the reason may again be that the activation of the WCSession was not finished successfully, the watch app is not running in the foreground or is not running with a high priority in the background, or the watch is not in range.
Hope this helps a little!