1.iOS平台是按照一直有网络连接的思路来设计的,开发者利用这一特点创造了很多优秀的第三方应用。

大多数的iOS应用都需要联网,甚至有些应用严重依赖网络,没有网络就无法正常工作。

2.在你的应用尝试通过网络获取数据之前,你需要知道当前设备是否知道连接上了网络,

甚至有时候你可能还需要知道当前网路是由wifi还是由移动蜂窝网络提供的。

3.“在网络访问失败的时候,应用没有做出适当的提示”是苹果的iOS审核团队拒绝一个应用的常见理由。

苹果要求你必须先检测网络连接状态,当网络不可用的时候以某种方式告知用户,或者用其他优雅的方式进行处理。

***********************

Reachability类:

1.这个类用于检测当前网络状态,它不是SDK的一部分,可以在iOS Developer Library里找到这份代码。

从苹果网站上下载Reachability.zip文件,解压之。

2.重用Reachability类

    (1)把Reachability.h和Reachability.m文件拖到项目中。

(2)添加框架:SystemConfiguration.framework。

3.同步的Reachability

(1)使用同步的方式是比较简单,导入Reachability.h头文件,然后通过代码检查网络:

#import “Reachability.h”

。。。some code omitted…

Reachability *reach = [Reachability reachabilityForInternetConnection];

NetworkStatus status = [reach currentReachabilityStatus];

   (2)通过检查某个主机能否访问来判断当前网络是否可用:

Reachability *reach = [Reachability reachabilityWithHostName:@“www.apple.com”];

NetworkStatus status = [reach currentReachabilityStatus];

 (3)案例:

创建一个工程,并添加Reachability.h和Reachability.m到工程中,并链接SystemConfiguration.framework.

在AppDelegate.h头文件中导入Reachability.h,并添加一个实例方法。如图:

    

在AppDelegate.m中这样实现:如图:

4.异步的Reachability

(1)异步的方式稍微复杂,不过通过这种方式可以来订阅实时的网络状态变化通知。导入Reachability.h头文件,然后注册一个对象来订阅网络状态变化的信息,网络状态变化的信息名称为kReachabilityChanged-Notification.如下:

[[NSNotificationCenter defaultCenter] addObserver:self

selector:@selector(reachabilityChanged:)

name:kReachabilityChangedNotification

object:nil];

(2)你需要创建一个Reachability对象实例并开始向外发布网络状态变化的消息:

Reachability *reach = [[Reachability reachabilityWithHostName:@“www.apple.com”] retain];

[reach startNotifier];

(3)当网络状态发生变化的时候,Reachability对象将调用reachabilityChanged:方法,可以在这个方法里面获取当前的网络状态,然后做相应的处理。

- (void)reachabilityChanged:(NSNotification *)notification{

Reachability *reach = [notification object];

if([reach isKindOfClass:[Reachability class]]){

NetworkStatus status = [reach currentReachabilityStatus];

//Insert your code here

}

}

****************************

5.原生 Reachability API

前面将的Reachability类实际上是苹果公司对SCNetworkReachability API的封装,这个API定义在SystemConfigure.framework库中。如果有其他特别的需求,也可以直接使用这个原生的SCNetworkReachability类。

.h 和.m文件

 //-------------------------.m---------------------------------------------------

 //-------------------------.m---------------------------------------------------

/*

File: Reachability.h

Copyright (C) 2014 Apple Inc. All Rights Reserved.

*/

#import <Foundation/Foundation.h>

#import <SystemConfiguration/SystemConfiguration.h>

#import <netinet/in.h>

typedef enum : NSInteger {

NotReachable = 0,

ReachableViaWiFi,

ReachableViaWWAN

} NetworkStatus;

extern NSString *kReachabilityChangedNotification;

@interface Reachability : NSObject

/*!

*

用于检查给定主机名的可达性。

*/

