iPhone可达性检查

39
我找到了几个与我想要的相似的代码示例(检查可达性),但似乎没有一个足够准确以供我使用。我无法弄清楚为什么这不愿意友好地运行。
我在我的项目中有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)


顺便说一句,我们最终没有在我们的代码中实现这个功能。需要互联网访问的两个功能(参加抽奖和购买DVD)不是主要功能。其他任何功能都不需要互联网访问。

我们没有添加更多代码,而是将两个互联网视图的背景设置为提示用户必须连接到互联网才能使用此功能的通知。它与应用程序界面的其余部分相符,并且做得很好/有品味。他们在批准过程中对此没有发表任何意见,但我们确实接到了个人电话以验证我们正在赠送与电影相关的物品。根据他们通常含糊的协议,否则您不允许进行抽奖。

我也认为这更严格地遵守了他们的“只有在绝对需要时才使用东西”的理念。

这是应用程序EvoScanner的iTunes链接。


1
它没有按照你的要求完成哪些方面?从这个代码中我们无法判断你想要什么或者它是如何运作的。它是否不能编译,是否在某些情况下不能产生正确的结果,还是其他方面存在问题? - David Maymudes
我更新了问题以反映我的问题。很抱歉没有更具体。 - Sneakyness
2
结果证明我们其实从来就不需要它!他们说“最好的代码是你永远不必写的代码!” :D - Sneakyness
5个回答

65

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

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

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

更新:您已经注意到了Reachability。但是查看最新版本,我可以看到为什么您会遇到列出的错误-他们更改了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"); }
}

没有,我已经将它们都添加了,但是提醒检查一下是个好主意。我该如何包含它们,以便在需要使用它们的地方使用?这真的让我感到沮丧。 - Sneakyness
1
你需要在文件顶部添加一个导入语句。import Reachability.h - bpapa
我会做这个!我从来没有在 Stack Overflow 上看到这个更新。很抱歉我没有及时回复。实际上,我们已经完成了这个应用程序,所以我可能会在这个周末回头尝试一下。谢谢! - Sneakyness
@KendallHelmstetterGelner nikoz的回答(下面)似乎有效。 NSNotification异步部分真的必要吗?谢谢! - Dan Rosenstark
1
如果您需要稍后检查状态,最好支持回调而不是每次创建新的Reachability对象,特别是如果您正在寻找特定主机的可达性而不仅仅是一般的互联网连接。 - Kendall Helmstetter Gelner
为了我的笔记,因为我一直回到这里:刚刚在这里检查了readme.txt(https://developer.apple.com/library/IOs/samplecode/Reachability/Listings/ReadMe_txt.html)。结果发现它是同步形式的阻塞,所以虽然你不应该这样做,但是可以不包括异步块来完成。;) - Dan Rosenstark

29
[reachability setHostName:@"http://www.google.com"];

注意!我遇到了一个问题,如果使用http://前缀,它总是显示"NotReachable"。

Raphael


20
仍然有一个需要指出的有效陷阱。并非我们所有人都是网络协议专家。 - Nicolas Miari
1
我也遇到了这个问题。谢谢@RaphaelSchaad。 - Ray Hunter

7

以下是今天对我有效的正确代码!!!

[[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"); }

这是正确的。如果您以这种方式执行,它将阻塞主线程,因此您不需要异步版本。 - Dan Rosenstark

3
你是否在任何地方使用了以下代码?
[reachability startNotifier];

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

即使您只是查询即时状态而不等待通知,您是否仍需要执行此操作? - David Maymudes
1
你无法查询即时状态。可达性是通过你尝试建立连接,然后可达性开始发出有关状态的通知来工作的。你能做的最接近的事情是尝试一些你知道存在的小URL结果,然后等待通知。在WWDC上,苹果非常明确地表示这是实现可达性的方法。 - Kendall Helmstetter Gelner
1
赞同 Kendall 的观点,你应该完全遵循苹果的 Reachability 示例(确保你使用的是最新版本,我相信是 2.0)来实现。这包括异步检查可达性。如果你同步执行并且没有被苹果拒绝,一旦你的应用程序在外部环境中运行,它将会时不时地崩溃。 - bpapa
这对我没有任何帮助。不崩溃和不被拒绝是我的首要任务。谢谢你们提供的信息。 - Sneakyness
1
Reachability演示的ReadMe.txt只是警告不要同步检查hostName的可达性:“您可以同步使用API,但不要在主线程上发出对hostName的同步检查。如果设备无法访问DNS服务器或处于慢速网络上,则对SCNetworkReachabilityGetFlags函数的同步调用可能会阻塞长达30秒以尝试解析hostName。如果这种情况发生在主线程上,则应用程序看门狗将在20秒的不活动后杀死应用程序。” - ohhorob
显示剩余2条评论

-2

改变这个

reachability = [Reachability reachabilityForInternetConnection];

到这里

reachability = [[Reachability reachabilityForInternetConnection] retain];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接