Genere su propio código de error en swift 3


Lo que estoy tratando de lograr es realizar una solicitud URLSession en swift 3. Estoy realizando esta acción en una función separada (para no escribir el código por separado para GET y POST) y devolviendo el URLSessionDataTask y manejando el éxito y el fracaso en closures. Algo así -

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!)
               }
          }
     }
}

No deseo manejar la condición de error en esta función y deseo generar un error usando el código de respuesta y devolver este Error para manejarlo desde donde se llame a esta función. ¿Puede alguien dime cómo hacer esto. O no es esta la manera "Rápida" de manejar tales situaciones?

Author: Rikh, 2016-11-18

6 answers

En su caso, el error es que está tratando de generar una instancia Error. Error en Swift 3 es un protocolo que se puede utilizar para definir un error personalizado. Esta característica es especialmente para aplicaciones Swift puras para ejecutar en diferentes sistemas operativos.

En el desarrollo de iOS la clase NSError todavía está disponible y se ajusta al protocolo Error.

Por lo tanto, si su propósito es solo propagar este código de error, puede reemplazar fácilmente

var errorTemp = Error(domain:"", code:httpResponse.statusCode, userInfo:nil)

Con

var errorTemp = NSError(domain:"", code:httpResponse.statusCode, userInfo:nil)

De lo contrario, compruebe la Sandeep Bhandari ' s respuesta con respecto a cómo crear un tipo de error personalizado

 65
Author: Luca D'Alberti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-04 11:21:23

Puede crear un protocolo, conforme al protocolo Swift LocalizedError, con estos valores:

protocol OurErrorProtocol: LocalizedError {

    var title: String? { get }
    var code: Int { get }
}

Esto entonces nos permite crear errores concretos así:

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
    }
}
 43
Author: Harry Bloom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-18 13:38:46

Puede crear enumeraciones para tratar los errores:)

enum RikhError: Error {
    case unknownError
    case connectionError
    case invalidCredentials
    case invalidRequest
    case notFound
    case invalidResponse
    case serverError
    case serverUnavailable
    case timeOut
    case unsuppotedURL
 }

Y luego cree un método dentro de enum para recibir el código de respuesta http y devolver el error correspondiente:)

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
        }
    }

Finalmente actualice su bloque de falla para aceptar un solo parámetro de tipo RikhError:)

Tengo un tutorial detallado sobre cómo reestructurar el modelo de red orientado a Objetos basado en Objective - C tradicional al modelo orientado a Protocolos moderno usando Swift3 aquí https://learnwithmehere.blogspot.in Echa un vistazo:)

Espero que ayude:)

 31
Author: Sandeep Bhandari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-18 08:10:56

Debe usar el objeto NSError.

let error = NSError(domain:"", code:401, userInfo:[ NSLocalizedDescriptionKey: "Invaild access token"])

Luego cast NSError a Error object

 15
Author: Ahmed Lotfy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-18 15:41:47

Implementar 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
    }
}

Tenga en cuenta que simplemente implementar Error, por ejemplo, como se describe en una de las respuestas, fallará (al menos en Swift 3), y llamar a localizedDescription dará como resultado la cadena "La operación no se pudo completar. (.StringError error 1.)"

 10
Author: prewett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-23 22:52:23

Sé que usted ya ha satisfecho con una respuesta, pero si usted está interesado en saber el enfoque correcto, entonces esto podría ser útil para usted. Preferiría no mezclar el código de error http-response con el código de error del objeto error (¿confundido? por favor, siga leyendo un poco...).

Los códigos de respuesta http son códigos de error estándar sobre una respuesta http que definen situaciones genéricas cuando se recibe una respuesta y varían de 1xx a 5xx ( por ejemplo, 200 OK, 408 Request timed out, 504 Gateway tiempo de espera etc - http://www.restapitutorial.com/httpstatuscodes.html )

El código de error en un objeto NSError proporciona una identificación muy específica para el tipo de error que el objeto describe para un dominio particular de aplicación/producto/software. Por ejemplo, su aplicación puede usar 1000 para "Lo siento, no puede actualizar este registro más de una vez al día" o decir 1001 para "Necesita el rol de administrador para acceder a este recurso"... que son específicos de su dominio / aplicación lógica.

Para una aplicación muy pequeña, a veces estos dos conceptos se fusionan. Pero son completamente diferentes como se puede ver y muy importante y útil para diseñar y trabajar con software grande.

Por lo tanto, puede haber dos técnicas para manejar el código de mejor manera:

1. La devolución de llamada de finalización realizará todas las comprobaciones

completionHandler(data, httpResponse, responseError) 

2. Su método decide la situación de éxito y error y luego invoca la devolución de llamada correspondiente

if nil == responseError { 
   successCallback(data)
} else {
   failureCallback(data, responseError) // failure can have data also for standard REST request/response APIs
}

Feliz codificación :)

 1
Author: Tushar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-18 09:07:30