Как найти, какой ответ принадлежит какому запросу в вызове Async API, используя URLSession

Я использую URLSession чтобы получить ответ от API's в моем приложении для iPhone. В моем случае я выполняю около 10 запросов одного и того же API за раз, используя асинхронный вызов API, и я получаю ответ на все запросы. Теперь из этих ответов, как я могу найти, какой ответ принадлежит какому запросу? Любая помощь приветствуется.

1 ответ

У вас есть много способов достичь этого.

1 - По сути, если вы вызываете свою клиентскую функцию с идентификатором, вы сможете получить ее в своем блоке завершения:

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

2 - Вы также можете использовать taskIdentifier 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 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"
Другие вопросы по тегам