检查是否可以访问互联网

时间:2020-01-08 16:03:15

标签: ios nsurlsession nsurlrequest reachability nsurlsessionconfiguration

在我的应用中,我只想在可以访问互联网的情况下才能拨打网络电话。

注意:我已连接到没有Internet的WiFi点

我想测试互联网是否可用。我尝试使用here中所述的“可达性”,也尝试过here中所述的更简单的解决方案

问题在于,“可达性”是它返回Internet可以访问时返回的信息。其他解决方案花费太多时间才能做出响应。我试图为请求和会话设置超时间隔,但是它被忽略了。

如果我连接到没有互联网的wifi,如何测试互联网的可达性?

这是我使用的一些代码:

- (void) postAsyncTaskWithUrl:(NSString*)urlString
                      andType:(NSString*)requestType
                     andToken:(NSString*)token
          andPropertiesObject:(id)propObject
                   urlEncoded:(BOOL)isUrlEncoded
                  withSuccess:(nullable void(^)(id _Nullable))success
                   andFailure:(nullable void(^)(id _Nullable))failure
{

    internetReachableFoo = [Reachability reachabilityWithHostname:@"www.google.com"];

    __weak typeof(self) weakSelf = self;
    // Internet is reachable
    internetReachableFoo.reachableBlock = ^(Reachability*reach)
    {
                 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:urlSt];
        [request setTimeoutInterval:20]; //Ignored ... WHY?

        NSURLSessionConfiguration *sessionConfigurations = [NSURLSessionConfiguration defaultSessionConfiguration];
        [sessionConfigurations setTimeoutIntervalForRequest:20]; //Ignored ... WHY?
        [sessionConfigurations setTimeoutIntervalForResource:20]; //Ignored ... WHY?
//        NSURLSession *session = [NSURLSession sharedSession];
        NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfigurations];
        [[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {


     }

}

}

3 个答案:

答案 0 :(得分:4)

尽管这是过去的历史记录,但我认为值得一试,以检查网络是否可访问,因为它不是可靠的东西,也不是在发出请求之前应做的事情现在几乎在所有情况下。

根据Apple's official documentation

始终尝试建立连接。不要试图猜测是否 网络服务可用,并且不缓存该决定

类似的blog post from Jared Sinclair on this topic,使用SCNetworkReachability(可到达性库在幕后使用的方式):

SCNetworkReachability仅应用于影响您对已经失败的网络请求的处理方式,而不能影响尚未尝试的初始请求。使用否定状态确定您是否尝试自动重试,或调整警报的面向用户的语言。使用肯定状态可以考虑重试先前失败的请求。切勿仅仅因为SCNetworkReachability认为网络不可达而阻止用户启动的请求

a recent Reddit thread借用:

可达到性是iOS世界中的一个或“这些主题”。这是什么意思 互联网可以访问?即使您检查网络接口, 您可能无法访问apple.com或google.com。即使你 联系Google,您可能无法访问本地服务器或 云。如果您检查是否可以访问您感兴趣的服务器,为什么 不立即发送请求?

答案 1 :(得分:2)

TL; DR:You probably want an NSTimer.

在我的应用中,我只想在可以访问互联网的情况下才能拨打网络电话。

这不是有意义的声明。没有可以可靠地执行的测试,也就是说您可以“访问互联网”(尽管存在NSURLErrorNotConnectedToInternet,但这实际上并不表示其含义)。例如,您的代码试图将“ www.google.com”视为“互联网”。但是,完全有可能建立一个允许数据包访问www.google.com的网络,而没有其他地方。或允许ICMP数据包,但不允许HTTP数据包。或允许HTTP数据包,但不允许在某些端口上。这样的网络配置不仅是可能的,而且很常见,并且以各种方式都看起来像“不在Internet上”。

您唯一可以回答的是“我可以将数据包发送到特定主机并接收数据包吗?”甚至不可能知道您是否只能发送数据包。如果您没有得到任何回报,则不知道您的包裹是否已送达。

可访问性回答了以下问题:“如果我尝试发送数据包,我的本地网络堆栈还会尝试吗?”基本上,问题在于路由表中是否存在第一跳。这并不意味着您可以实际连接。它只能告诉你它绝对不会。

您使用的超时基于会话的空闲时间。但是您永远不会启动会话,因此它永远不会闲置。您正在寻找的超时是TCP超时,我希望是4分钟。 NSURLSession无法配置它。

如果您希望挂钟“开始完成”超时,则需要run it yourself with a Timer

答案 2 :(得分:0)

如果您尝试加载http://captive.apple.com,则如果Internet正常工作,它将以硬编码字符串“ Success”作为正文返回,否则将重定向/失败。您可以检查响应开始为200,正文为“成功”。这就是Apple在连接到WiFi之类的机场时用于自动显示凭据窗口的方式 这样说 a)没有万无一失的解决方案 b)您将浪费用户的数据(在您的用例中可以吗?)