iOS 网络状态

Reachability.h

 1 /*
 2  
 3  File: Reachability.h
 4  Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs.
 5  
 6  Version: 2.2
 7  
 8  Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple Inc.
 9  ("Apple") in consideration of your agreement to the following terms, and your
10  use, installation, modification or redistribution of this Apple software
11  constitutes acceptance of these terms.  If you do not agree with these terms,
12  please do not use, install, modify or redistribute this Apple software.
13  
14  In consideration of your agreement to abide by the following terms, and subject
15  to these terms, Apple grants you a personal, non-exclusive license, under
16  Apple's copyrights in this original Apple software (the "Apple Software"), to
17  use, reproduce, modify and redistribute the Apple Software, with or without
18  modifications, in source and/or binary forms; provided that if you redistribute
19  the Apple Software in its entirety and without modifications, you must retain
20  this notice and the following text and disclaimers in all such redistributions
21  of the Apple Software.
22  Neither the name, trademarks, service marks or logos of Apple Inc. may be used
23  to endorse or promote products derived from the Apple Software without specific
24  prior written permission from Apple.  Except as expressly stated in this notice,
25  no other rights or licenses, express or implied, are granted by Apple herein,
26  including but not limited to any patent rights that may be infringed by your
27  derivative works or by other works in which the Apple Software may be
28  incorporated.
29  
30  The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
31  WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
32  WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
33  PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
34  COMBINATION WITH YOUR PRODUCTS.
35  
36  IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
37  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
38  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
40  DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
41  CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
42  APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43  
44  Copyright (C) 2010 Apple Inc. All Rights Reserved.
45  
46 */
47 
48 
49 #import <Foundation/Foundation.h>
50 #import <SystemConfiguration/SystemConfiguration.h>
51 
52 typedef enum {
53     NotReachable = 0,
54     ReachableViaWiFi,
55     ReachableViaWWAN
56 } NetworkStatus;
57 #define kReachabilityChangedNotification @"kNetworkReachabilityChangedNotification"
58 
59 @interface Reachability: NSObject
60 {
61     BOOL localWiFiRef;
62     SCNetworkReachabilityRef reachabilityRef;
63 }
64 
65 //reachabilityWithHostName- Use to check the reachability of a particular host name. 
66 + (Reachability*) reachabilityWithHostName: (NSString*) hostName;
67 
68 //reachabilityWithAddress- Use to check the reachability of a particular IP address. 
69 + (Reachability*) reachabilityWithAddress: (const struct sockaddr_in*) hostAddress;
70 
71 //reachabilityForInternetConnection- checks whether the default route is available.  
72 //  Should be used by applications that do not connect to a particular host
73 + (Reachability*) reachabilityForInternetConnection;
74 
75 //reachabilityForLocalWiFi- checks whether a local wifi connection is available.
76 + (Reachability*) reachabilityForLocalWiFi;
77 
78 //Start listening for reachability notifications on the current run loop
79 - (BOOL) startNotifier;
80 - (void) stopNotifier;
81 
82 - (NetworkStatus) currentReachabilityStatus;
83 //WWAN may be available, but not active until a connection has been established.
84 //WiFi may require a connection for VPN on Demand.
85 - (BOOL) connectionRequired;
86 @end
View Code

