Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #8615: NetInfo.isConnected for iOS #17397

Closed
wants to merge 6 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 61 additions & 40 deletions Libraries/Network/RCTNetInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,69 @@ @implementation RCTNetInfo
NSString *_effectiveConnectionType;
NSString *_statusDeprecated;
NSString *_host;
BOOL _isObserving;
}

RCT_EXPORT_MODULE()

static void RCTReachabilityCallback(__unused SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info)
{
RCTNetInfo *self = (__bridge id)info;
if ([self setReachabilityStatus:flags] && self->_isObserving) {
[self sendEventWithName:@"networkStatusDidChange" body:@{@"connectionType": self->_connectionType,
@"effectiveConnectionType": self->_effectiveConnectionType,
@"network_info": self->_statusDeprecated}];
}
}

#pragma mark - Lifecycle

- (instancetype)initWithHost:(NSString *)host
{
RCTAssertParam(host);
RCTAssert(![host hasPrefix:@"http"], @"Host value should just contain the domain, not the URL scheme.");

if ((self = [self init])) {
_host = [host copy];
}
return self;
}

- (NSArray<NSString *> *)supportedEvents
{
return @[@"networkStatusDidChange"];
}

- (void)startObserving
{
_isObserving = YES;
_connectionType = RCTConnectionTypeUnknown;
_effectiveConnectionType = RCTEffectiveConnectionTypeUnknown;
_statusDeprecated = RCTReachabilityStateUnknown;
_reachability = [self getReachabilityRef];
}

- (void)stopObserving
{
_isObserving = NO;
if (_reachability) {
SCNetworkReachabilityUnscheduleFromRunLoop(_reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
CFRelease(_reachability);
}
}

- (SCNetworkReachabilityRef)getReachabilityRef
{
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, _host.UTF8String ?: "apple.com");
SCNetworkReachabilityContext context = { 0, ( __bridge void *)self, NULL, NULL, NULL };
SCNetworkReachabilitySetCallback(reachability, RCTReachabilityCallback, &context);
SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);

return reachability;
}

- (BOOL)setReachabilityStatus:(SCNetworkReachabilityFlags)flags
{
NSString *connectionType = RCTConnectionTypeUnknown;
NSString *effectiveConnectionType = RCTEffectiveConnectionTypeUnknown;
NSString *status = RCTReachabilityStateUnknown;
Expand Down Expand Up @@ -96,54 +152,19 @@ static void RCTReachabilityCallback(__unused SCNetworkReachabilityRef target, SC
self->_connectionType = connectionType;
self->_effectiveConnectionType = effectiveConnectionType;
self->_statusDeprecated = status;
[self sendEventWithName:@"networkStatusDidChange" body:@{@"connectionType": connectionType,
@"effectiveConnectionType": effectiveConnectionType,
@"network_info": status}];
}
}

#pragma mark - Lifecycle

- (instancetype)initWithHost:(NSString *)host
{
RCTAssertParam(host);
RCTAssert(![host hasPrefix:@"http"], @"Host value should just contain the domain, not the URL scheme.");

if ((self = [self init])) {
_host = [host copy];
}
return self;
}

- (NSArray<NSString *> *)supportedEvents
{
return @[@"networkStatusDidChange"];
}

- (void)startObserving
{
_connectionType = RCTConnectionTypeUnknown;
_effectiveConnectionType = RCTEffectiveConnectionTypeUnknown;
_statusDeprecated = RCTReachabilityStateUnknown;
_reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, _host.UTF8String ?: "apple.com");
SCNetworkReachabilityContext context = { 0, ( __bridge void *)self, NULL, NULL, NULL };
SCNetworkReachabilitySetCallback(_reachability, RCTReachabilityCallback, &context);
SCNetworkReachabilityScheduleWithRunLoop(_reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
}

- (void)stopObserving
{
if (_reachability) {
SCNetworkReachabilityUnscheduleFromRunLoop(_reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
CFRelease(_reachability);
return YES;
}

return NO;
}

#pragma mark - Public API

RCT_EXPORT_METHOD(getCurrentConnectivity:(RCTPromiseResolveBlock)resolve
reject:(__unused RCTPromiseRejectBlock)reject)
{
SCNetworkReachabilityRef reachability = [self getReachabilityRef];
CFRelease(reachability);
resolve(@{@"connectionType": _connectionType ?: RCTConnectionTypeUnknown,
@"effectiveConnectionType": _effectiveConnectionType ?: RCTEffectiveConnectionTypeUnknown,
@"network_info": _statusDeprecated ?: RCTReachabilityStateUnknown});
Expand Down