一、说明
在网络应用中,需要对用户设备的网络状态进行实时监控,有两个目的:
(1)让用户了解自己的网络状态,防止一些误会(比如怪应用无能)
(2)根据用户的网络状态进行智能处理,节省用户流量,提高用户体验
WIFI\3G网络:自动下载高清图片
低速网络:只下载缩略图
没有网络:只显示离线的缓存数据
iOS7以前苹果官方提供了一个叫Reachability的示例程序,便于开发者检测网络状态
https://developer.apple.com/library/ios/samplecode/Reachability/Reachability.zip
iOS7之后苹果提供了 <CoreTelephony/CTTelephonyNetworkInfo.h>可以获取当前的网络状态(但是没找到wifi)
参考我的另一篇博文——iOS获取设备信息
二、监测网络状态
Reachability的使用步骤
添加框架SystemConfiguration.framework
(1) 点击项目,选择"Build Phases"选项卡
(2) 展开"Link Binary With Libraries"并添加相应选项
下载Reachability项目的压缩包,右击工程文件夹(注意不是总的那个项目文件)添加以下文件
添加Reachability.h 和 Reachability.m
在需要调用的m文件中包含相应头文件
#import "Reachability.h"
即可开始实现(略)
三、项目结构和运行结果
(1)项目结构
(2)运行结果(当网络变化时会自动改变当前连接状态)
四、官方实现源码
/*
Copyright (C) 2016 Apple Inc. All Rights Reserved.
See LICENSE.txt for this sample’s licensing information
Abstract:
Application delegate class.
*/
#import "APLViewController.h"
#import "Reachability.h"
@interface APLViewController ()
@property (nonatomic, weak) IBOutlet UILabel* summaryLabel;
@property (nonatomic, weak) IBOutlet UITextField *remoteHostLabel;
@property (nonatomic, weak) IBOutlet UIImageView *remoteHostImageView;
@property (nonatomic, weak) IBOutlet UITextField *remoteHostStatusField;
@property (nonatomic, weak) IBOutlet UIImageView *internetConnectionImageView;
@property (nonatomic, weak) IBOutlet UITextField *internetConnectionStatusField;
@property (nonatomic) Reachability *hostReachability;
@property (nonatomic) Reachability *internetReachability;
@end
@implementation APLViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.summaryLabel.hidden = YES;
/*
Observe the kNetworkReachabilityChangedNotification. When that notification is posted, the method reachabilityChanged will be called.
*/
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kReachabilityChangedNotification object:nil];
//Change the host name here to change the server you want to monitor.
NSString *remoteHostName = @"www.apple.com";
NSString *remoteHostLabelFormatString = NSLocalizedString(@"Remote Host: %@", @"Remote host label format string");
self.remoteHostLabel.text = [NSString stringWithFormat:remoteHostLabelFormatString, remoteHostName];
self.hostReachability = [Reachability reachabilityWithHostName:remoteHostName];
[self.hostReachability startNotifier];
[self updateInterfaceWithReachability:self.hostReachability];
self.internetReachability = [Reachability reachabilityForInternetConnection];
[self.internetReachability startNotifier];
[self updateInterfaceWithReachability:self.internetReachability];
}
/*!
* Called by Reachability whenever status changes.
*/
- (void) reachabilityChanged:(NSNotification *)note
{
Reachability* curReach = [note object];
NSParameterAssert([curReach isKindOfClass:[Reachability class]]);
[self updateInterfaceWithReachability:curReach];
}
- (void)updateInterfaceWithReachability:(Reachability *)reachability
{
if (reachability == self.hostReachability)
{
[self configureTextField:self.remoteHostStatusField imageView:self.remoteHostImageView reachability:reachability];
NetworkStatus netStatus = [reachability currentReachabilityStatus];
BOOL connectionRequired = [reachability connectionRequired];
self.summaryLabel.hidden = (netStatus != ReachableViaWWAN);
NSString* baseLabelText = @"";
if (connectionRequired)
{
baseLabelText = NSLocalizedString(@"Cellular data network is available.\nInternet traffic will be routed through it after a connection is established.", @"Reachability text if a connection is required");
}
else
{
baseLabelText = NSLocalizedString(@"Cellular data network is active.\nInternet traffic will be routed through it.", @"Reachability text if a connection is not required");
}
self.summaryLabel.text = baseLabelText;
}
if (reachability == self.internetReachability)
{
[self configureTextField:self.internetConnectionStatusField imageView:self.internetConnectionImageView reachability:reachability];
}
}
- (void)configureTextField:(UITextField *)textField imageView:(UIImageView *)imageView reachability:(Reachability *)reachability
{
NetworkStatus netStatus = [reachability currentReachabilityStatus];
BOOL connectionRequired = [reachability connectionRequired];
NSString* statusString = @"";
switch (netStatus)
{
case NotReachable: {
statusString = NSLocalizedString(@"Access Not Available", @"Text field text for access is not available");
imageView.image = [UIImage imageNamed:@"stop-32.png"] ;
/*
Minor interface detail- connectionRequired may return YES even when the host is unreachable. We cover that up here...
*/
connectionRequired = NO;
break;
}
case ReachableViaWWAN: {
statusString = NSLocalizedString(@"Reachable WWAN", @"");
imageView.image = [UIImage imageNamed:@"WWAN5.png"];
break;
}
case ReachableViaWiFi: {
statusString= NSLocalizedString(@"Reachable WiFi", @"");
imageView.image = [UIImage imageNamed:@"Airport.png"];
break;
}
}
if (connectionRequired)
{
NSString *connectionRequiredFormatString = NSLocalizedString(@"%@, Connection Required", @"Concatenation of status string with connection requirement");
statusString= [NSString stringWithFormat:connectionRequiredFormatString, statusString];
}
textField.text= statusString;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:kReachabilityChangedNotification object:nil];
}
@end