抓娃娃版1127

Reachability.m 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /*
  2. Copyright (C) 2016 Apple Inc. All Rights Reserved.
  3. See LICENSE.txt for this sample’s licensing information
  4. Abstract:
  5. Basic demonstration of how to use the SystemConfiguration Reachablity APIs.
  6. */
  7. #import <arpa/inet.h>
  8. #import <ifaddrs.h>
  9. #import <netdb.h>
  10. #import <sys/socket.h>
  11. #import <netinet/in.h>
  12. #import <CoreFoundation/CoreFoundation.h>
  13. #import "Reachability.h"
  14. #import <CoreTelephony/CTTelephonyNetworkInfo.h>
  15. #import <UIKit/UIKit.h>
  16. #pragma mark IPv6 Support
  17. //Reachability fully support IPv6. For full details, see ReadMe.md.
  18. NSString *kReachabilityChangedNotification = @"kNetworkReachabilityChangedNotification";
  19. #pragma mark - Supporting functions
  20. #define kShouldPrintReachabilityFlags 1
  21. static void PrintReachabilityFlags(SCNetworkReachabilityFlags flags, const char* comment)
  22. {
  23. #if kShouldPrintReachabilityFlags
  24. // NSLog(@"Reachability Flag Status: %c%c %c%c%c%c%c%c%c %s\n",
  25. // (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-',
  26. // (flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-',
  27. //
  28. // (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-',
  29. // (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-',
  30. // (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-',
  31. // (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
  32. // (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-',
  33. // (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-',
  34. // (flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-',
  35. // comment
  36. // );
  37. #endif
  38. }
  39. static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)
  40. {
  41. #pragma unused (target, flags)
  42. NSCAssert(info != NULL, @"info was NULL in ReachabilityCallback");
  43. NSCAssert([(__bridge NSObject*) info isKindOfClass: [Reachability class]], @"info was wrong class in ReachabilityCallback");
  44. Reachability* noteObject = (__bridge Reachability *)info;
  45. // Post a notification to notify the client that the network reachability changed.
  46. [[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification object: noteObject];
  47. }
  48. #pragma mark - Reachability implementation
  49. @implementation Reachability
  50. {
  51. SCNetworkReachabilityRef _reachabilityRef;
  52. }
  53. + (instancetype)reachabilityWithHostName:(NSString *)hostName
  54. {
  55. Reachability* returnValue = NULL;
  56. SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
  57. if (reachability != NULL)
  58. {
  59. returnValue= [[self alloc] init];
  60. if (returnValue != NULL)
  61. {
  62. returnValue->_reachabilityRef = reachability;
  63. }
  64. else {
  65. CFRelease(reachability);
  66. }
  67. }
  68. return returnValue;
  69. }
  70. + (instancetype)reachabilityWithAddress:(const struct sockaddr *)hostAddress
  71. {
  72. SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, hostAddress);
  73. Reachability* returnValue = NULL;
  74. if (reachability != NULL)
  75. {
  76. returnValue = [[self alloc] init];
  77. if (returnValue != NULL)
  78. {
  79. returnValue->_reachabilityRef = reachability;
  80. }
  81. else {
  82. CFRelease(reachability);
  83. }
  84. }
  85. return returnValue;
  86. }
  87. + (instancetype)reachabilityForInternetConnection
  88. {
  89. struct sockaddr_in zeroAddress;
  90. bzero(&zeroAddress, sizeof(zeroAddress));
  91. zeroAddress.sin_len = sizeof(zeroAddress);
  92. zeroAddress.sin_family = AF_INET;
  93. return [self reachabilityWithAddress: (const struct sockaddr *) &zeroAddress];
  94. }
  95. #pragma mark reachabilityForLocalWiFi
  96. //reachabilityForLocalWiFi has been removed from the sample. See ReadMe.md for more information.
  97. //+ (instancetype)reachabilityForLocalWiFi
  98. #pragma mark - Start and stop notifier
  99. - (BOOL)startNotifier
  100. {
  101. BOOL returnValue = NO;
  102. SCNetworkReachabilityContext context = {0, (__bridge void *)(self), NULL, NULL, NULL};
  103. if (SCNetworkReachabilitySetCallback(_reachabilityRef, ReachabilityCallback, &context))
  104. {
  105. if (SCNetworkReachabilityScheduleWithRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode))
  106. {
  107. returnValue = YES;
  108. }
  109. }
  110. return returnValue;
  111. }
  112. - (void)stopNotifier
  113. {
  114. if (_reachabilityRef != NULL)
  115. {
  116. SCNetworkReachabilityUnscheduleFromRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
  117. }
  118. }
  119. - (void)dealloc
  120. {
  121. [self stopNotifier];
  122. if (_reachabilityRef != NULL)
  123. {
  124. CFRelease(_reachabilityRef);
  125. }
  126. }
  127. #pragma mark - Network Flag Handling
  128. - (NetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags
  129. {
  130. PrintReachabilityFlags(flags, "networkStatusForFlags");
  131. if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
  132. {
  133. // The target host is not reachable.
  134. return NotReachable;
  135. }
  136. NetworkStatus returnValue = NotReachable;
  137. if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
  138. {
  139. /*
  140. If the target host is reachable and no connection is required then we'll assume (for now) that you're on Wi-Fi...
  141. */
  142. returnValue = ReachableViaWiFi;
  143. }
  144. if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
  145. (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
  146. {
  147. /*
  148. ... and the connection is on-demand (or on-traffic) if the calling application is using the CFSocketStream or higher APIs...
  149. */
  150. if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
  151. {
  152. /*
  153. ... and no [user] intervention is needed...
  154. */
  155. returnValue = ReachableViaWiFi;
  156. }
  157. }
  158. if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
  159. {
  160. /*
  161. ... but WWAN connections are OK if the calling application is using the CFNetwork APIs.
  162. */
  163. returnValue = ReachableViaWWAN;
  164. float IOS_VERSION=[[[UIDevice currentDevice] systemVersion] floatValue];
  165. NSLog(@"版本号:%lf",IOS_VERSION);
  166. if (IOS_VERSION >= 7.0) {
  167. CTTelephonyNetworkInfo *phonyNetwork = [[CTTelephonyNetworkInfo alloc] init];
  168. NSString *currentStr = phonyNetwork.currentRadioAccessTechnology;
  169. if (currentStr) {
  170. if ([currentStr isEqualToString:CTRadioAccessTechnologyLTE]) {
  171. return kRaeachableVia4G;
  172. }else if ([currentStr isEqualToString:CTRadioAccessTechnologyGPRS]|| [currentStr isEqualToString:CTRadioAccessTechnologyEdge]){
  173. return kReachableVia2G;
  174. }else{
  175. return kReachableVia3G;
  176. }
  177. }
  178. }
  179. if ((flags & kSCNetworkReachabilityFlagsTransientConnection) == kSCNetworkReachabilityFlagsTransientConnection) {
  180. if((flags & kSCNetworkReachabilityFlagsConnectionRequired) == kSCNetworkReachabilityFlagsConnectionRequired) {
  181. return kReachableVia2G;
  182. }
  183. return kReachableVia3G;
  184. }
  185. return ReachableViaWWAN;
  186. }
  187. return returnValue;
  188. }
  189. - (BOOL)connectionRequired
  190. {
  191. NSAssert(_reachabilityRef != NULL, @"connectionRequired called with NULL reachabilityRef");
  192. SCNetworkReachabilityFlags flags;
  193. if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags))
  194. {
  195. return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
  196. }
  197. return NO;
  198. }
  199. - (NetworkStatus)currentReachabilityStatus
  200. {
  201. NSAssert(_reachabilityRef != NULL, @"currentNetworkStatus called with NULL SCNetworkReachabilityRef");
  202. NetworkStatus returnValue = NotReachable;
  203. SCNetworkReachabilityFlags flags;
  204. if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags))
  205. {
  206. returnValue = [self networkStatusForFlags:flags];
  207. }
  208. return returnValue;
  209. }
  210. @end