+ (instancetype)reachabilityWithHostName:(NSString *)hostName;

/*!

*

用来检查给定IP地址的可达性。

*/

+ (instancetype)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress;

/*!

*

检查是否违约路is available。should be used by应用that do not connect to a particular主机。

*/

+ (instancetype)reachabilityForInternetConnection;

/*!

* 检查是否一个本地无线连接是可用的。

*/

+ (instancetype)reachabilityForLocalWiFi;

/*!

*开始在当前运行的循环上侦听可达性通知。

*/

- (BOOL)startNotifier;

- (void)stopNotifier;

- (NetworkStatus)currentReachabilityStatus;

/*!

* WWAN may be available, but not active until a connection has been established. WiFi may require a connection for VPN on Demand.

*广域网可能是可用的,但不主动到连接已经建立。无线网络可能需要连接VPN的需求。

*/

- (BOOL)connectionRequired;

@end

 //-------------------------.m---------------------------------------------------

 //-------------------------.m---------------------------------------------------

/*

File: Reachability.m

Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs.

Version: 3.5

Copyright (C) 2014 Apple Inc. All Rights Reserved.

*/

#import <arpa/inet.h>

#import <ifaddrs.h>

#import <netdb.h>

#import <sys/socket.h>

#import <CoreFoundation/CoreFoundation.h>

#import "Reachability.h"

NSString *kReachabilityChangedNotification = @"kNetworkReachabilityChangedNotification";

#pragma mark - Supporting functions

#define kShouldPrintReachabilityFlags 1

static void PrintReachabilityFlags(SCNetworkReachabilityFlags flags, const char* comment)

{

#if kShouldPrintReachabilityFlags

NSLog(@"Reachability Flag Status: %c%c %c%c%c%c%c%c%c %s\n",

(flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-',

(flags & kSCNetworkReachabilityFlagsReachable)            ? 'R' : '-',

(flags & kSCNetworkReachabilityFlagsTransientConnection)  ? 't' : '-',

(flags & kSCNetworkReachabilityFlagsConnectionRequired)   ? 'c' : '-',

(flags & kSCNetworkReachabilityFlagsConnectionOnTraffic)  ? 'C' : '-',

(flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',

(flags & kSCNetworkReachabilityFlagsConnectionOnDemand)   ? 'D' : '-',

(flags & kSCNetworkReachabilityFlagsIsLocalAddress)       ? 'l' : '-',

(flags & kSCNetworkReachabilityFlagsIsDirect)             ? 'd' : '-',

comment

);

#endif

}

static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)

{

#pragma unused (target, flags)

NSCAssert(info != NULL, @"info was NULL in ReachabilityCallback");

NSCAssert([(__bridge NSObject*) info isKindOfClass: [Reachability class]], @"info was wrong class in ReachabilityCallback");

Reachability* noteObject = (__bridge Reachability *)info;

// Post a notification to notify the client that the network reachability changed.

[[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification object: noteObject];

}

#pragma mark - Reachability implementation

@implementation Reachability

{

BOOL _alwaysReturnLocalWiFiStatus; //default is NO

SCNetworkReachabilityRef _reachabilityRef;

}

+ (instancetype)reachabilityWithHostName:(NSString *)hostName

{

Reachability* returnValue = NULL;

SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);

if (reachability != NULL)

{

returnValue= [[self alloc] init];

if (returnValue != NULL)

{

returnValue->_reachabilityRef = reachability;

returnValue->_alwaysReturnLocalWiFiStatus = NO;

}

}

return returnValue;

}

+ (instancetype)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress

{

SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)hostAddress);

Reachability* returnValue = NULL;

if (reachability != NULL)

{

returnValue = [[self alloc] init];

if (returnValue != NULL)

{

returnValue->_reachabilityRef = reachability;

returnValue->_alwaysReturnLocalWiFiStatus = NO;

}

}

return returnValue;

}

+ (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);

