Skip to content
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