一: .h文件 #import <Foundation/Foundation.h>@interface HttpHelper : NSObject+ (BOOL)NetWorkIsOK;//检查网络是
一:
.h文件
#import <Foundation/Foundation.h>@interface HttpHelper : NSObject+ (BOOL)NetWorkIsOK;//检查网络是否可用+ (void)post:(NSString *)Url RequestParams:(NSDictionary *)params FinishBlock:(void (^)(NSURLResponse *response, NSData *data, NSError *connectionError)) block;//post请求封装@end
.m文件
#import "HttpHelper.h"#import "Reachability.h"@implementation HttpHelper//这个函数是判断网络是否可用的函数(wifi或者蜂窝数据可用,都返回YES)+ (BOOL)NetWorkIsOK{ if( ([[Reachability reachabilityForInternetConnection] currentReachabilityStatus] != NotReachable) && ([[Reachability reachabilityForLocalWiFi] currentReachabilityStatus] != NotReachable) ){ return YES; }else{ return NO; }// return YES;}//post异步请求封装函数+ (void)post:(NSString *)URL RequestParams:(NSDictionary *)params FinishBlock:(void (^)(NSURLResponse *response, NSData *data, NSError *connectionError)) block{ //把传进来的URL字符串转变为URL地址 NSURL *url = [NSURL URLWithString:URL]; //请求初始化,可以在这针对缓存,超时做出一些设置 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:20]; //解析请求参数,用NSDictionary来存参数,通过自定义的函数parseParams把它解析成一个post格式的字符串 NSString *parseParamsResult = [self parseParams:params]; NSData *postData = [parseParamsResult dataUsingEncoding:NSUTF8StringEncoding]; [request setHTTPMethod:@"POST"]; [request setHTTPBody:postData]; //创建一个新的队列(开启新线程) NSOperationQueue *queue = [NSOperationQueue new]; //发送异步请求,请求完以后返回的数据,通过completionHandler参数来调用 [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:block]; // return result;}//把NSDictionary解析成post格式的NSString字符串+ (NSString *)parseParams:(NSDictionary *)params{ NSString *keyValueFormat; NSMutableString *result = [NSMutableString new]; //实例化一个key枚举器用来存放dictionary的key NSEnumerator *keyEnum = [params keyEnumerator]; id key; while (key = [keyEnum nextObject]) { keyValueFormat = [NSString stringWithFormat:@"%@=%@&",key,[params valueForKey:key]]; [result appendString:keyValueFormat];// NSLog(@"post()方法参数解析结果:%@",result); } return result;}@end
二:引入文件
Reachability.h
#import <Foundation/Foundation.h>#import <SystemConfiguration/SystemConfiguration.h>#import <netinet/in.h>/** * Create NS_ENUM macro if it does not exist on the targeted version of iOS or OS X. * * @see http://nshipster.com/ns_enum-ns_options/ **/#ifndef NS_ENUM#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type#endifextern NSString *const kReachabilityChangedNotification;// 定义网络请求可到达状态typedef NS_ENUM(NSInteger, NetworkStatus) { // Apple NetworkStatus Compatible Names. NotReachable = 0,// 不可到达 ReachableViaWiFi = 2,// 通过WiFi可到达 ReachableViaWWAN = 1 // 通过无线广域网可到达(WWAN,即Wireless Wide Area Network,无线广域网。)};@class Reachability;typedef void (^NetworkReachable)(Reachability * reachability);typedef void (^NetworkUnreachable)(Reachability * reachability);@interface Reachability : NSObject@property (nonatomic, copy) NetworkReachable reachableBlock;@property (nonatomic, copy) NetworkUnreachable unreachableBlock;@property (nonatomic, assign) BOOL reachableOnWWAN;// 用于检查网络请求是否可到达指定的主机名+(instancetype)reachabilityWithHostname:(NSString*)hostname;// This is identical to the function above, but is here to maintain//compatibility with Apples original code. (see .m)+(instancetype)reachabilityWithHostName:(NSString*)hostname;// 用于检查路由连接是否有效+(instancetype)reachabilityForInternetConnection;// 用于检查网络请求是否可到达指定的IP地址+(instancetype)reachabilityWithAddress:(void *)hostAddress;// 用于检查本地的WiFi连接是否有效+(instancetype)reachabilityForLocalWiFi;-(instancetype)initWithReachabilityRef:(SCNetworkReachabilityRef)ref;-(BOOL)startNotifier;-(void)stopNotifier;-(BOOL)isReachable;-(BOOL)isReachableViaWWAN;-(BOOL)isReachableViaWiFi;// WWAN may be available, but not active until a connection has been established.// WiFi may require a connection for VPN on Demand.-(BOOL)isConnectionRequired; // Identical DDG variant.// 连接需求-(BOOL)connectionRequired; // Apple's routine.// Dynamic, on demand connection?-(BOOL)isConnectionOnDemand;// Is user intervention required?-(BOOL)isInterventionRequired;// 当前网络请求可到达状态-(NetworkStatus)currentReachabilityStatus;-(SCNetworkReachabilityFlags)reachabilityFlags;-(NSString*)currentReachabilityString;-(NSString*)currentReachabilityFlags;@end
Reachability.m
#import "Reachability.h"#import <sys/socket.h>#import <netinet/in.h>#import <netinet6/in6.h>#import <arpa/inet.h>#import <ifaddrs.h>#import <netdb.h>NSString *const kReachabilityChangedNotification = @"kReachabilityChangedNotification";@interface Reachability ()@property (nonatomic, assign) SCNetworkReachabilityRef reachabilityRef;@property (nonatomic, strong) dispatch_queue_t reachabilitySerialQueue;@property (nonatomic, strong) id reachabilityObject;-(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags;-(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags;@endstatic NSString *reachabilityFlags(SCNetworkReachabilityFlags flags) { return [NSString stringWithFormat:@"%c%c %c%c%c%c%c%c%c",#if TARGET_OS_IPHONE (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-',#else 'X',#endif (flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-', (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-', (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-', (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-', (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-', (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-', (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-', (flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-'];}// Start listening for reachability notifications on the current run loopstatic void TMReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info) {#pragma unused (target) Reachability *reachability = ((__bridge Reachability*)info); // We probably don't need an autoreleasepool here, as GCD docs state each queue has its own autorelease pool, // but what the heck eh? @autoreleasepool { [reachability reachabilityChanged:flags]; }}@implementation Reachability#pragma mark - Class Constructor Methods+(instancetype)reachabilityWithHostName:(NSString*)hostname{ return [Reachability reachabilityWithHostname:hostname];}+(instancetype)reachabilityWithHostname:(NSString*)hostname{ SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostname UTF8String]); if (ref) { id reachability = [[self alloc] initWithReachabilityRef:ref]; return reachability; } return nil;}+(instancetype)reachabilityWithAddress:(void *)hostAddress{ SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress); if (ref) { id reachability = [[self alloc] initWithReachabilityRef:ref]; return reachability; } return nil;}+(instancetype)reachabilityForInternetConnection{ struct sockaddr_in zeroAddress; bzero(&zeroAddress, sizeof(zeroAddress)); zeroAddress.sin_len = sizeof(zeroAddress); zeroAddress.sin_family = AF_INET; return [self reachabilityWithAddress:&zeroAddress];}+(instancetype)reachabilityForLocalWiFi{ struct sockaddr_in localWifiAddress; bzero(&localWifiAddress, sizeof(localWifiAddress)); localWifiAddress.sin_len = sizeof(localWifiAddress); localWifiAddress.sin_family = AF_INET; // IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0 localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM); return [self reachabilityWithAddress:&localWifiAddress];}// Initialization methods-(instancetype)initWithReachabilityRef:(SCNetworkReachabilityRef)ref{ self = [super init]; if (self != nil) { self.reachableOnWWAN = YES; self.reachabilityRef = ref; // We need to create a serial queue. // We allocate this once for the lifetime of the notifier. self.reachabilitySerialQueue = dispatch_queue_create("com.tonymillion.reachability", NULL); } return self; }-(void)dealloc{ [self stopNotifier]; if(self.reachabilityRef) { CFRelease(self.reachabilityRef); self.reachabilityRef = nil; } self.reachableBlock = nil; self.unreachableBlock = nil; self.reachabilitySerialQueue = nil;}#pragma mark - Notifier Methods// Notifier // NOTE: This uses GCD to trigger the blocks - they *WILL NOT* be called on THE MAIN THREAD// - In other words DO NOT DO ANY UI UPDATES IN THE BLOCKS.// INSTEAD USE dispatch_async(dispatch_get_main_queue(), ^{UISTUFF}) (or dispatch_sync if you want)-(BOOL)startNotifier{ // allow start notifier to be called multiple times if(self.reachabilityObject && (self.reachabilityObject == self)) { return YES; } SCNetworkReachabilityContext context = { 0, NULL, NULL, NULL, NULL }; context.info = (__bridge void *)self; if(SCNetworkReachabilitySetCallback(self.reachabilityRef, TMReachabilityCallback, &context)) { // Set it as our reachability queue, which will retain the queue if(SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, self.reachabilitySerialQueue)) { // this should do a retain on ourself, so as long as we're in notifier mode we shouldn't disappear out from under ourselves // woah self.reachabilityObject = self; return YES; } else {#ifdef DEBUG NSLog(@"SCNetworkReachabilitySetDispatchQueue() failed: %s", SCErrorString(SCError()));#endif // UH OH - FAILURE - stop any callbacks! SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL); } } else {#ifdef DEBUG NSLog(@"SCNetworkReachabilitySetCallback() failed: %s", SCErrorString(SCError()));#endif } // if we get here we fail at the internet self.reachabilityObject = nil; return NO;}-(void)stopNotifier{ // First stop, any callbacks! SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL); // Unregister target from the GCD serial dispatch queue. SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, NULL); self.reachabilityObject = nil;}#pragma mark - reachability tests// This is for the case where you flick the airplane mode;// you end up getting something like this://Reachability: WR ct-----//Reachability: -- -------//Reachability: WR ct-----//Reachability: -- -------// We treat this as 4 UNREACHABLE triggers - really apple should do better than this#define testcase (kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection)-(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags{ BOOL connectionUP = YES; if(!(flags & kSCNetworkReachabilityFlagsReachable)) connectionUP = NO; if( (flags & testcase) == testcase ) connectionUP = NO; #if TARGET_OS_IPHONE if(flags & kSCNetworkReachabilityFlagsIsWWAN) { // We're on 3G. if(!self.reachableOnWWAN) { // We don't want to connect when on 3G. connectionUP = NO; } }#endif return connectionUP;}-(BOOL)isReachable{ SCNetworkReachabilityFlags flags; if(!SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) return NO; return [self isReachableWithFlags:flags];}-(BOOL)isReachableViaWWAN {#if TARGET_OS_IPHONE SCNetworkReachabilityFlags flags = 0; if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) { // Check we're REACHABLE if(flags & kSCNetworkReachabilityFlagsReachable) { // Now, check we're on WWAN if(flags & kSCNetworkReachabilityFlagsIsWWAN) { return YES; } } }#endif return NO;}-(BOOL)isReachableViaWiFi { SCNetworkReachabilityFlags flags = 0; if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) { // Check we're reachable if((flags & kSCNetworkReachabilityFlagsReachable)) {#if TARGET_OS_IPHONE // Check we're NOT on WWAN if((flags & kSCNetworkReachabilityFlagsIsWWAN)) { return NO; }#endif return YES; } } return NO;}// WWAN may be available, but not active until a connection has been established.// WiFi may require a connection for VPN on Demand.-(BOOL)isConnectionRequired{ return [self connectionRequired];}-(BOOL)connectionRequired{ SCNetworkReachabilityFlags flags; if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) { return (flags & kSCNetworkReachabilityFlagsConnectionRequired); } return NO;}// Dynamic, on demand connection?-(BOOL)isConnectionOnDemand{ SCNetworkReachabilityFlags flags; if (SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) { return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) && (flags & (kSCNetworkReachabilityFlagsConnectionOnTraffic | kSCNetworkReachabilityFlagsConnectionOnDemand))); } return NO;}// Is user intervention required?-(BOOL)isInterventionRequired{ SCNetworkReachabilityFlags flags; if (SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) { return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) && (flags & kSCNetworkReachabilityFlagsInterventionRequired)); } return NO;}#pragma mark - reachability status stuff-(NetworkStatus)currentReachabilityStatus{ if([self isReachable]) { if([self isReachableViaWiFi]) return ReachableViaWiFi; #if TARGET_OS_IPHONE return ReachableViaWWAN;#endif } return NotReachable;}-(SCNetworkReachabilityFlags)reachabilityFlags{ SCNetworkReachabilityFlags flags = 0; if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) { return flags; } return 0;}-(NSString*)currentReachabilityString{ NetworkStatus temp = [self currentReachabilityStatus]; if(temp == ReachableViaWWAN) { // Updated for the fact that we have CDMA phones now! return NSLocalizedString(@"Cellular", @""); } if (temp == ReachableViaWiFi) { return NSLocalizedString(@"WiFi", @""); } return NSLocalizedString(@"No Connection", @"");}-(NSString*)currentReachabilityFlags{ return reachabilityFlags([self reachabilityFlags]);}#pragma mark - Callback function calls this method-(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags{ if([self isReachableWithFlags:flags]) { if(self.reachableBlock) { self.reachableBlock(self); } } else { if(self.unreachableBlock) { self.unreachableBlock(self); } } // this makes sure the change notification happens on the MAIN THREAD dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:kReachabilityChangedNotification object:self]; });}#pragma mark - Debug Description- (NSString *) description{ NSString *description = [NSString stringWithFormat:@"<%@: %#x (%@)>", NSStringFromClass([self class]), (unsigned int) self, [self currentReachabilityFlags]]; return description;}@end