Reachability——网络状态检测

WARNING there have been reports of apps being rejected when Reachability is used in a framework. The only solution to this so far is to rename the class.

警告:该类库可能使用了与 Apple 源码相同的类名,因此提交应用审核时,可能会被拒绝。目前为止,唯一的解决方法就是更改类名。

Reachability

Reachability 是 Apple 的 Reachability 类的替代品。 它兼容自动引用计数(ARC),使用新的 GCD 方法来通知网络状态的变化。

除了标准的 NSNotification 之外,它还支持使用 Blocks 块的方式处理网络是否可访问的情况。

最后,你可以指定是否将 WWAN 连接视为“可达”。

在真实设备上测试之前,请不要开启 BUGS 模式

在你开启一个关于 iOS6 / iOS5 版本的构建错误之前,请使用标签3.2或3.1,因为它们支持分配类型。

Requirements

Once you have added the .h/m files to your project, simply:

  • Go to the Project->TARGETS->Build Phases->Link Binary With Libraries.
  • Press the plus in the lower left of the list.
  • Add SystemConfiguration.framework.

Boom, you're done.

示例

一、Blocks 方法示例

使用 Blocks 块来监听网络状态是否改变。该 Blocks 将会在后台线程中被调用,因此你需要将UI 更新切换到主线程中。

Objective-C 示例

// 创建 reachability 对象
Reachability *reach = [Reachability reachabilityWithHostname:@"www.google.com"];

// 设置网络可以访问的 blocks 回调
reach.reachableBlock = ^(Reachability*reach)
{
    // 记住这里的代码会在后台线程中被调用,如果你想要更新 UI,一定到切换到主线程:
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"REACHABLE!");
    });
};

// 设置网络不可访问的 blocks 回调
reach.unreachableBlock = ^(Reachability*reach)
{
    NSLog(@"UNREACHABLE!");
};

// 开启监听
[reach startNotifier];

Swift 3 示例

import Reachability

var reach: Reachability?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Allocate a reachability object
        self.reach = Reachability.forInternetConnection()
        
        // Set the blocks
        self.reach!.reachableBlock = {
            (reach: Reachability?) -> Void in
            
            // keep in mind this is called on a background thread
            // and if you are updating the UI it needs to happen
            // on the main thread, like this:
            DispatchQueue.main.async {
                print("REACHABLE!")
            }
        }
        
        self.reach!.unreachableBlock = {
            (reach: Reachability?) -> Void in
            print("UNREACHABLE!")
        }
        
        self.reach!.startNotifier()
    
        return true
}

二、NSNotification 通知方法示例

此示例将使用 NSNotification 来通知网络连接状态的变化。 它们将在主线程上被调用,因此你可以从该函数内部进行UI更新。

此外,它要求Reachability对象默认将 WWAN(3G / EDGE / CDMA)蜂窝网络视为不可达的连接(如果你正在编写视频流应用程序(例如,用于保存用户的数据计划),则可以使用此功能)。

Objective-C 示例

// 通过指定域名的方式创建 reachability 对象
Reachability* reach = [Reachability reachabilityWithHostname:@"www.google.com"];

// 不判断蜂窝网络是否可用
reach.reachableOnWWAN = NO;

// Here we set up a NSNotification observer. The Reachability that caused the notification
// is passed in the object parameter
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(reachabilityChanged:)
                                             name:kReachabilityChangedNotification
                                           object:nil];

[reach startNotifier];

接收通知的方法:

-(void)reachabilityChanged:(NSNotification*)note
{
    Reachability * reach = [note object];
    if([reach isReachable])
    {
        NSString * temp = [NSString stringWithFormat:@"GOOGLE Notification Says Reachable(%@)", reach.currentReachabilityString];
        NSLog(@"%@", temp);
    }
    else
    {
        NSString * temp = [NSString stringWithFormat:@"GOOGLE Notification Says Unreachable(%@)", reach.currentReachabilityString];
        NSLog(@"%@", temp);
    }
}

Swift 3 示例

import Reachability

var reach: Reachability?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Allocate a reachability object
    self.reach = Reachability.forInternetConnection()
    
    // Tell the reachability that we DON'T want to be reachable on 3G/EDGE/CDMA
    self.reach!.reachableOnWWAN = false
    
    // Here we set up a NSNotification observer. The Reachability that caused the notification
    // is passed in the object parameter
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(reachabilityChanged),
        name: NSNotification.Name.reachabilityChanged,
        object: nil
    )
    
    self.reach!.startNotifier()
    
    return true
}
        
func reachabilityChanged(notification: NSNotification) {
    if self.reach!.isReachableViaWiFi() || self.reach!.isReachableViaWWAN() {
        print("Service avalaible!!!")
    } else {
        print("No service avalaible!!!")
    }
}

Tell the world

Head over to Projects using Reachability and add your project for "Maximum Wins!".

总结

  1. 创建 Reachability 对象的方法有以下几种:
+(instancetype)reachabilityWithHostName:(NSString*)hostname; // 指定域名
+(instancetype)reachabilityForInternetConnection; // 通用网络连接
+(instancetype)reachabilityWithAddress:(void *)hostAddress; // 指定地址
+(instancetype)reachabilityForLocalWiFi; // 指定Wi-Fi网络
  1. 可选设置,是否忽视蜂窝网络可达性
@property (nonatomic, assign) BOOL reachableOnWWAN;
  1. 监听网络可达性的方法有两种:

Blocks 方式:

@property (nonatomic, copy) NetworkReachable    reachableBlock;
@property (nonatomic, copy) NetworkUnreachable  unreachableBlock;

通知方式:

[[NSNotificationCenter defaultCenter] addObserver:self 
                                        selector:@selector(reachabilityChanged:) 
                                            name:kReachabilityChangedNotification 
                                          object:nil];
  1. 开始、停止监听
-(BOOL)startNotifier;
-(void)stopNotifier;

示例代码

// 网络可达性检查
Reachability *reachability = [Reachability reachabilityWithHostName:URL_HOST];
reachability.reachableBlock = ^(Reachability *reachability) {
    // 3.0s 后执行加载任务
    // 默认情况下,切换到主线程更新UI,这里延迟3秒是为了多旋转一会菊花用的。
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        // 连接服务器
        [self connectToServer];
    });
};
reachability.unreachableBlock = ^(Reachability *reachability) {
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.emptyDescription = @"无法访问服务器,请稍后再试。";
        self.displayEmptyDataSet = YES;
        self.loading = NO;
    });
};
[reachability startNotifier];

类似框架

  1. Apple 官方示例:Reachability
  2. AFNetworkingAFNetworkReachabilityManager
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容