Reachability* returnValue = [self reachabilityWithAddress: &localWifiAddress];

if (returnValue != NULL)

{

returnValue->_alwaysReturnLocalWiFiStatus = YES;

}

return returnValue;

}

#pragma mark - Start and stop notifier

- (BOOL)startNotifier

{

BOOL returnValue = NO;

SCNetworkReachabilityContext context = {0, (__bridge void *)(self), NULL, NULL, NULL};

if (SCNetworkReachabilitySetCallback(_reachabilityRef, ReachabilityCallback, &context))

{

if (SCNetworkReachabilityScheduleWithRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode))

{

returnValue = YES;

}

}

return returnValue;

}

- (void)stopNotifier

{

if (_reachabilityRef != NULL)

{

SCNetworkReachabilityUnscheduleFromRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);

}

}

- (void)dealloc

{

[self stopNotifier];

if (_reachabilityRef != NULL)

{

CFRelease(_reachabilityRef);

}

}

#pragma mark - Network Flag Handling

- (NetworkStatus)localWiFiStatusForFlags:(SCNetworkReachabilityFlags)flags

{

PrintReachabilityFlags(flags, "localWiFiStatusForFlags");

NetworkStatus returnValue = NotReachable;

if ((flags & kSCNetworkReachabilityFlagsReachable) && (flags & kSCNetworkReachabilityFlagsIsDirect))

{

returnValue = ReachableViaWiFi;

}

return returnValue;

}

- (NetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags

{

PrintReachabilityFlags(flags, "networkStatusForFlags");

if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)

{

// The target host is not reachable.

return NotReachable;

}

NetworkStatus returnValue = NotReachable;

if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)

{

/*

If the target host is reachable and no connection is required then we'll assume (for now) that you're on Wi-Fi...

*/

returnValue = ReachableViaWiFi;

}

if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||

(flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))

{

/*

... and the connection is on-demand (or on-traffic) if the calling application is using the CFSocketStream or higher APIs...

*/

if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)

{

/*

... and no [user] intervention is needed...

*/

returnValue = ReachableViaWiFi;

}

}

if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)

{

/*

... but WWAN connections are OK if the calling application is using the CFNetwork APIs.

*/

returnValue = ReachableViaWWAN;

}

return returnValue;

}

- (BOOL)connectionRequired

{

NSAssert(_reachabilityRef != NULL, @"connectionRequired called with NULL reachabilityRef");

SCNetworkReachabilityFlags flags;

if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags))

{

return (flags & kSCNetworkReachabilityFlagsConnectionRequired);

}

return NO;

}

- (NetworkStatus)currentReachabilityStatus

{

NSAssert(_reachabilityRef != NULL, @"currentNetworkStatus called with NULL SCNetworkReachabilityRef");

NetworkStatus returnValue = NotReachable;

SCNetworkReachabilityFlags flags;

if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags))

{

if (_alwaysReturnLocalWiFiStatus)

{

returnValue = [self localWiFiStatusForFlags:flags];

}

else

{

returnValue = [self networkStatusForFlags:flags];

}

}

return returnValue;

}

@end

