iOS可达性测试

3

对于我们的应用程序,每当应用程序用户尝试发布消息时,我们使用以下代码检查互联网连接。当我们测试该功能时,在打开飞行模式时它可以正常工作。然后当我们关闭飞行模式时,调用connected仍然返回NO。可能的原因是什么?我们需要额外的“设置”才能正确获取吗?比如监听网络状态改变通知?

+ (BOOL)connected 
{
    Reachability *hostReach = [Reachability reachabilityForInternetConnection]; 
    NetworkStatus netStatus = [hostReach currentReachabilityStatus];    
    return !(netStatus == NotReachable);
}
3个回答

2

苹果工程师建议不要完全依赖Rechability。

来自SO帖子(引用的来源)

On a WWDC talk this year the Apple engineer on stage recommended users to never base 
the application internet access on the Reachability example app status. Often     
reachability doesn't provide a complete information (it is based on a complex mechanism)    
and the suggestion provided by the engineer was this:

1. try to do your internet connection, whatever it is the Reachability status; 
   then set your UI hint based on success/fail result
2. if it fails due to networking issue, then register to Reachability and retry again 
   when Reachability gives the green light; this is needed when you want to recover 
   automatically from the fail condition
3. in any case give the user the possibility to "force a retry", whatever is the 
   Reachability status. If it succeeds, reset your UI hint immediately.

我能做什么?

每次我需要建立连接时,例如

NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString 
               stringWithFormat:@"http://myadress.com"]]];
[self performSelectorOnMainThread:@selector(responseHandler:)
                       withObject:data waitUntilDone:TRUE];


- (void)responseHandler:(NSData *)responseData {
    if(!responseData) {
       ReachabilityController *reachability = [[ReachabilityController alloc] init];
       [reachability checkReachability];
       return;
    }
   // you handle your data
}

那里正在发生的事情是,只有在连接失败时才会测试可达性。我创建了一个通用的ReachabilityController,只处理可达性。我这样做是为了每次发出请求时,可以从所有其他控制器中进行调用。
我的ReachabilityController.m看起来像:
-(void) checkReachability {
     Reachability* internetAvailable = [Reachability reachabilityForInternetConnection];
     NetworkStatus netStatus = [internetAvailable currentReachabilityStatus];
     NSString *messageText;
     if (netStatus == NotReachable)
     {
         messageText = [NSString stringWithFormat:@"Internet access not available"];
     }
     else
     {
          Reachability *netReach = [Reachability reachabilityWithHostName:host];
          NetworkStatus hostStatus = [netReach currentReachabilityStatus];
          if (hostStatus == NotReachable)
          {
              messageText = [NSString stringWithFormat:@"Host Unreachable"];

          }
          else
          {
              messageText = [NSString stringWithFormat:@"Problem with remote service"];
          }

     }
     NSLog(@"%@", messageText);   
}

它不会导致您的应用程序崩溃,因为您正在自己处理“nil”数据参数,并最终确定原因。

希望这可以帮助您!

更新:

如果您显示有关Internet连接的错误消息,则Apple可能会拒绝您的应用程序。他们非常重视与iPhone的声誉。如果互联网连接可用,但是您的应用程序报告互联网连接不可用,则这将被认为是非常严重的


1
你应该直接尝试网络连接,而不使用Reachability。 NSURLConnection会启动无线电。但是,在它失败时一定要处理错误。

0

你正在使用某种方便的构造函数来检查可达性——这样做行不通。

有关如何使用可达性的最佳示例之一可以在此SO上找到:

https://dev59.com/BHNA5IYBdhLWcg3wH6EW#3597085

或者像EricS建议的那样,根本不使用可达性 - 这是一个可行的选择。


当我们在主线程调用Reachability时,在我们的代码中发现了许多超时崩溃。这种情况会在某些不良网络条件下发生。所以现在我们仅在后台线程上调用它,并仅将其用于“网络已连接”通知,而不是“网络是否可用”的测试。 - EricS
你不应该直接“调用”Reachability。你需要先进行设置并监听其通知。 - Rok Jarc

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