简体   繁体   English

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

[英]how i can make a HTTP request with Swift 3?

Im learning about Swift and i trying to make an HTTP request. 我正在学习Swift,并尝试发出HTTP请求。 My code is working but i dont know how to return the result of the request: 我的代码正在运行,但我不知道如何返回请求的结果:

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
}

Someone can help me please? 有人可以帮帮我吗? i was trying using CompletionHanlder but all the example that i found is based on swift 2, and this causes error on my code 我正在尝试使用CompletionHanlder,但我找到的所有示例都基于swift 2,这会导致我的代码出错

在此输入图像描述

The completion handler's type needs to be something like this: 完成处理程序的类型必须是这样的:

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

@escaping is needed as the completion handler is executed later when the communication is completed. 需要@escaping ,因为稍后在通信完成时执行完成处理程序。

{argument types...} needs to be the types you want to pass to the handler, so in your case, a single type String . {argument types...}需要是您要传递给处理程序的类型,因此在您的情况下,单个类型为String And you usually do not use the result from the handler, so you need to specify Void (aka () ). 而且您通常不使用处理程序的结果,因此您需要指定Void (aka () )。

Thus your completion handler's type needs to be: 因此,您的完成处理程序的类型需要是:

@escaping (String)->Void

So, your method header becomes: 因此,您的方法标题变为:

(You know you need a closing parenthesis for argument list.) (你知道你需要一个右括号用于参数列表。)

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

Whole your method would be something like this: 整个你的方法将是这样的:

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()
}

You can use it as: 您可以将其用作:

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

to call it 打电话给它

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

You can't "return" the result of the request. 您无法“返回”请求的结果。 By the time you have a result your makeRequest function has already returned to its caller. 当你有结果时,你的makeRequest函数已经返回给它的调用者。 You should: 你应该:

  1. Change makeRequest to not return anything, because there's no point 改变makeRequest不返回任何东西,因为没有意义
  2. Replace the commented-out print statement with code that does something with the responseString result. 将注释掉的print语句替换为对responseString结果执行某些操作的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM