This commit is contained in:
overtake
2017-03-14 11:50:09 +03:00
parent 2d14089ca5
commit 45c19fbc4c

View File

@@ -64,32 +64,36 @@ static void MTNetworkAvailabilityContextRelease(const void *info)
_delegate = delegate;
[[MTNetworkAvailability networkAvailabilityQueue] dispatchOnQueue:^
{
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
_reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)&zeroAddress);
if (_reachability != NULL)
{
MTNetworkAvailabilityContext *availabilityContext = [[MTNetworkAvailabilityContext alloc] init];
availabilityContext.context = self;
SCNetworkReachabilityContext context = { 0, (__bridge void *)availabilityContext, &MTNetworkAvailabilityContextRetain, &MTNetworkAvailabilityContextRelease, NULL };
[self updateReachability:kSCNetworkReachabilityFlagsReachable notify:false];
[self updateFlags:true];
_timer = [[MTTimer alloc] initWithTimeout:5.0 repeat:true completion:^
{
[self updateFlags:true];
} queue:[MTNetworkAvailability networkAvailabilityQueue].nativeQueue];
[_timer start];
if (SCNetworkReachabilitySetCallback(_reachability, &MTAvailabilityCallback, &context))
SCNetworkReachabilitySetDispatchQueue(_reachability, [MTNetworkAvailability networkAvailabilityQueue].nativeQueue);
}
}];
{
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
_reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)&zeroAddress);
if (_reachability != NULL)
{
MTNetworkAvailabilityContext *availabilityContext = [[MTNetworkAvailabilityContext alloc] init];
availabilityContext.context = self;
SCNetworkReachabilityContext context = { 0, (__bridge void *)availabilityContext, &MTNetworkAvailabilityContextRetain, &MTNetworkAvailabilityContextRelease, NULL };
[self updateReachability:kSCNetworkReachabilityFlagsReachable notify:false];
[self updateFlags:true];
__weak MTNetworkAvailability *weakSelf = self;
_timer = [[MTTimer alloc] initWithTimeout:5.0 repeat:true completion:^
{
__strong MTNetworkAvailability *strongSelf = weakSelf;
if (strongSelf != nil) {
[strongSelf updateFlags:true];
}
} queue:[MTNetworkAvailability networkAvailabilityQueue].nativeQueue];
[_timer start];
if (SCNetworkReachabilitySetCallback(_reachability, &MTAvailabilityCallback, &context))
SCNetworkReachabilitySetDispatchQueue(_reachability, [MTNetworkAvailability networkAvailabilityQueue].nativeQueue);
}
}];
}
return self;
}
@@ -103,12 +107,12 @@ static void MTNetworkAvailabilityContextRelease(const void *info)
_timer = nil;
[[MTNetworkAvailability networkAvailabilityQueue] dispatchOnQueue:^
{
[timer invalidate];
SCNetworkReachabilitySetCallback(reachability, NULL, NULL);
SCNetworkReachabilitySetDispatchQueue(reachability, NULL);
}];
{
[timer invalidate];
SCNetworkReachabilitySetCallback(reachability, NULL, NULL);
SCNetworkReachabilitySetDispatchQueue(reachability, NULL);
}];
}
+ (MTQueue *)networkAvailabilityQueue
@@ -116,57 +120,58 @@ static void MTNetworkAvailabilityContextRelease(const void *info)
static MTQueue *queue = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
{
queue = [[MTQueue alloc] initWithName:"org.mtproto.MTNetwotkAvailability"];
});
{
queue = [[MTQueue alloc] initWithName:"org.mtproto.MTNetwotkAvailability"];
});
return queue;
}
- (void)updateFlags:(bool)notify
{
[[MTNetworkAvailability networkAvailabilityQueue] dispatchOnQueue:^
{
if (_reachability != nil)
{
SCNetworkReachabilityFlags currentFlags = 0;
if (SCNetworkReachabilityGetFlags(_reachability, &currentFlags))
[self updateReachability:currentFlags notify:notify];
}
}];
{
if (_reachability != nil)
{
SCNetworkReachabilityFlags currentFlags = 0;
if (SCNetworkReachabilityGetFlags(_reachability, &currentFlags))
[self updateReachability:currentFlags notify:notify];
}
}];
}
- (void)updateReachability:(SCNetworkReachabilityFlags)flags notify:(bool)notify
{
[[MTNetworkAvailability networkAvailabilityQueue] dispatchOnQueue:^
{
BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0);
BOOL needsConnection = ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0);
BOOL canConnectionAutomatically = (((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
((flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0));
BOOL canConnectWithoutUserInteraction = (canConnectionAutomatically &&
(flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0);
BOOL isNetworkReachable = (isReachable && (!needsConnection || canConnectWithoutUserInteraction));
bool isWWAN = false;
{
BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0);
BOOL needsConnection = ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0);
BOOL canConnectionAutomatically = (((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
((flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0));
BOOL canConnectWithoutUserInteraction = (canConnectionAutomatically &&
(flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0);
BOOL isNetworkReachable = (isReachable && (!needsConnection || canConnectWithoutUserInteraction));
bool isWWAN = false;
#if TARGET_OS_IPHONE
isWWAN = (flags & kSCNetworkReachabilityFlagsIsWWAN);
isWWAN = (flags & kSCNetworkReachabilityFlagsIsWWAN);
#endif
NSString *currentReachabilityState = [[NSString alloc] initWithFormat:@"%s_%s_%s", isWWAN ? "M" : "L", canConnectWithoutUserInteraction ? "+U" : "-U", isNetworkReachable ? "+" : "-"];
if (![currentReachabilityState isEqualToString:_lastReachabilityState])
{
_lastReachabilityState = currentReachabilityState;
if (MTLogEnabled()) {
MTLog(@"[MTNetworkAvailability#%p state: %@]", self, _lastReachabilityState);
}
if (notify)
{
id<MTNetworkAvailabilityDelegate> delegate = _delegate;
if ([delegate respondsToSelector:@selector(networkAvailabilityChanged:networkIsAvailable:)])
[delegate networkAvailabilityChanged:self networkIsAvailable:isNetworkReachable];
}
}
}];
NSString *currentReachabilityState = [[NSString alloc] initWithFormat:@"%s_%s_%s", isWWAN ? "M" : "L", canConnectWithoutUserInteraction ? "+U" : "-U", isNetworkReachable ? "+" : "-"];
if (![currentReachabilityState isEqualToString:_lastReachabilityState])
{
_lastReachabilityState = currentReachabilityState;
if (MTLogEnabled()) {
MTLog(@"[MTNetworkAvailability#%p state: %@]", self, _lastReachabilityState);
}
if (notify)
{
id<MTNetworkAvailabilityDelegate> delegate = _delegate;
if ([delegate respondsToSelector:@selector(networkAvailabilityChanged:networkIsAvailable:)])
[delegate networkAvailabilityChanged:self networkIsAvailable:isNetworkReachable];
}
}
}];
}
@end