Reachability.m

  1 /*
  2  
  3  File: Reachability.m
  4  Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs.
  5  
  6  Version: 2.2
  7  
  8  Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple Inc.
  9  ("Apple") in consideration of your agreement to the following terms, and your
 10  use, installation, modification or redistribution of this Apple software
 11  constitutes acceptance of these terms.  If you do not agree with these terms,
 12  please do not use, install, modify or redistribute this Apple software.
 13  
 14  In consideration of your agreement to abide by the following terms, and subject
 15  to these terms, Apple grants you a personal, non-exclusive license, under
 16  Apple's copyrights in this original Apple software (the "Apple Software"), to
 17  use, reproduce, modify and redistribute the Apple Software, with or without
 18  modifications, in source and/or binary forms; provided that if you redistribute
 19  the Apple Software in its entirety and without modifications, you must retain
 20  this notice and the following text and disclaimers in all such redistributions
 21  of the Apple Software.
 22  Neither the name, trademarks, service marks or logos of Apple Inc. may be used
 23  to endorse or promote products derived from the Apple Software without specific
 24  prior written permission from Apple.  Except as expressly stated in this notice,
 25  no other rights or licenses, express or implied, are granted by Apple herein,
 26  including but not limited to any patent rights that may be infringed by your
 27  derivative works or by other works in which the Apple Software may be
 28  incorporated.
 29  
 30  The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
 31  WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
 32  WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 33  PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
 34  COMBINATION WITH YOUR PRODUCTS.
 35  
 36  IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
 37  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 38  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 39  ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
 40  DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
 41  CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
 42  APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 43  
 44  Copyright (C) 2010 Apple Inc. All Rights Reserved.
 45  
 46 */
 47 
 48 #import <sys/socket.h>
 49 #import <netinet/in.h>
 50 #import <netinet6/in6.h>
 51 #import <arpa/inet.h>
 52 #import <ifaddrs.h>
 53 #import <netdb.h>
 54 
 55 #import <CoreFoundation/CoreFoundation.h>
 56 
 57 #import "Reachability.h"
 58 
 59 #define kShouldPrintReachabilityFlags 1
 60 
 61 static void PrintReachabilityFlags(SCNetworkReachabilityFlags    flags, const char* comment)
 62 {
 63 #if kShouldPrintReachabilityFlags
 64     
 65     NSLog(@"Reachability Flag Status: %c%c %c%c%c%c%c%c%c %s\n",
 66             (flags & kSCNetworkReachabilityFlagsIsWWAN)                  ? 'W' : '-',
 67             (flags & kSCNetworkReachabilityFlagsReachable)            ? 'R' : '-',
 68             
 69             (flags & kSCNetworkReachabilityFlagsTransientConnection)  ? 't' : '-',
 70             (flags & kSCNetworkReachabilityFlagsConnectionRequired)   ? 'c' : '-',
 71             (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic)  ? 'C' : '-',
 72             (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
 73             (flags & kSCNetworkReachabilityFlagsConnectionOnDemand)   ? 'D' : '-',
 74             (flags & kSCNetworkReachabilityFlagsIsLocalAddress)       ? 'l' : '-',
 75             (flags & kSCNetworkReachabilityFlagsIsDirect)             ? 'd' : '-',
 76             comment
 77             );
 78 #endif
 79 }
 80 
 81 
 82 @implementation Reachability
 83 static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, id info)
 84 {
 85     #pragma unused (target, flags)
 86     NSCAssert(info != NULL, @"info was NULL in ReachabilityCallback");
 87     NSCAssert([(NSObject*) info isKindOfClass: [Reachability class]], @"info was wrong class in ReachabilityCallback");
 88 
 89     //We're on the main RunLoop, so an NSAutoreleasePool is not necessary, but is added defensively
 90     // in case someon uses the Reachablity object in a different thread.
 91     
 92     Reachability* noteObject = (Reachability*) info;
 93     // Post a notification to notify the client that the network reachability changed.
 94     [[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification object: noteObject];
 95     
 96 }
 97 
 98 - (BOOL) startNotifier
 99 {
100     BOOL retVal = NO;
101     SCNetworkReachabilityContext context = {0, (__bridge void *)(self), NULL, NULL, NULL};
102     if(SCNetworkReachabilitySetCallback(reachabilityRef, ReachabilityCallback, &context))
103     {
104         if(SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode))
105         {
106             retVal = YES;
107         }
108     }
109     return retVal;
110 }
111 
112 - (void) stopNotifier
113 {
114     if(reachabilityRef!= NULL)
115     {
116         SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
117     }
118 }
119 
120 
121 + (Reachability*) reachabilityWithHostName: (NSString*) hostName;
122 {
123     Reachability* retVal = NULL;
124     SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
125     if(reachability!= NULL)
126     {
127         retVal= [[self alloc] init];
128         if(retVal!= NULL)
129         {
130             retVal->reachabilityRef = reachability;
131             retVal->localWiFiRef = NO;
132         }
133     }
134     return retVal;
135 }
136 
137 + (Reachability*) reachabilityWithAddress: (const struct sockaddr_in*) hostAddress;
138 {
139     SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress);
140     Reachability* retVal = NULL;
141     if(reachability!= NULL)
142     {
143         retVal= [[self alloc] init];
144         if(retVal!= NULL)
145         {
146             retVal->reachabilityRef = reachability;
147             retVal->localWiFiRef = NO;
148         }
149     }
150     return retVal;
151 }
152 
153 + (Reachability*) reachabilityForInternetConnection;
154 {
155     struct sockaddr_in zeroAddress;
156     bzero(&zeroAddress, sizeof(zeroAddress));
157     zeroAddress.sin_len = sizeof(zeroAddress);
158     zeroAddress.sin_family = AF_INET;
159     return [self reachabilityWithAddress: &zeroAddress];
160 }
161 
162 + (Reachability*) reachabilityForLocalWiFi;
163 {
164     struct sockaddr_in localWifiAddress;
165     bzero(&localWifiAddress, sizeof(localWifiAddress));
166     localWifiAddress.sin_len = sizeof(localWifiAddress);
167     localWifiAddress.sin_family = AF_INET;
168     // IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0
169     localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
170     Reachability* retVal = [self reachabilityWithAddress: &localWifiAddress];
171     if(retVal!= NULL)
172     {
173         retVal->localWiFiRef = YES;
174     }
175     return retVal;
176 }
177 
178 #pragma mark Network Flag Handling
179 
180 - (NetworkStatus) localWiFiStatusForFlags: (SCNetworkReachabilityFlags) flags
181 {
182     PrintReachabilityFlags(flags, "localWiFiStatusForFlags");
183 
184     BOOL retVal = NotReachable;
185     if((flags & kSCNetworkReachabilityFlagsReachable) && (flags & kSCNetworkReachabilityFlagsIsDirect))
186     {
187         retVal = ReachableViaWiFi;    
188     }
189     return retVal;
190 }
191 
192 - (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags
193 {
194     PrintReachabilityFlags(flags, "networkStatusForFlags");
195     if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
196     {
197         // if target host is not reachable
198         return NotReachable;
199     }
200 
201     BOOL retVal = NotReachable;
202     
203     if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
204     {
205         // if target host is reachable and no connection is required
206         //  then we'll assume (for now) that your on Wi-Fi
207         retVal = ReachableViaWiFi;
208     }
209     
210     
211     if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
212         (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
213     {
214             // ... and the connection is on-demand (or on-traffic) if the
215             //     calling application is using the CFSocketStream or higher APIs
216 
217             if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
218             {
219                 // ... and no [user] intervention is needed
220                 retVal = ReachableViaWiFi;
221             }
222         }
223     
224     if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
225     {
226         // ... but WWAN connections are OK if the calling application
227         //     is using the CFNetwork (CFSocketStream?) APIs.
228         retVal = ReachableViaWWAN;
229     }
230     return retVal;
231 }
232 
233 - (BOOL) connectionRequired;
234 {
235     NSAssert(reachabilityRef != NULL, @"connectionRequired called with NULL reachabilityRef");
236     SCNetworkReachabilityFlags flags;
237     if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
238     {
239         return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
240     }
241     return NO;
242 }
243 
244 - (NetworkStatus) currentReachabilityStatus
245 {
246     NSAssert(reachabilityRef != NULL, @"currentNetworkStatus called with NULL reachabilityRef");
247     NetworkStatus retVal = NotReachable;
248     SCNetworkReachabilityFlags flags;
249     if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
250     {
251         if(localWiFiRef)
252         {
253             retVal = [self localWiFiStatusForFlags: flags];
254         }
255         else
256         {
257             retVal = [self networkStatusForFlags: flags];
258         }
259     }
260     return retVal;
261 }
262 @end
View Code

将Reachability.h 和 Reachability.m 加到自己的项目中,并引用 SystemConfiguration.framework。

 1 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
 2 {
 3     
 4     self.helper = [Helper Instance];
 5     
 6     //开启网络状况的监听
 7     [[NSNotificationCenter defaultCenter] addObserver:self
 8                                              selector:@selector(reachabilityChanged:)
 9                                                  name: kReachabilityChangedNotification
10                                                object: nil];
11     curReach = [Reachability reachabilityForInternetConnection];
12 
13     switch ([curReach currentReachabilityStatus])
14     {
15         case NotReachable://没有网络
16         {
17             UIAlertView * av_error = [[UIAlertView alloc] initWithTitle:@"Title" message:@"无网络连接\n无法加载数据" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
18             [av_error show];
19             break;
20         }
21         case ReachableViaWiFi://有wifi
22         case ReachableViaWWAN://有3G
23         {
24         }
25         default:
26             break;
27     }
28 
29     [curReach startNotifier]; 
30     [self updateInterfaceWithReachability: curReach];
31     
32     
33     return YES;
34 }
35 
36 // 连接改变
37 - (void) reachabilityChanged: (NSNotification* )note
38 {
39     Reachability* curReach = [note object];
40     NSParameterAssert([curReach isKindOfClass: [Reachability class]]);
41     [self updateInterfaceWithReachability: curReach];
42 }
43 
44 //处理连接改变后的情况
45 - (void) updateInterfaceWithReachability: (Reachability*) curReach
46 {
47     //对连接改变做出响应的处理动作。
48     NetworkStatus status = [curReach currentReachabilityStatus];
49     
50     if (status == NotReachable)
51     {
52         ;//do something
53     }
54     else
55     {
56         ;//do otherthing
57     }
58 }

 

posted on 2013-07-11 13:19  许木木  阅读(207)  评论(0编辑  收藏  举报

导航