Создайте свой собственный код ошибки в swift 3
Чего я пытаюсь добиться, так это выполнить запрос URLSession в swift 3. Я выполняю это действие в отдельной функции (чтобы не писать код отдельно для GET и POST) и возвращаю URLSessionDataTask и обрабатываю успех и неудачу в замыканиях. Вроде как это-
let task = URLSession.shared.dataTask(with: request) { (data, uRLResponse, responseError) in
DispatchQueue.main.async {
var httpResponse = uRLResponse as! HTTPURLResponse
if responseError != nil && httpResponse.statusCode == 200{
successHandler(data!)
}else{
if(responseError == nil){
//Trying to achieve something like below 2 lines
//Following line throws an error soo its not possible
//var errorTemp = Error(domain:"", code:httpResponse.statusCode, userInfo:nil)
//failureHandler(errorTemp)
}else{
failureHandler(responseError!)
}
}
}
}
Я не хочу обрабатывать условие ошибки в этой функции и хочу генерировать ошибку, используя код ответа, и возвращать эту ошибку, чтобы обработать ее везде, где эта функция вызывается.
Может кто-нибудь скажи мне, как это сделать? Или это не самый "быстрый" способ справиться с подобными ситуациями?
6 ответов:
В вашем случае ошибка заключается в том, что вы пытаетесь создать экземпляр
Error.Errorв Swift 3 есть протокол, который можно использовать для определения пользовательской ошибки. Эта функция особенно подходит для чисто Swift-приложений, работающих на разных ОС.В разработке iOS класс
Таким образом, если ваша цель состоит только в распространении этого кода ошибки, вы можете легко заменитьNSErrorвсе еще доступен и соответствует протоколуError.var errorTemp = Error(domain:"", code:httpResponse.statusCode, userInfo:nil)С
var errorTemp = NSError(domain:"", code:httpResponse.statusCode, userInfo:nil)В противном случае проверьте Sandeep Bhandari ' s Ответ о том, как создать пользовательский тип ошибки
Вы можете создать протокол, соответствующий протоколу Swift
LocalizedError, со следующими значениями:protocol OurErrorProtocol: LocalizedError { var title: String? { get } var code: Int { get } }Это позволяет нам создавать конкретные ошибки, такие как:
struct CustomError: OurErrorProtocol { var title: String? var code: Int var errorDescription: String? { return _description } var failureReason: String? { return _description } private var _description: String init(title: String?, description: String, code: Int) { self.title = title ?? "Error" self._description = description self.code = code } }
Вы можете создавать перечисления для работы с ошибками:)
enum RikhError: Error { case unknownError case connectionError case invalidCredentials case invalidRequest case notFound case invalidResponse case serverError case serverUnavailable case timeOut case unsuppotedURL }И затем создайте метод внутри enum, чтобы получить код ответа http и вернуть соответствующую ошибку в return:)
static func checkErrorCode(_ errorCode: Int) -> RikhError { switch errorCode { case 400: return .invalidRequest case 401: return .invalidCredentials case 404: return .notFound //bla bla bla default: return .unknownError } }Наконец обновите свой блок сбоев, чтобы принять один параметр типа RikhError:)
У меня есть подробное руководство о том, как реструктурировать традиционную объектно-ориентированную сетевую модель на основе Objective-C в современную протокольно-ориентированную модель с использованием Swift3 здесь https://learnwithmehere.blogspot.in посмотрите :)
Надеюсь, это поможет :)
Следует использовать объект NSError.
let error = NSError(domain:"", code:401, userInfo:[ NSLocalizedDescriptionKey: "Invaild access token"])Затем приведите NSError к объекту Error
Реализовать LocalizedError:
Обратите внимание, что простая реализация ошибки, например, как описано в одном из ответов, завершится неудачей (по крайней мере, в Swift 3), а вызов localizedDescription приведет к строке "операция не может быть завершена. (.Ошибка StringError 1.) "struct StringError : LocalizedError { var errorDescription: String? { return mMsg } var failureReason: String? { return mMsg } var recoverySuggestion: String? { return "" } var helpAnchor: String? { return "" } private var mMsg : String init(_ description: String) { mMsg = description } }
Я знаю, что вы уже удовлетворились ответом, но если вам интересно знать правильный подход, то это может быть полезно для вас. Я бы предпочел не смешивать код ошибки http-ответа с кодом ошибки в объекте error (запутался? пожалуйста, продолжайте читать немного...).
Коды ответа http являются стандартными кодами ошибок об ответе http, определяющими общие ситуации, когда ответ получен и изменяется от 1xx до 5xx ( например, 200 OK, 408 запрос тайм-аут, 504 шлюз timeout etc - http://www.restapitutorial.com/httpstatuscodes.html )
Код ошибки в объекте NSError обеспечивает очень специфическую идентификацию вида ошибки, описываемой объектом для конкретной области приложения / продукта / программного обеспечения. Например, ваше приложение может использовать 1000 для "Извините, вы не можете обновить эту запись более одного раза в день" или сказать 1001 для "вам нужна роль менеджера для доступа к этому ресурсу"... которые специфичны для вашего домена / приложения логика.Для очень небольшого приложения иногда эти два понятия объединяются. Но они совершенно разные, как вы можете видеть, и очень важны и полезны для проектирования и работы с большим программным обеспечением.
Таким образом, для лучшей обработки кода можно использовать два метода:
1. Обратный вызов завершения выполнит все проверки
completionHandler(data, httpResponse, responseError)2. Ваш метод решает ситуацию успеха и ошибки, а затем вызывает соответствующий обратный вызов
if nil == responseError { successCallback(data) } else { failureCallback(data, responseError) // failure can have data also for standard REST request/response APIs }Счастливое кодирование :)
Comments