TIL: Boy, Have I Been Misusing SCNetworkReachability

After reading this discussion — courtesy of Jeremy Sherman — I learned that I’ve been misusing SCNetworkReachability for years. I’ve been allowing certain user-facing states and features to be influenced by the current reachability state, even to the point of blocking some user-initiated network requests. In ’sodes, for example, I’m currently preventing a playback attempt whenever the network is unreachable.

Turns.

Out.

SCNetworkReachability, like all networking, is not reliable enough to support that kind of behavior. If there’s a false negative (which is much more common than one might think), it means the app becomes needlessly unusable.

SCNetworkReachability should only be used to influence what you do about a network request that has already failed, not an initial request that has yet to be attempted. Use a negative status to determine whether or not you attempt an automatic retry, or to tweak the user-facing language of an alert. Use a positive status to consider retrying an earlier failed request. Never prevent a user-initiated request from being attempted just because SCNetworkReachability thinks there’s not a reachable network.

You can see the code I’m using to monitor reachability status right here on GitHub. To drive the point home to myself, I’m probably going to change the public API of my network reachability wrapper from this:

var isReachable: Bool {...}

to something that more accurately models the truth:

enum ReachabilityStatus {
    case probablyNotButWhoKnows
    case itWorkedThatOneTimeRecently
}

var status: ReachabilityStatus {...}

SCNetworkReachability, or rather the realities of real-world networking at whose mercy SCNetworkReachability remains, is just not reliable enough to deserve a Bool.

|  15 Oct 2018