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

Swift 如何使用URLSession在异步api调用中查找哪个响应属于哪个请求,swift,asynchronous,request,response,nsurlsession,Swift,Asynchronous,Request,Response,Nsurlsession,我正在使用URLSession从iPhone应用程序中的API获取响应。在我的例子中,我使用异步api调用一次处理10个相同api的请求,并且得到所有请求的响应。现在,从这些响应中,我如何找到哪个响应属于哪个请求?感谢您的帮助。您有很多方法可以实现这一点 1-基本上,如果您使用标识符调用客户端函数,您将能够在完成块中检索它: func call(with identifier: String, at url: URL) { URLSession.shared.dataTask(url:

我正在使用
URLSession
从iPhone应用程序中的
API
获取响应。在我的例子中,我使用异步api调用一次处理10个相同api的请求,并且得到所有请求的响应。现在,从这些响应中,我如何找到哪个响应属于哪个请求?感谢您的帮助。

您有很多方法可以实现这一点

1-基本上,如果您使用标识符调用客户端函数,您将能够在完成块中检索它:

func call(with identifier: String, at url: URL) {
    URLSession.shared.dataTask(url: url) { (_, _, _) in
        print(identifier)
    }.resume()
}
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)
    }
}
2-您还可以使用
URLSessionDataTask
的任务标识符。但要执行此操作,您需要使用自定义
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 call(with identifier: String, at url: URL) {
    URLSession.shared.dataTask(url: url) { (_, _, _) in
        print(identifier)
    }.resume()
}
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"

你有很多方法来实现这一点

1-基本上,如果您使用标识符调用客户端函数,您将能够在完成块中检索它:

func call(with identifier: String, at url: URL) {
    URLSession.shared.dataTask(url: url) { (_, _, _) in
        print(identifier)
    }.resume()
}
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)
    }
}
2-您还可以使用
URLSessionDataTask
的任务标识符。但要执行此操作,您需要使用自定义
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 call(with identifier: String, at url: URL) {
    URLSession.shared.dataTask(url: url) { (_, _, _) in
        print(identifier)
    }.resume()
}
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"

是否要包括到目前为止尝试过的代码?是否要包括到目前为止尝试过的代码?