我如何使用 Swift 3 发出 HTTP 请求?

how i can make a HTTP request with Swift 3?

我正在了解 Swift 并且我正在尝试发出 HTTP 请求。我的代码可以正常工作,但我不知道如何 return 请求的结果:

func makeRequest(request: URLRequest)->String{
    let task = URLSession.shared.dataTask(with: request){data, response, error in
        guard let data = data, error == nil else{
            print("error=\(error)")
            return
        }

        if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {           // check for http errors
            print("statusCode should be 200, but is \(httpStatus.statusCode)")
            print("response = \(response)")
        }
        print (data)
        do {
            let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
            print(json)
        } catch {
            print("error serializing JSON: \(error)")
        }
        //print("responseString = \(responseString)")

    }
    task.resume()
    return "Something"//i need to return the json as String
}

有人可以帮助我吗?我正在尝试使用 CompletionHanlder,但我找到的所有示例都是基于 swift 2,这会导致我的代码出错

您无法"return"请求的结果。当您得到结果时,您的 makeRequest 函数已经 return 发送给它的调用者。你应该:

  1. makeRequest 更改为不 return 任何东西,因为没有 点
  2. 用执行的代码替换注释掉的打印语句 responseString 结果。
func makeRequest(request: URLRequest, completion: (result : String?)->() {
    let task = URLSession.shared.dataTask(with: request){data, response, error in
    guard let data = data, error == nil else{
        print("error=\(error)")
        return
    }

    if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {           // check for http errors
        print("statusCode should be 200, but is \(httpStatus.statusCode)")
        print("response = \(response)")
    }
    print (data)
    do {
        let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
            print(json)
        } catch {
            print("error serializing JSON: \(error)")
        }
        completion("yourResultString")
    //print("responseString = \(responseString)")

    }
    task.resume()
}

调用它

makeRequest(request: request) { (result : String?) in 
    if let result = result {
        print("got result: \(result)")
}

完成处理程序的类型需要是这样的:

@escaping ({argument types...})->{result type}

@escaping 是必需的,因为完成处理程序会在通信完成后执行。

{argument types...} 需要是您要传递给处理程序的类型,因此在您的情况下,单个类型 String。而且您通常不使用处理程序的结果,因此您需要指定 Void(又名 ())。

因此您的完成处理程序的类型需要是:

@escaping (String)->Void

因此,您的方法 header 变为:

(您知道参数列表需要一个右括号。)

func makeRequest(request: URLRequest, completion: @escaping (String)->Void)

整个方法应该是这样的:

func makeRequest(request: URLRequest, completion: @escaping (String)->Void) {
    let task = URLSession.shared.dataTask(with: request) {data, response, error in
        guard let data = data, error == nil else{
            print("error=\(error)")
            return
        }

        if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {           // check for http errors
            print("statusCode should be 200, but is \(httpStatus.statusCode)")
            print("response = \(response)")
        }
        print(data as NSData) //<-`as NSData` is useful for debugging
        do {
            let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
            print(json)
            //Why don't you use decoded JSON object? (`json` may not be a `String`)
        } catch {
            print("error serializing JSON: \(error)")
        }
        //Not sure what you mean with "i need to return the json as String"
        let responseString = String(data: data, encoding: .utf8) ?? ""
        completion(responseString)
    }
    task.resume()
}

您可以将其用作:

    makeRequest(request: request) {response in //<-`response` is inferred as `String`, with the code above.
        print(response)
    }