李洪强iOS开发之使用 Reachability 检测网络的更多相关文章

  1. 李洪强iOS开发之添加手势

    李洪强iOS开发之添加手势 02 - 添加手势

  2. 李洪强iOS开发之- 实现简单的弹窗

     李洪强iOS开发之- 实现简单的弹窗 实现的效果:  112222222222223333333333333333

  3. 李洪强iOS开发之后使用XIB实现横向滚动的UIScrollView

    李洪强iOS开发之后使用XIB实现横向滚动的UIScrollView 11111222

  4. 李洪强iOS开发之苹果使用预览截图

    李洪强iOS开发之苹果使用预览截图 01 在预览的图片中选中你要截得区域  02 - command + C   03 - Command + N 04 - Command + S (保存)

  5. 李洪强iOS开发之通知的使用

    李洪强iOS开发之通知的使用 01 - 在A中发送通知 02 - 在B中监听通知 03 - 在B中通知出发的方法 04 - 在B控制器viewDidLoad调用通知

  6. 李洪强iOS开发之后使用纯代码实现横向滚动的UIScrollView

    李洪强iOS开发之后使用纯代码实现横向滚动的UIScrollView (VTmagic是一个实现左右滚动的控制器的框架,也可以实现此功能) 实现的效果:  01 - 创建四个控制器 02 - 定义需要 ...

  7. 李洪强iOS开发之 - 实现九宫格并使用SDWebImage下载图片

     李洪强iOS开发之 - 实现九宫格并使用SDWebImage下载图片  源码:  // //  ViewController.m //  08-九宫格扩展 // //  Created by 李洪强 ...

  8. 李洪强iOS开发之 - WebViewJavascriptBridge

    李洪强iOS开发之 - WebViewJavascriptBridge 01 - JS端:   02 - iOS端 01 遵守代理协议 02 申明属性 03 开启日志 04 给哪个webview建立J ...

  9. 李洪强iOS开发本人集成环信的经验总结_09_处理好友请求

    李洪强iOS开发本人集成环信的经验总结_09_处理好友请求 实现这种效果: 01 - 遵守处理好友请求的代理协议 02  - 设置代理 03 - 实现代理方法 04 - 实现代理中用到的方法 

随机推荐

  1. Objective-C 【动态类型检测&响应方法】

    ------------------------------------------- 动态类型检测 代码: #import <Foundation/Foundation.h> @inte ...

  2. (转)java:快速文件分割及合并

    文件分割与合并是一个常见需求,比如:上传大文件时,可以先分割成小块,传到服务器后,再进行合并.很多高大上的分布式文件系统(比如:google的GFS.taobao的TFS)里,也是按block为单位, ...

  3. javascript笔记——date以及datetime的比较

    <script src="$!webPath/resources/js/laydate/laydate.js"></script> <script s ...

  4. 膜拜 2014-2 (献给L之三)

    文/安然 深深的夜静静的想你细细的品味满满的甜蜜爱,心灵的对话让我流泪战栗谢谢你给我这么弥足珍贵的体会不能一生相随又有什么关系你一直都在我的爱就永不停息此生足以——献给心底的爱

  5. PERL 脚本

    PERL: Practical Extraction and Report Language 参考文档 1.Perl 5 version 24.0 documentation

  6. android浪漫樱花凋零动态壁纸应用源码

    android浪漫樱花凋零动态壁纸应用源码,是从那个安卓教程网拿过来的,本项目是一套基于安卓的樱花动态壁纸项目源码,安装以后桌面没有图标,但是可以在修改壁纸-动态壁纸中找到.我的分辨率是480×854 ...

  7. Android 布局 中实现适应屏幕大小及组件滚动

    要实现如图的布局: 这是在eclipse可视化窗口中的截图,但实际运行在Android设备上可能出现的问题有: (1):当编辑图1中的最后一个EditText时,输入法的编辑界面会把底部的Button ...

  8. js优化 ----js的有序加载

    说到有序加载,我们先来说说js的无序加载: <script src="jquery/jquery-1.4.1.js" type="text/javascript&q ...

  9. 非常出色的一款WinForm窗体重绘GUI类库源码

    基本控件的演示 ScrollBar滚动条 各种圆形进度条 ProgressBar进度条 Mdi演示,仿谷歌浏览器 多种皮肤可供选择 一套专业级别的GUI控件,目前包含了窗体.进度条.滚动条以及MDI多 ...

  10. HTTP Header 详解【转】

    原文出自:http://kb.cnblogs.com/page/92320/ HTTP(HyperTextTransferProtocol)即超文本传输协议,目前网页传输的的通用协议.HTTP协议采用 ...