Программа Swift никогда не входит в CompletionHandler для dataTask

Я занимаюсь внедрением REST API с помощью Swift. Конечно, часть этого API использует HTTP-запросы для получения и отправки данных.

Полное раскрытие, у меня нет опыта работы со Swift, и я использую это как учебный проект, чтобы, так сказать, намочить ноги. Но это оказалось гораздо более трудным проектом, чем я ожидал.

При реализации первого метода get я (наконец) избавился от всех ошибок компиляции. Однако, когда я вызываю функцию, которая использует URLRequest, URLSession, dataTask и т. д., она никогда не вводится.

После отладки программы я могу наблюдать, как выполнение программы достигает CompletionHandler, и пропускать его прямо к «task.resume()».

Аналогичная конструкция работает в Swift Playground, но не работает в самом проекте.

До сих пор я пробовал несколько вещей, а именно предоставление функции доступа к переменной экземпляра класса в надежде, что это заставит ее выполниться. Но это не так.

Я думаю, что проблема может быть связана с синхронностью, и, возможно, мне нужно использовать семафор, но сначала я хочу убедиться, что не упустил ничего очевидного.

import Foundation
/**
 A class to wrap all GET and POST requests, to avoid the necessity of repeatedly writing request code in each API method.
 */
class BasicRequest {
    private var url: URL
    private var header: [String: String]
    private var responseType: String

    private var jsonResponse: Any?


    init(url: URL, header: [String: String], responseType: String) {
        self.url = url
        self.header = header
        self.responseType = responseType
    } //END INIT

    public func requestJSON() -> Any {
        // Create the URLRequest object, and fill the header with the header fields as provided.
        var urlRequest = URLRequest(url: self.url)
        for (value, key) in self.header {
            urlRequest.addValue(value, forHTTPHeaderField: key)
        }

        let task = URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
            print("Entered the completion handler")
            if error != nil {
                return
            }
            guard let httpResponse = response as? HTTPURLResponse, 200 == httpResponse.statusCode else {
                print("HTTP Request unsuccessful")
                return
            }
            guard let mime = response?.mimeType, mime == "application/json" else {
                print("Not a JSON response")
                return
            }
            do {
                let json = try JSONSerialization.jsonObject(with: data!, options: [])
                print(json)
                self.jsonResponse = json
            } catch {
                print("Could not transform to JSON")
                return
            }
        }
        task.resume()

        return "Function has returned"
    } //END REQUESTJSON
}

Ожидаемый результат будет возвращать объект JSON, однако, похоже, это не так.

Что касается сообщений об ошибках, я их не получаю. Единственный журнал, который я получаю в отладчике, — это шаблонный «процесс завершен с кодом 0».

Честно говоря, я в недоумении, почему это не работает.


person Catradora    schedule 22.07.2019    source источник


Ответы (1)


Похоже, вы пишете это в приложении командной строки. В этом случае программа завершается до завершения URLRequest.

Я думаю, что проблема может быть связана с синхронностью, и, возможно, мне нужно использовать семафор, но сначала я хочу убедиться, что не упустил ничего очевидного.

Точно.

Типичным инструментом в Swift является DispatchGroup, который представляет собой семафор более высокого уровня. Вызовите dispatchGroup.enter() перед запуском запроса и все dispatchGroup.leave() в конце обработчика завершения. В свой код вызова включите dispatchGroup.wait(), чтобы дождаться его. (Если это неясно, я могу добавить для него код, но вы также можете найти много ответов SO, которые продемонстрируют это.)

person Rob Napier    schedule 22.07.2019
comment
Звучит идеально, я попробую. Большое спасибо! - person Catradora; 22.07.2019