Session reachability status bug?

- (void)willActivate {
    /
    [super willActivate];

    if ([WCSession isSupported]) {
        WCSession *session = [WCSession defaultSession];
        session.delegate = self;
        [session activateSession];

        NSLog(@"willActivate: %d",session.reachable);
    }
}
- (void)sessionReachabilityDidChange:(WCSession *)session{
    NSLog(@"sessionReachabilityDidChange: %d",session.isReachable);
}


Above code block prints

willActive:1

immediately.

However, after that it prints:

sessionReachabilityDidChange: 0
sessionReachabilityDidChange: 1


I am trusting session.reachable to send a message to iOS app, but that value has incorrect information.


If I go back and reopen this InterfaceController, same thing happens, except, this time sessionReachabilityDidChange is never called and reachable value is correct this time.

Replies

No one having this issue??

I have your same issue but I think it is a Simulator bug.

It requires a small delay to be really reachable after launch.

reachablility is still buggy in the simulator, unfortunatly thats all i have to test against, its almost like "i hope it works" on actual devices.. but im seeing the above, the simulator will tell me its reachable then i make a SendMessage Call and it comes back with and error that is not reachable.

I'm having this issue intermittently in the InterfaceController for the main WatchApp, and always in the GlanceInterface. And, I might add, it's not just in the simulator, it's on the watch as well. My Glance interface calls to:


session.sendMessage(applicationData, replyHandler: { (reply: [String : AnyObject]) -> Void in

self.isNetWorkAvailable = (reply["status"]?.boolValue)!

})


Always fail if I take out the check for session.reachable (which is always false)

It seems there is a bug in the simulator. Use the following code and it will run in the simulator

private(set) var appReachable = false

     if WCSession.isSupported() {
            session = WCSession.defaultSession()
            session?.delegate = self
            session?.activateSession()
            if TARGET_OS_SIMULATOR == 1 {
                appReachable = true
            }
     }

//some other code


if appReachable {
            session?.sendMessage(["action":action], replyHandler: nil, errorHandler: { (error) -> Void in
                debugPrint("failed to send message for action \"\(action)\": \(error.localizedDescription)")
            })
        }

//some more code


This works for me in the Simulator with the GM release

I’ve noticed another odd behavior between the simulators and actual hardware. Whether the app on the phone is active or I put the phone simulator into Hardware->Lock (simulator screen goes black). I can run the watch simulator and the watch extension works as expected. I let both simulators sit with neither app running. After a minute or two, or even 10 minutes. I run the watch app again, and all works again as expected.


Now, if I do the same on the actual hardware (phone and watch), the phone is unlocked, I then run the watch app everything works as it did in the simulators, but if the phone is locked and after about 10 minutes or so. The watch does not get to the “session didRecieveApplicationContext”. When I “Slide to unlock” the phone and run the watch app again, the didRecieveApplicationContext method on the watch works. I doesn’t matter if the WCSession setup is in the didFinishLaunchingWithOptions or in the viewControllers viewdidload on the phone. I’m on 9.0.1 and watch 2.0.


I’m lost. Has anyone else seen this behavior?

Hi,


unfortunately, the whole WCSession stuff in Watch OS seems to be unreliable (I am talking about Watch OS on a watch, not in a simulator). I am facing the following issues:


- after having startet the app on the watch [session isReachable] returns YES even if the iPhone app is not running at all; is the status buffered (should not be the case)?

- stopping running the app on the iPhone does not result always in a call to sessionReachabilityDidChange:

- sometimes sessionReachabilityDidChange: is called although the reachability has not changed (messages are going through).

Hi Hardy,


after having startet the app on the watch [session isReachable] returns YES even if the iPhone app is not running at all

This is as designed as the Watch app is allowed to wake the iOS app up in the background, therefore it is reachable even if it is not running.


stopping running the app on the iPhone does not result always in a call to sessionReachabilityDidChange:

See above. The iOS app is reachable even when it is not running; devices just have to be connected.


sometimes sessionReachabilityDidChange: is called although the reachability has not changed

There are times when the app has gone through lifetime events (suspension, background, etc) where this callback could occur even though there is no change since the last time it was called. Best practice would be to check the value of reachable in the callback and take actions based upon that, rather than just the occurance of the callback.

Hi Viking,


your statement is in contrast to the documentation (WatchOS 2.0):


In your WatchKit extension, the value of this property is

YES
when a matching session is active on the user’s iPhone and the device is within range so that communication may occur. On iOS, the value is
YES
when the paired Apple Watch is in range and the associated Watch app is running in the foreground. In all other cases, the value is
NO


(I believe that a matching session cannot be called active if the iOS is not running in the foreground nor background, or?)


Furthermore, there is no documentation when the iOS app can be woken app in the background (WatchOS 2.0); or better I do not know where this is written. I was surprised that sometimes(!) the WatchOS app indeed is able to wake up the iOS app but this behaviour cannot be reproduced. Actually, in about 95% of the cases this is impossible. Only when the iOS app has once been started and moved to the background it can be reliably activated to run in the background.


I am checking the reachability status in sessionReachabilityDidChange: but the issue is that the status itself is not correct respectively sessionReachabilityDidChange: is not always called when the reachability changes.

Please file bugs if you find the documentation not matching the observed behavior. It could either be a bug in the documentation, or in the behavior. We will internally figure out which of the two it is, and screen the bug to the right group here at Apple.


I'd suggest checking out the 2015 WWDC talk on WatchConnectivity which discusses reachability and waking the iOS app up in the backround quite extensivly, and also has some great examples.

Hi Viking,


my major problem is that I really do not know if it is a documentation or an OS bug. I do not want to rant but I have to tell you the truth: I very often do not know if a WCSession behavior is intended or not because the whole WCSession API is not reliable respectively reproducable. Example: if I can always wake up an app into the background and let it run and this behavior is not documented I assume that it is a documentation bug. If I cannot wake up an app but in one or two exceptional cases I assume that this an OS bug (and in my situation these are only one or two cases I can even not reliably reproduce, so there is no meaning to file an OS bug report).


I have also checked the 2015 WWDC talk before but it does not say anything about reachability and whether I can launch and run(!) an iOS app in the background (I can do data transfers in the background as mentioned in the WWDC talk but this is not equivalent with being able to launch an app and let it run in the background).


In summary: I do not know what the intended behavior / documentation is.

Sorry to hear you are having such a hard time with the WatchConnectivity framework. Often the best way to get answers whether something is a bug or not (documentation or behavior) is to file a good bug report with a sample project attached that reproduces the problem, even if you are only seeing a problem occasionally!


As for the WWDC video, it definitely does discuss both launching the iOS app in the background as well as reachability. Specifically check out the following timestamps 29:10 and 45:15 for the most pertinent sections.

Hi Viking,


thanks for the hint. I missed the first part when searching for it again. I will file a documentation bug.

Much appreciated!

Hello,


Any news regarding this?


I've stumbled upon this recently. My watch app works fine during initial run but if I exit (press the crown) and re-enter the app (via watch menu), sometimes (95%) session will not work and return error 7014.

I've managed to workaround this by detecting the error, registering a callback block and invoking that block when session reachability changes to 1. It works but it isn't very pretty... 😝


Anyway, I've also filed a bug: 23662971.


Any update in this would be appreciated!


Thanks,

Francisco