检查针对URL中特定页面的可达性

8
我看完了这个问题的答案后发现,使用reachabilityWithHostName无法检查像mySite.com/service.asmx这样的URL,那么有没有办法使用reachabilityWithHostName或其他reachability类方法来检查该URL的可达性呢?
非常感谢您的提前帮助。

1
可达性仅用于检查您是否具有互联网访问权限,以便确定是否应向用户发出警报并因此使用缓存数据。这是苹果用户交互指南的一部分。如果您想要检查特定的URL,则尝试访问它,将超时设置为非常短,并捕获错误。 - Nick Bull
3个回答

17

Reachability类和-reachabilityWithHostname:方法旨在快速、快速地确定您是否具有与主机的基本网络连接。如果您需要验证特定URL是否可以下载,则需要使用NSURLConnection检索URL的内容,以验证其是否真正可用。

根据您是需要在前台还是后台执行此操作,您可以使用简单但会阻塞的:

+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error

或者您可以使用更复杂的方法,创建一个NSURLConnection对象,设置代理以接收响应并等待这些响应的到来。

对于简单情况:

 NSURL *myURL = [NSURL URLWithString: @"http://example.com/service.asmx"];
 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: myURL];
 [request setHTTPMethod: @"HEAD"];
 NSURLResponse *response;
 NSError *error;
 NSData *myData = [NSURLConnection sendSynchronousRequest: request returningResponse: &response error: &error];

如果你收到了非空的myData,那么你就有了某种连接。在responseerror中,会告诉你服务器对你做出了什么响应(在响应的情况下,如果你收到了非空的myData),或者发生了什么样的错误(对于一个空的myData)。
对于复杂的情况,你可以从苹果公司的使用NSURLConnection获取良好的指导。
如果你不想阻塞前台进程,可以用两种不同的方式来实现。上述文档将提供有关如何实现委托等信息。但是,更简单的实现方式是使用GCD在后台线程上发送同步请求,然后在完成时向主线程发送消息。
像这样:
 NSURL *myURL = [NSURL URLWithString: @"http://example.com/service.asmx"];
 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: myURL];
 [request setHTTPMethod: @"HEAD"];
 dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_BACKGROUND, NULL), ^{
      NSURLResponse *response;
      NSError *error;
      NSData *myData = [NSURLConnection sendSynchronousRequest: request returningResponse: &response error: &error];
      BOOL reachable;

      if (myData) {
            // we are probably reachable, check the response
            reachable=YES;
      } else {
            // we are probably not reachable, check the error:
            reachable=NO;
      }

      // now call ourselves back on the main thread
      dispatch_async( dispatch_get_main_queue(), ^{
            [self setReachability: reachable];
      });
 });

你能提供一个简单的例子来在后台执行以防止应用程序挂起吗? - JAHelia
我已经添加了一个使用GCD的示例,以在异步调用后台线程上进行同步请求,并在完成时将响应作为消息返回到您的主线程。希望这有所帮助。 - gaige
太棒了!上面的代码有一个小错误,你必须在第一个if语句中将reachable设置为YES,在第二个if语句中将其设置为NO。非常感谢,gaige。 - JAHelia
@brainray感谢您的有益编辑。注意:对于那些想知道为什么将域名示例从MySite.com更改为example.com的人,这是Stack Overflow的要求。 - gaige

6

如果您想检查URL的可达性(通常用于主机名),只需使用NSURLConnection进行HEAD请求即可。


4

Swift 5

Swift 5的一个可能解决方案是:

 func verifyURL(urlPath: String, completion: @escaping (_ isValid: Bool) ->()) {
    if let url = URL(string: urlPath) {
        var request = URLRequest(url: url)
        request.httpMethod = "HEAD"
        let task = URLSession.shared.dataTask(with: request) { _, response, error in
            if let httpResponse = response {
                if httpResponse.getStatusCode() == 200 {
                completion(true)
                }
            } else {
                completion(false)
            }
        }
        task.resume()
    } else {
        completion(false)
    }
}

那么就让我们这样调用该方法:
verifyURL(urlPath: "www.google.com", completion: { (isValid) in
    if isValid {
        runYourCode()
    } else {
        print("URL: www.google.com is not reachable")
    }
})

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