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

标签 swift asynchronous request response nsurlsession

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

最佳答案

您有很多方法可以实现这一目标。

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

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

2 - 您还可以使用 URLSessionDataTask 的任务标识符。但为此,您需要使用自定义 URLSession 的委托(delegate):

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

那么你将不会使用完成 block ,而是使用委托(delegate)函数:

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

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

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

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"

关于swift - 如何使用 URLSession 在异步 api 调用中查找哪个响应属于哪个请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53519430/

相关文章:

ios - Xcode 10 - 无法本地化 UINavigationController 标题

javascript - 按 Node 下载图像(请求)

ruby-on-rails - 在 Rails 应用中检测 iframe 请求

javascript - Promise是一种实现异步编程的技术吗?

kotlin - 为什么我不能使用try/catch来捕获Kotlin协程中的异常?

android - Android 中的 Http get 请求

ios - 使用 RxSwift 分配属性

ios - 我怎样才能用单个标记多次敲击

swift - 根据其他下拉选择项更改下拉选项(swift 3)

c# - 如何调用嵌套的异步方法