Skip to content

Commit dbafc29

Browse files
alburdette619facebook-github-bot
authored andcommitted
Fix facebook#8615: NetInfo.isConnected for iOS
Summary: This is fixing facebook#8615. The problem was that, on initialization, the `_connectionType` variable was still set to its default value of `RCTConnectionTypeUnknown`. The exposed API method did nothing to determine this unless a subscription had be established and then the method would simply return the last reported value. Instead, the exposed oneshot API call now actually checks the connection status through the same methods as the subscription and updates RCTNetInfo’s values before returning. In order to avoid reporting events without a subscription, a flag is set and unset on calls to start/stopObserving. - start app - observe the (in)correct reporting of the manual status - change network status to offline - press refresh - observe the manual fetch - start subscription - change network status to online - press refresh to show that the manual refresh works (only now working for current RN version) - change network status to offline - stop subscription - change network status to online - press refresh to show manual refresh does(n't) work without subscription - start subscription to show it updates to current Current Behavior: https://drive.google.com/file/d/1Ods6HORgp_vfm1mQVjGwhtH1D7issxjo/view?usp=sharing Fixed Behavior: https://drive.google.com/file/d/11H1UOF33LeMGvXEOoapU62ARDSb7qoYv/view?usp=sharing [IOS] [BUGFIX] [Libraries\Network\RCTNetInfo.m] - Fixed facebook#8615, `iOS: NetInfo.isConnected returns always false`, by decoupling the fetch from the status of the subscription. Closes facebook#17397 Differential Revision: D7102771 Pulled By: hramos fbshipit-source-id: ea11eb0b1a7ca641fc43da2fe172cf7b2597de4a
1 parent 2ad3407 commit dbafc29

File tree

1 file changed

+61
-40
lines changed

1 file changed

+61
-40
lines changed

Libraries/Network/RCTNetInfo.m

+61-40
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,69 @@ @implementation RCTNetInfo
4141
NSString *_effectiveConnectionType;
4242
NSString *_statusDeprecated;
4343
NSString *_host;
44+
BOOL _isObserving;
4445
}
4546

4647
RCT_EXPORT_MODULE()
4748

4849
static void RCTReachabilityCallback(__unused SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info)
4950
{
5051
RCTNetInfo *self = (__bridge id)info;
52+
if ([self setReachabilityStatus:flags] && self->_isObserving) {
53+
[self sendEventWithName:@"networkStatusDidChange" body:@{@"connectionType": self->_connectionType,
54+
@"effectiveConnectionType": self->_effectiveConnectionType,
55+
@"network_info": self->_statusDeprecated}];
56+
}
57+
}
58+
59+
#pragma mark - Lifecycle
60+
61+
- (instancetype)initWithHost:(NSString *)host
62+
{
63+
RCTAssertParam(host);
64+
RCTAssert(![host hasPrefix:@"http"], @"Host value should just contain the domain, not the URL scheme.");
65+
66+
if ((self = [self init])) {
67+
_host = [host copy];
68+
}
69+
return self;
70+
}
71+
72+
- (NSArray<NSString *> *)supportedEvents
73+
{
74+
return @[@"networkStatusDidChange"];
75+
}
76+
77+
- (void)startObserving
78+
{
79+
_isObserving = YES;
80+
_connectionType = RCTConnectionTypeUnknown;
81+
_effectiveConnectionType = RCTEffectiveConnectionTypeUnknown;
82+
_statusDeprecated = RCTReachabilityStateUnknown;
83+
_reachability = [self getReachabilityRef];
84+
}
85+
86+
- (void)stopObserving
87+
{
88+
_isObserving = NO;
89+
if (_reachability) {
90+
SCNetworkReachabilityUnscheduleFromRunLoop(_reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
91+
CFRelease(_reachability);
92+
}
93+
}
94+
95+
- (SCNetworkReachabilityRef)getReachabilityRef
96+
{
97+
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, _host.UTF8String ?: "apple.com");
98+
SCNetworkReachabilityContext context = { 0, ( __bridge void *)self, NULL, NULL, NULL };
99+
SCNetworkReachabilitySetCallback(reachability, RCTReachabilityCallback, &context);
100+
SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
101+
102+
return reachability;
103+
}
104+
105+
- (BOOL)setReachabilityStatus:(SCNetworkReachabilityFlags)flags
106+
{
51107
NSString *connectionType = RCTConnectionTypeUnknown;
52108
NSString *effectiveConnectionType = RCTEffectiveConnectionTypeUnknown;
53109
NSString *status = RCTReachabilityStateUnknown;
@@ -96,54 +152,19 @@ static void RCTReachabilityCallback(__unused SCNetworkReachabilityRef target, SC
96152
self->_connectionType = connectionType;
97153
self->_effectiveConnectionType = effectiveConnectionType;
98154
self->_statusDeprecated = status;
99-
[self sendEventWithName:@"networkStatusDidChange" body:@{@"connectionType": connectionType,
100-
@"effectiveConnectionType": effectiveConnectionType,
101-
@"network_info": status}];
102-
}
103-
}
104-
105-
#pragma mark - Lifecycle
106-
107-
- (instancetype)initWithHost:(NSString *)host
108-
{
109-
RCTAssertParam(host);
110-
RCTAssert(![host hasPrefix:@"http"], @"Host value should just contain the domain, not the URL scheme.");
111-
112-
if ((self = [self init])) {
113-
_host = [host copy];
114-
}
115-
return self;
116-
}
117-
118-
- (NSArray<NSString *> *)supportedEvents
119-
{
120-
return @[@"networkStatusDidChange"];
121-
}
122-
123-
- (void)startObserving
124-
{
125-
_connectionType = RCTConnectionTypeUnknown;
126-
_effectiveConnectionType = RCTEffectiveConnectionTypeUnknown;
127-
_statusDeprecated = RCTReachabilityStateUnknown;
128-
_reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, _host.UTF8String ?: "apple.com");
129-
SCNetworkReachabilityContext context = { 0, ( __bridge void *)self, NULL, NULL, NULL };
130-
SCNetworkReachabilitySetCallback(_reachability, RCTReachabilityCallback, &context);
131-
SCNetworkReachabilityScheduleWithRunLoop(_reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
132-
}
133-
134-
- (void)stopObserving
135-
{
136-
if (_reachability) {
137-
SCNetworkReachabilityUnscheduleFromRunLoop(_reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
138-
CFRelease(_reachability);
155+
return YES;
139156
}
157+
158+
return NO;
140159
}
141160

142161
#pragma mark - Public API
143162

144163
RCT_EXPORT_METHOD(getCurrentConnectivity:(RCTPromiseResolveBlock)resolve
145164
reject:(__unused RCTPromiseRejectBlock)reject)
146165
{
166+
SCNetworkReachabilityRef reachability = [self getReachabilityRef];
167+
CFRelease(reachability);
147168
resolve(@{@"connectionType": _connectionType ?: RCTConnectionTypeUnknown,
148169
@"effectiveConnectionType": _effectiveConnectionType ?: RCTEffectiveConnectionTypeUnknown,
149170
@"network_info": _statusDeprecated ?: RCTReachabilityStateUnknown});

0 commit comments

Comments
 (0)