Как бросить внутрь замыкания в функцию? - PullRequest
2 голосов
/ 08 апреля 2019

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

Я хотел, чтобы эта функция выдавала, поэтому я мог просто использовать do catch для обработки ошибок или успехадело с разными типами.

Это моя функция:

func performRequest<T: Codable>(_ request: URLRequest, ofType: T.Type) throws -> T{
    URLSession.shared.dataTask(with: request) {(data, response, err) in
        if let err = err {throw err}
        if let response = response as? HTTPURLResponse {
            if response.statusCode != 200 {
                // Here I would return the value
            } else {
                // here I would throw the error
            }
        }
        }.resume()
}

Но в первой строке после URLSession.shared.dataTask я получил эту ошибку:

Неверное преобразованиеот бросающей функции типа '(_, _, _) throws -> ()' к непрокидывающему типу функции (Data ?, URLResponse ?, Error?) -> Void '

IЯ понимаю, что это потому, что я пытаюсь добавить функцию dataTask, но у меня вопрос, есть ли способ сделать это?

1 Ответ

1 голос
/ 08 апреля 2019

Ваш звонок асинхронный. Вы должны вернуть данные в течение закрытия после получения данных. Для проверки, успешно ли выполнен вызов, вы можете использовать недавно введенный тип Result, поэтому вам не нужно throw

func performRequest<T: Codable>(_ request: URLRequest, completion: @escaping (Result<T, Error>) -> Void) {
    URLSession.shared.dataTask(with: request) { (data, response, err) in
        if let err = err {
            return completion(Result.failure(err))
        }
        if let response = response as? HTTPURLResponse {
            if response.statusCode == 200 { // 200 is code for OK btw
                return completion(Result.success(someValueOfTypeT))
            } else {
                return completion(Result.failure(yourError))
            }
        }
    }.resume()
}

Использование: (обратите внимание, что тип T может быть выведен из объявления закрытия)

performRequest(someRequest) { (result: Result<SomeTypeConformsToCodable, Error>) in
    switch result {
    case .success(let value):
        // work with value
    case .failure(let err):
        print(err)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...