iPhone 可达性检查

Posted

技术标签:

【中文标题】iPhone 可达性检查【英文标题】:iPhone reachability checking 【发布时间】:2010-12-24 02:47:33 【问题描述】:

我找到了几个代码示例来做我想做的事(检查可达性),但似乎没有一个对我有用。我不明白为什么这不想玩得很好。

我的项目中有reachability.h/m,我正在做

#import <SystemConfiguration/SystemConfiguration.h>

我添加了框架。我也有:

#import "Reachability.h"

在我尝试使用可达性的 .m 顶部。

Reachability* reachability = [Reachability sharedReachability];
[reachability setHostName:@"http://www.google.com"];    // set your host name here
NetworkStatus remoteHostStatus = [reachability remoteHostStatus];

if(remoteHostStatus == NotReachable) NSLog(@"no");
else if (remoteHostStatus == ReachableViaWiFiNetwork) NSLog(@"wifi"); 
else if (remoteHostStatus == ReachableViaCarrierDataNetwork) NSLog(@"cell"); 

这给了我各种各样的问题。我究竟做错了什么?我是一个很好的编码员,我只是很难弄清楚需要把什么放在哪里来启用我想做的事情,无论我是否想知道我想做什么。 (好郁闷)

更新:这就是正在发生的事情。这是在我的视图控制器中,我有

#import <SystemConfiguration/SystemConfiguration.h>

#import "Reachability.h"

设置。这是迄今为止我最不喜欢的编程部分。(来源:sneakyness.com)


FWIW,我们从未在代码中实现这一点。需要互联网访问的两个功能(参加抽奖活动和购买 DVD)不是主要功能。没有其他需要互联网访问。

我们没有添加更多代码,而是将两个 Internet 视图的背景设置为通知用户他们必须连接到 Internet 才能使用此功能。它与应用程序界面的其余部分处于主题中,并且做得很好/有品位。他们在审批过程中只字未提,但我们确实接到了一个私人电话,以确认我们正在赠送与电影实际相关的物品。根据他们通常含糊不清的协议,否则不允许您进行抽奖活动。

我还认为这也更严格地遵循了他们“仅在绝对需要时才使用它们”的理念。

Here's the iTunes link to the application, EvoScanner.

【问题讨论】:

在什么方面没有做你想做的事?我们无法从这里的代码中看出你想要什么或它是如何不工作的。它不会编译,在某些情况下不会产生正确的结果,还是什么? 我更新了问题以反映我的问题。抱歉没有更具体。 原来我们从来不需要它!他们确实说最好的代码是你永远不必编写的代码!:D 【参考方案1】:

从您的屏幕截图来看,您的项目中似乎没有添加可达性。您必须从 Apple 下载 Reachability:

https://developer.apple.com/library/content/samplecode/Reachability/Introduction/Intro.html

并将 .h 和 .m 文件添加到您的项目中。

更新:你注意到你有可达性。但是查看最新版本,我可以看到您列出错误的原因 - 它们更改了 API,您可能正在使用您在其他地方找到的示例代码。试试:

在 .h 文件中:

//import Reachability class
#import "Reachability.h"

// declare Reachability, you no longer have a singleton but manage instances
Reachability* reachability;

在 .m 文件中:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNetworkChange:) name:kReachabilityChangedNotification object:nil];

reachability = [Reachability reachabilityForInternetConnection];
[reachability startNotifier];

NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];

 if(remoteHostStatus == NotReachable) NSLog(@"no");
else if (remoteHostStatus == ReachableViaWiFi) NSLog(@"wifi"); 
else if (remoteHostStatus == ReachableViaWWAN) NSLog(@"cell"); 

.....

- (void) handleNetworkChange:(NSNotification *)notice


  NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];

   if(remoteHostStatus == NotReachable) NSLog(@"no");
