GRPC Objective-C  1.26.0
gRPC iOS Network Transition Behaviors

Network connectivity on an iOS device may transition between cellular, WIFI, or no network connectivity. This document describes how these network changes should be handled by gRPC and current known issues.

Expected Network Transition Behaviors

The expected gRPC iOS channel and network transition behaviors are:

Implementations

gRPC iOS with TCP Sockets

gRPC's default implementation is to use TCP sockets for networking. It turns out that although Apple supports this type of usage, it is not recommended by Apple and has some issues described below.

Issues with TCP Sockets

The TCP sockets on iOS is flawed in that it does not reflect the viability of the channel connection. Particularly, we observed the following issues when using TCP sockets:

gRPC iOS library's resolution to TCP socket issues

We introduced ConnectivityMonitor in gRPC iOS library v0.14.0 to alleviate these issues in TCP sockets, which changes the network transition behaviors a bit.

We classify network connectivity state of the device into three categories based on flags obtained from SCNetworkReachability API:

Reachable ConnectionRequired IsWWAN Category
0 X X None
X 1 X None
1 0 0 WiFi
1 0 1 Cellular

Whenever there is a transition of network between two of these categories, all previously existing channels are assumed to be broken and are actively destroyed. If there is an unfinished call, the call should return with status code UNAVAILABLE.

ConnectivityMonitor is able to detect the scenario of the first issue above and actively destroy the channels. However, the second issue is not resolvable. To solve that issue the best solution is to switch to CFStream implementation which eliminates all of them.

gRPC iOS with CFStream

gRPC iOS with CFStream implementation (introduced in v1.13.0) uses Apple's networking API to make connections. It resolves the issues with TCP sockets mentioned above. Users are recommended to use this implementation rather than TCP socket implementation. The detailed behavior of streams in CFStream is not documented by Apple, but our experiments show that it accords to the expected behaviors. With CFStream implementation, an event is always received when the underlying connection is no longer viable. For more detailed information and usages of CFStream implementation, refer to the https://github.com/grpc/grpc/blob/master/src/objective-c/README-CFSTREAM.md "user guide".