Создайте свой собственный код ошибки в 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!)
}
}
}
}


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

708   6  

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:

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
    }
}
Обратите внимание, что простая реализация ошибки, например, как описано в одном из ответов, завершится неудачей (по крайней мере, в Swift 3), а вызов localizedDescription приведет к строке "операция не может быть завершена. (.Ошибка StringError 1.) "

Я знаю, что вы уже удовлетворились ответом, но если вам интересно знать правильный подход, то это может быть полезно для вас. Я бы предпочел не смешивать код ошибки 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

    Ничего не найдено.