Grandes preguntas. Analicemos cada uno individualmente.
¿Cuál es el uso adecuado de URLRequestConvertible en la API del mundo real?
El URLRequestConvertible
protocolo es una forma ligera de garantizar que un objeto dado pueda crear un archivo NSURLRequest
. Realmente no existe un conjunto estricto de reglas o pautas que lo obliguen a usar este protocolo de una manera particular. Es simplemente un protocolo de conveniencia para permitir que otros objetos almacenen el estado requerido para crear correctamente el NSURLRequest
. Puede encontrar más información relacionada con Alamofire aquí .
¿Debo crear un enrutador por punto final?
Definitivamente no. Eso frustraría todo el propósito de usar un Enum
. Los objetos Swift Enum son increíblemente poderosos y te permiten compartir una gran cantidad de estados comunes y activar las partes que realmente son diferentes. ¡Poder crear un NSURLRequest
con algo tan simple como lo siguiente es realmente poderoso!
let URLRequest: NSURLRequest = Router.ReadUser("cnoon")
No puedo entender por qué se usa enum para construir enrutadores. ¿Por qué no usamos clases con métodos estáticos?
Se utiliza una enumeración porque es una forma mucho más concisa de expresar varios objetos relacionados en una interfaz común. Todos los métodos se comparten entre todos los casos. Si usó métodos estáticos, tendría que tener un método estático para cada caso para cada método. O tendría que usar una enumeración de estilo Obj-C dentro del objeto. He aquí un ejemplo rápido de lo que quiero decir.
enum Router: URLRequestConvertible {
static let baseURLString = "http://example.com"
case CreateUser([String: AnyObject])
case ReadUser(String)
case UpdateUser(String, [String: AnyObject])
case DestroyUser(String)
var method: Alamofire.HTTPMethod {
switch self {
case .CreateUser:
return .post
case .ReadUser:
return .get
case .UpdateUser:
return .put
case .DestroyUser:
return .delete
}
}
var path: String {
switch self {
case .CreateUser:
return "/users"
case .ReadUser(let username):
return "/users/\(username)"
case .UpdateUser(let username, _):
return "/users/\(username)"
case .DestroyUser(let username):
return "/users/\(username)"
}
}
}
Para obtener el método de cualquiera de los diferentes puntos finales, puede llamar al mismo método sin tener que pasar ningún parámetro para definir qué tipo de punto final está buscando, ya lo maneja el caso que seleccione.
let createUserMethod = Router.CreateUser.method
let updateUserMethod = Router.UpdateUser.method
O si desea obtener la ruta, los mismos tipos de llamadas.
let updateUserPath = Router.UpdateUser.path
let destroyUserPath = Router.DestroyUser.path
Ahora intentemos el mismo enfoque usando métodos estáticos.
struct Router: URLRequestConvertible {
static let baseURLString = "http://example.com"
static var method: Method {
}
static func methodForEndpoint(endpoint: String) -> Method {
}
static var path: String {
}
static func pathForEndpoint(endpoint: String) -> String {
}
static var pathForCreateUser: String {
return "/create/user/path"
}
static var pathForUpdateUser: String {
return "/update/user/path"
}
}
NOTA: Si no tiene muchas propiedades o funciones que activen los casos, entonces una enumeración no presenta muchas ventajas sobre una estructura. Es simplemente un enfoque alternativo con diferente azúcar sintáctico.
Las enumeraciones pueden maximizar la reutilización del código y el estado. Los valores asociados también le permiten hacer cosas realmente poderosas como agrupar objetos que son algo similares, pero tienen requisitos increíblemente diferentes ... como la NSURLRequest
creación.
¿Cuál es la forma correcta de construir parámetros para casos de enumeración para mejorar la legibilidad? (tuve que triturar este juntos)
Esa es una excelente pregunta. Ya ha presentado dos opciones posibles. Permítanme agregar un tercio que puede satisfacer sus necesidades un poco mejor.
case CreateUser(username: String, firstName: String, lastName: String, email: String)
case ReadUser(username: String)
case UpdateUser(username: String, firstName: String, lastName: String, email: String)
case DestroyUser(username: String)
En los casos en los que tenga valores asociados, creo que puede ser útil agregar nombres explícitos para todos los valores en la tupla. Esto realmente ayuda a construir el contexto. La desventaja es que luego debe volver a declarar esos valores en sus declaraciones de cambio de esa manera.
static var method: String {
switch self {
case let CreateUser(username: username, firstName: firstName, lastName: lastName, email: email):
return "POST"
default:
return "GET"
}
}
Si bien esto le brinda un contexto agradable y consistente, se vuelve bastante detallado. Esas son sus tres opciones en este momento en Swift, cuál es la correcta para usar depende de su caso de uso.
Actualizar
Con el lanzamiento de 🔥🔥 Alamofire 4.0 🔥🔥, URLRequestConvertible
ahora puede ser MUCHO más inteligente y también puede lanzar. Hemos agregado soporte completo en Alamofire para manejar solicitudes no válidas y generar errores sensibles a través de los controladores de respuesta. Este nuevo sistema está documentado en detalle en nuestro README .
case
declaraciones. Eso me parece un método enorme. No estoy seguro de si eso llevará al código legible ...