Add allowsCellularAccess flag for iOS fetch calls (#24242)

Summary:
On iOS in React Native, immediately after successfully connecting to a WiFi network, if 4G is also on, it is possible that network requests sent via fetch get sent over 4G instead of WiFi for several seconds (between 1 and 40+ seconds depending on the device and network in my experience). If the calls are meant to be communicating with a local Wireless Device (such as a wireless router, etc.), then API calls that get sent over 4G to the internet are lost. Note that Reachability/NetInfo are saying that we are connected to a WiFi network and are not sufficient to prevent this from happening. To prevent this, I would like to be able to set an instance property that iOS exposes for network requests allowsCellularAccess to NO to ensure a request is never sent over 4G.

This code needs to be able to accept a flag to allow the user to override the default value of YES, but only when they explicitly opt in to this decision. I am not sure the best place to set and pass in this value, so I created [this issue](https://github.com/react-native-community/discussions-and-proposals/issues/113), where it was recommended that I make a PR and discuss how best to do this here. Before this PR could be merged we would need to allow the NO to be configurable in some way.

Additional information about the [allowsCellularAccess](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1409406-allowscellularaccess?language=objc) property can be found in the [Apple documentation.](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/Platform-SpecificNetworkingTechnologies/Platform-SpecificNetworkingTechnologies.html#//apple_ref/doc/uid/TP40010220-CH212-SW9)

[iOS] [Added] - Ability to force network requests to use WiFi using the allowsCellularAccess property. This can ensure that network requests are sent over WiFi if communicating with a local hardware device and is accomplished by setting a flag. Default behavior of allowing network connections over cellular networks when available is unchanged.
Pull Request resolved: https://github.com/facebook/react-native/pull/24242

Differential Revision: D15316760

Pulled By: cpojer

fbshipit-source-id: 96df43b4eff6b4301c853df6b2e5c6e1bb1abda0
This commit is contained in:
Parker Bond 2019-05-13 07:26:46 -07:00 коммит произвёл Facebook Github Bot
Родитель ddce74388a
Коммит 01c70f2fb9
1 изменённых файлов: 13 добавлений и 0 удалений

Просмотреть файл

@ -60,10 +60,23 @@ RCT_EXPORT_MODULE()
{ {
// Lazy setup // Lazy setup
if (!_session && [self isValid]) { if (!_session && [self isValid]) {
// You can override default NSURLSession instance property allowsCellularAccess (default value YES)
// by providing the following key to your RN project (edit ios/project/Info.plist file in Xcode):
// <key>ReactNetworkForceWifiOnly</key> <string>YES</string>
// This will set allowsCellularAccess to NO and force Wifi only for all network calls on iOS
// If you do not want to override default behavior, do nothing or set key with value "NO"
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
NSString *useWifiOnly = [infoDictionary objectForKey:@"ReactNetworkForceWifiOnly"];
NSOperationQueue *callbackQueue = [NSOperationQueue new]; NSOperationQueue *callbackQueue = [NSOperationQueue new];
callbackQueue.maxConcurrentOperationCount = 1; callbackQueue.maxConcurrentOperationCount = 1;
callbackQueue.underlyingQueue = [[_bridge networking] methodQueue]; callbackQueue.underlyingQueue = [[_bridge networking] methodQueue];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
// set allowsCellularAccess to NO ONLY if key ReactNetworkForceWifiOnly exists AND string value is "YES"
NSString *compareKeyToForceWifiOnly = @"YES";
if (useWifiOnly) {
configuration.allowsCellularAccess = ![compareKeyToForceWifiOnly isEqualToString:useWifiOnly];
}
[configuration setHTTPShouldSetCookies:YES]; [configuration setHTTPShouldSetCookies:YES];
[configuration setHTTPCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways]; [configuration setHTTPCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
[configuration setHTTPCookieStorage:[NSHTTPCookieStorage sharedHTTPCookieStorage]]; [configuration setHTTPCookieStorage:[NSHTTPCookieStorage sharedHTTPCookieStorage]];