Search code examples
iosiphoneios8reachability

main thread blockage is causing app to crash in iOS 8


My app crashes on startup because with exception 'failed to scene-update in time'

this is because reachability does not return on time Here is the stack trace

com.tjango.Plus3 failed to scene-update in time

Elapsed total CPU time (seconds): 2.590 (user 2.590, system 0.000), 12% CPU 
Elapsed application CPU time (seconds): 0.302, 1% CPU


Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0:
_semaphore_wait_trap + 8
__dispatch_semaphore_wait_slow + 252
_xpc_connection_send_message_with_reply_sync + 184
___SCNetworkReachabilityServer_targetStatus + 192
___SCNetworkReachabilityGetFlags + 440
_SCNetworkReachabilityGetFlags + 232
-[Reachability currentReachabilityStatus] Reachability.m:295

this happens on iOS 8 only.

The function where it gets stuck is Apple's Reachability library : I can't figure out why would this function block it.

- (NetworkStatus)currentReachabilityStatus

{

    NSAssert(_reachabilityRef != NULL, @"currentNetworkStatus called with NULL SCNetworkReachabilityRef");

    NetworkStatus returnValue = NotReachable;

    SCNetworkReachabilityFlags flags;



    if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags))

    {

        if (_alwaysReturnLocalWiFiStatus)

        {

            returnValue = [self localWiFiStatusForFlags:flags];

        }

        else

        {

            returnValue = [self networkStatusForFlags:flags];

        }

    }



    return returnValue;

}

Solution

  • Reachability is probably the single most incorrectly used library on iOS. These rules help:

    1. Reachability should not be called on the main thread. Call it on a secondary thread and have that thread notify the main thread of network changes.
    2. Do not check network status before attempting a connection - just try the connection and handle errors as needed. There are times when the network will be offline to save power until someone tries a connection.
    3. Reachability is mostly useful for detecting when the network comes back online after being offline. You can retry failed connections at that point.

    See my comment: iOS Reachability fails to catch the case where connected to WiFi but not logged in