在Swift中使用sendSynchronousRequest时如何检查Response.statusCode

80
如何在Swift中的SendSynchronousRequest中检查response.statusCode 以下是代码:

let urlPath: String = "URL_IS_HERE"
var url: NSURL = NSURL(string: urlPath)
var request: NSURLRequest = NSURLRequest(URL: url)
var response: AutoreleasingUnsafeMutablePointer<NSURLResponse?> = nil

var error: NSErrorPointer? = nil
var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: response, error: nil) as NSData?

在 Objective-C 中,我们可以使用以下代码检查 response.statusCode: (long)response.statusCode

但在 Swift 中,我不知道如何检查 response 状态码。

9个回答

115

您将响应的引用传递进去,以便填充它,然后检查结果并将其转换为HTTPResponse,因为只有HTTP响应声明状态码属性。

let urlPath: String = "http://www.google.de"
var url: NSURL = NSURL(string: urlPath)
var request: NSURLRequest = NSURLRequest(URL: url)
var response: NSURLResponse?

var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: nil) as NSData?

if let httpResponse = response as? NSHTTPURLResponse {
    println("error \(httpResponse.statusCode)")
}

注意:在 Objective-C 中使用相同的方法,但如果您使用方括号,编译器不会强制转换。Swift(类型安全)始终强制进行转换


你可以将 iflet 语句简化并合并为 if let httpResponse = response as? NSHTTPURLResponse { ... } - Martin R
是的,我不太习惯使用 if let 结构,但它更加简洁!-- 已编辑 - Daij-Djan
1
你的回答中所有以NS开头的类型现在都不需要NS前缀了。 NSHTTPURLResponse -> HTTPURLResponse 这是给未来程序员的一条注记。 - GranolaGuy

83

@GarySabo的回答的Swift 3版本:

let url = URL(string: "https://apple.com")!
let request = URLRequest(url: url)

let task = URLSession.shared().dataTask(with: request) {data, response, error in

    if let httpResponse = response as? HTTPURLResponse {
        print("statusCode: \(httpResponse.statusCode)")
    }

}
task.resume()

18

Swift 3+

let dataURL = "https://myurl.com"
        var request = URLRequest(url: URL(string: dataURL)!)
        request.addValue("Bearer \(myToken)", forHTTPHeaderField: "Authorization")
        URLSession.shared.dataTask(with: request) { (data, response, error) in
            // Check if the response has an error
            if error != nil{
                print("Error \(String(describing: error))")
                return
            }

            if let httpResponse = response as? HTTPURLResponse{
                if httpResponse.statusCode == 401{
                    print("Refresh token...")
                    return
                }
            }

            // Get data success

        }.resume()

17

我使用一个扩展来简化URLResponse(Swift 3):

extension URLResponse {

    func getStatusCode() -> Int? {
        if let httpResponse = self as? HTTPURLResponse {
            return httpResponse.statusCode
        }
        return nil
    }
}

而如何使用它呢?举个例子会更好。 - winklerrr
使用示例:if let statusCode = urlResponse.getStatusCode() { /*...*/ } - eskimwier

13
创建扩展程序以检查有效/无效的响应 -
extension HTTPURLResponse {
     func isResponseOK() -> Bool {
      return (200...299).contains(self.statusCode)
     }
}

从请求中获取响应 -

let task = URLSession.shared.dataTask(with: request) { (jsonData, response, error) in

                // post result on main thread
                DispatchQueue.main.async {

                    if let response = response as? HTTPURLResponse, response.isResponseOK() {
                        // assume if we don't receive any error then its successful
                        handler(true)
                    } else {
                        handler(false)
                    }
                }

            }
            task.resume()
        }

11

使用NSURLSession进行Swift 2.0清理

let urlPath: String = "http://www.google.de"
let url: NSURL = NSURL(string: urlPath)!
let request: NSURLRequest = NSURLRequest(URL: url)
var response: NSURLResponse?


let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) {urlData, response, reponseError in

         if let httpResponse = response as? NSHTTPURLResponse {
             print("error \(httpResponse.statusCode)")  
          }

 }
 task.resume()
 //You should not write any code after `task.resume()`

7

针对使用 await 的 Swift 5.5

        let (data, response) = try await URLSession.shared.data(for: request)

        if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode != 200 {
            print ("httpResponse.statusCode: \(httpResponse.statusCode)")

            throw(Error.invalidHttpResponseCode)
        }

1
如果您使用Just库,只需要这样简单:
Just.get("URL_IS_HERE").statusCode

0

Swift 5.7 你可以在playground上尝试这个:

import Foundation
import PlaygroundSupport

let url = URL(string: "http://stackoverflow.com")!

URLSession.shared.dataTask(with: url) { data, response, error in
    guard let data = data, error == nil else {
        print(error ?? "Unknown error")
        return
    }
    if let httpResponse = response as? HTTPURLResponse {
        print("statusCode: \(httpResponse.statusCode)")
    }
    let contents = String(data: data, encoding: .utf8)
    print(contents!)
}.resume()

PlaygroundPage.current.needsIndefiniteExecution = true

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