else if (remoteHostStatus == ReachableViaWiFi) NSLog(@"wifi"); 
else if (remoteHostStatus == ReachableViaWWAN) NSLog(@"cell"); 

【讨论】:

不,我已经添加了这两个,尽管这是一件值得一提的好事情。如何包含它们以便我可以在需要使用它们的地方使用它们?这真的让我很沮丧。 您需要在文件顶部有一个导入语句。导入可达性.h 我会这样做的!我从未在 SO 上看到此更新。我很抱歉没有更快地检查。我们实际上在没有这个的情况下完成了这个应用程序,所以我可能会在这个周末回去搞砸它。谢谢! @KendallHelmstetterGelner nikoz 的回答(如下)似乎有效。 NSNotification async 真的有必要吗?谢谢! 如果您需要稍后检查状态,最好支持回调而不是每次都创建新的可达性对象,特别是如果您正在寻找特定主机的可达性而不是一般的互联网连接.【参考方案2】:

改一下

reachability = [Reachability reachabilityForInternetConnection];

到这里

reachability = [[Reachability reachabilityForInternetConnection] retain];

【讨论】:

【参考方案3】:

这是今天适合我的正确代码!!!

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(handleNetworkChange:) name: kReachabilityChangedNotification object: nil];

reachability = [Reachability reachabilityForInternetConnection];

[reachability startNotifier];

NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];

if(remoteHostStatus == NotReachable) NSLog(@"no");
else if (remoteHostStatus == ReachableViaWiFi) NSLog(@"wifi"); 
else if (remoteHostStatus == ReachableViaWWAN) NSLog(@"cell"); 

【讨论】:

这是正确的。如果你这样做,它会阻塞主线程,所以你不需要异步版本。【参考方案4】:
[reachability setHostName:@"http://www.google.com"];

注意!如果使用 http:// 前缀,我遇到了总是“NotReachable”的问题。

拉斐尔

【讨论】:

仍然需要指出一个有效的陷阱。并非所有人都是网络协议专家。 这也吸引了我。谢谢@RaphaelSchaad【参考方案5】:

你有下面的代码吗?

[reachability startNotifier];

如果您的可达性代码来自苹果的示例,那么您需要在它开始向您报告状态更新之前执行此操作。

【讨论】:

即使您只是像上面的代码那样查询即时状态而不是等待通知,您是否需要这样做? 我相信;我可能是错的,但苹果的可达性代码基本上运行在一个单独的线程中,我相信它会在设定的时间间隔内检查可达性,你需要启动该进程,然后它才能将状态报告给你。 您不能查询即时状态。可达性通过您尝试建立连接来起作用,然后可达性开始发出有关状态的通知。您可以做的最接近的方法是尝试一些您知道自己存在的小型 URL 结果,然后等待通知。 Apple 在 WWDC 上非常明确地表明这是实现可达性的方法。 第二个 Kendall,您应该遵循 Apple 的可达性示例(确保您使用的是最新版本,我相信是 2.0)到 T。这包括异步检查可达性。如果您同步执行并且没有被 Apple 拒绝,那么您的应用程序一旦发布就会崩溃。 Reachability 演示的ReadMe.txt 仅警告不要同步检查hostName 可达性:“您可以同步使用API​​,但不要在主线程上通过hostName 发出同步检查。如果设备无法到达 DNS 服务器或处于慢速网络上,对 SCNetworkReachabilityGetFlags 函数的同步调用可能会阻塞长达 30 秒以尝试解析主机名。如果这种情况发生在主线程上,应用程序看门狗将在 20 秒后终止应用程序不活动。”

以上是关于iPhone 可达性检查的主要内容,如果未能解决你的问题,请参考以下文章

尽管有 4G,但一台设备的可达性返回“NotReachable”

检查 iPhone 上的互联网连接并监控变化

如何实现 iPhone 应用程序的可达性

iPhone 上的网络可达性

iPhone Wifi 开启还是关闭?

实时检查网络可达性