如何使用URLSession在异步api调用中查找哪个响应属于哪个请求

时间:2018-11-28 12:24:48

标签: swift asynchronous request response nsurlsession

我正在使用URLSession从我的iPhone应用程序中的API's获得响应。就我而言,我一次使用异步API调用了大约10个相同api的请求,并且得到了所有请求的响应。现在,从这些响应中,我如何找到哪个响应属于哪个请求?任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:2)

您可以通过多种方式实现这一目标。

1-基本上,如果您使用标识符调用客户端函数,则可以在完成代码块中对其进行检索:

func call(with identifier: String, at url: URL) {
    URLSession.shared.dataTask(url: url) { (_, _, _) in
        print(identifier)
    }.resume()
}

2-您也可以使用URLSessionDataTask的taskIdentifier。但是,为此,您将需要使用自定义URLSession的委托:

self.session = URLSession(configuration: URLSessionConfiguration.default,
                          delegate: self,
                          delegateQueue: nil)

然后,您将不使用完成块,而是使用委托函数:

func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
    print(dataTask.taskIdentifier)
}

(当然,您需要知道为哪个URLSessionDataTask设置了哪个任务标识符)

3-如果需要从完成区访问标识符,则可以编写一个函数,它将在默认完成区的参数列表中出现:

func dataTask(session: URLSession,
              url: URL,
              identifier: String,
              completionBlock: @escaping (String, Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask {
    return session.dataTask(with: url) { (data, response, error) in
        completionBlock(identifier, data, response, error)
    }
}

4-如果需要在URLSessionDataTask对象中具有自定义标识符,则可以使用扩展名和关联的对象添加它:

extension URLSessionDataTask {
    var identifier: String? {
        get {
            let identifier = objc_getAssociatedObject(self, &kIdentiferId)
            if let id = identifier as? String {
                return id
            } else {
                return nil
            }
        }
        set {
            objc_setAssociatedObject(self, &kIdentiferId, newValue, .OBJC_ASSOCIATION_RETAIN)
        }
    }
}

private var kIdentiferId: Int8 = 100

然后您可以像这样使用它:

let task = session.dataTask(url: url)
task.identifier = "hello"