responses headers example swift alamofire

example - swift alamofire headers



Patrón de Singleton y uso adecuado de URLRequestConvertible de Alamofire (1)

Estas son algunas preguntas realmente buenas. Déjame intentar responder a cada uno a su vez.

¿Creo un enrutador de enumeración que implemente URLRequestConvertible para cada modelo en mi capa de modelo?

Esta es una gran pregunta y desafortunadamente no hay una respuesta perfecta. Ciertamente, hay algunas formas en que podría extender el patrón de Router para acomodar múltiples tipos de objetos. La primera opción sería agregar más casos para admitir otro tipo de objeto. Sin embargo, esto se vuelve peludo rápidamente cuando se obtienen más de 6 o 7 casos. Sus instrucciones de cambio solo comienzan a salirse de control. Por lo tanto, no recomendaría este enfoque.

Otra forma de abordar el problema es mediante la introducción de genéricos en el Router .

Protocolo RouterObject

protocol RouterObject { func createObjectPath() -> String func readObjectPath(identifier: String) -> String func updateObjectPath(identifier: String) -> String func destroyObjectPath(identifier: String) -> String }

Objetos modelo

struct User: RouterObject { let rootPath = "/users" func createObjectPath() -> String { return rootPath } func readObjectPath(identifier: String) -> String { return "/(rootPath)//(identifier)" } func updateObjectPath(identifier: String) -> String { return "/(rootPath)//(identifier)" } func destroyObjectPath(identifier: String) -> String { return "/(rootPath)//(identifier)" } } struct Company: RouterObject { let rootPath = "/companies" func createObjectPath() -> String { return rootPath } func readObjectPath(identifier: String) -> String { return "/(rootPath)//(identifier)" } func updateObjectPath(identifier: String) -> String { return "/(rootPath)//(identifier)" } func destroyObjectPath(identifier: String) -> String { return "/(rootPath)//(identifier)" } } struct Location: RouterObject { let rootPath = "/locations" func createObjectPath() -> String { return rootPath } func readObjectPath(identifier: String) -> String { return "/(rootPath)//(identifier)" } func updateObjectPath(identifier: String) -> String { return "/(rootPath)//(identifier)" } func destroyObjectPath(identifier: String) -> String { return "/(rootPath)//(identifier)" } }

Enrutador

let baseURLString = "http://example.com" var OAuthToken: String? enum Router<T where T: RouterObject>: URLRequestConvertible { case CreateObject(T, [String: AnyObject]) case ReadObject(T, String) case UpdateObject(T, String, [String: AnyObject]) case DestroyObject(T, String) var method: Alamofire.Method { switch self { case .CreateObject: return .POST case .ReadObject: return .GET case .UpdateObject: return .PUT case .DestroyObject: return .DELETE } } var path: String { switch self { case .CreateObject(let object, _): return object.createObjectPath() case .ReadObject(let object, let identifier): return object.readObjectPath(identifier) case .UpdateObject(let object, let identifier, _): return object.updateObjectPath(identifier) case .DestroyObject(let object, let identifier): return object.destroyObjectPath(identifier) } } // MARK: URLRequestConvertible var URLRequest: NSMutableURLRequest { let URL = NSURL(string: baseURLString)! let mutableURLRequest = NSMutableURLRequest(URL: URL.URLByAppendingPathComponent(path)) mutableURLRequest.HTTPMethod = method.rawValue if let token = OAuthToken { mutableURLRequest.setValue("Bearer /(token)", forHTTPHeaderField: "Authorization") } switch self { case .CreateObject(_, let parameters): return Alamofire.ParameterEncoding.JSON.encode(mutableURLRequest, parameters: parameters).0 case .UpdateObject(_, _, let parameters): return Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: parameters).0 default: return mutableURLRequest } } }

Ejemplo de uso

func exampleUsage() { let URLRequest = Router.CreateObject(Location(), ["address": "1234 Road of Awesomeness"]).URLRequest Alamofire.request(URLRequest) .response { request, response, data, error in print(request) print(response) print(data) print(error) } }

Ahora hay algunas compensaciones que tienes que hacer aquí. En primer lugar, los objetos de su modelo deben cumplir con el protocolo RouterObject . De lo contrario, el Router no tiene idea de qué usar para la ruta. Además, deberá asegurarse de que todas sus rutas se puedan construir con un solo identifier . Si no pueden, este diseño podría no funcionar. El último problema es que no puede almacenar la baseURL o el OAuthToken directamente dentro de la enumeración del Router . Desafortunadamente, las propiedades estáticas y almacenadas todavía no son compatibles en las enumeraciones genéricas.

En cualquier caso, esta sería una forma válida de evitar tener que crear un Router para cada objeto modelo.

¿ Alamofire.Manager.sharedInstance usarse Alamofire.Manager.sharedInstance como mi instancia de NetworkManager singleton?

Ciertamente podría ser utilizado de esa manera. Realmente depende de su caso de uso y de cómo haya diseñado su acceso a la red. También depende de cuántos tipos diferentes de sesiones necesites. Si necesita sesiones en segundo plano y sesiones predeterminadas, es probable que aún necesite el concepto de un NetworkManager que contenga cada instancia de Manager personalizada. Sin embargo, si está llegando a la red con una sesión predeterminada, probablemente la sharedInstance sea ​​suficiente.

¿Cómo podría baseURL la baseURL del Alamofire singleton junto con el patrón Router ?

Buena pregunta ... el siguiente código es un ejemplo de cómo se podría hacer.

Extensión de Alamofire Manager

extension Manager { static let baseURLString = "http://example.com" static var OAuthToken: String? }

Router URLRequestConvertible Actualizaciones

var URLRequest: NSMutableURLRequest { let URL = NSURL(string: Alamofire.Manager.baseURLString)! let mutableURLRequest = NSMutableURLRequest(URL: URL.URLByAppendingPathComponent(path)) mutableURLRequest.HTTPMethod = method.rawValue if let token = Alamofire.Manager.OAuthToken { mutableURLRequest.setValue("Bearer /(token)", forHTTPHeaderField: "Authorization") } switch self { case .CreateObject(_, let parameters): return Alamofire.ParameterEncoding.JSON.encode(mutableURLRequest, parameters: parameters).0 case .UpdateObject(_, _, let parameters): return Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: parameters).0 default: return mutableURLRequest } }

Esperemos que eso ayude a arrojar algo de luz. ¡La mejor de las suertes!

Esta es una pregunta de 2 partes, la primera es similar a esta pregunta aquí: Uso correcto de URLRequestConvertible de Alamofire . ¡Pero necesito un poco más de ayuda!

1) ¿Creo un enrutador de enumeración que implemente URLRequestConvertible para cada modelo en mi capa de modelo?

La página de github de alamofire proporciona un ejemplo de un enrutador que he copiado aquí:

enum Router: URLRequestConvertible { static let baseURLString = "http://example.com" static var OAuthToken: String? case CreateUser([String: AnyObject]) case ReadUser(String) case UpdateUser(String, [String: AnyObject]) case DestroyUser(String) var method: Alamofire.Method { 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)" } } // MARK: URLRequestConvertible var URLRequest: NSURLRequest { let URL = NSURL(string: Router.baseURLString)! let mutableURLRequest = NSMutableURLRequest(URL: URL.URLByAppendingPathComponent(path)) mutableURLRequest.HTTPMethod = method.rawValue if let token = Router.OAuthToken { mutableURLRequest.setValue("Bearer /(token)", forHTTPHeaderField: "Authorization") } switch self { case .CreateUser(let parameters): return Alamofire.ParameterEncoding.JSON.encode(mutableURLRequest, parameters: parameters).0 case .UpdateUser(_, let parameters): return Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: parameters).0 default: return mutableURLRequest } } }

Cuando miro esto (soy nuevo en swift, por favor tenga paciencia conmigo> _ <) Veo operaciones en un objeto de usuario; están creando un usuario, actualizando un usuario, etc. Entonces, si tuviera una persona, empresa, ubicación de objetos modelo en mi capa de modelo, ¿crearía un enrutador para cada objeto modelo?

2) Cuando interactúo en gran medida con una API, estoy acostumbrado a crear un singleton de "administrador de red" para abstraer la capa de red y mantener los encabezados y la baseurl para esa API. El alamofire tiene un "administrador" descrito aquí:

Los métodos de conveniencia de nivel superior como Alamofire.request utilizan una instancia compartida de Alamofire.Manager, que está configurada con la configuración predeterminada de NSURLSessionConfiguration. Como tal, las siguientes dos afirmaciones son equivalentes:

Alamofire.request(.GET, "http://httpbin.org/get") let manager = Alamofire.Manager.sharedInstance manager.request(NSURLRequest(URL: NSURL(string: "http://httpbin.org/get")))

¿Es este administrador lo que debería usar como mi singleton? Si es así, ¿cómo configuro la baseurl en el administrador? Además, si uso este administrador, ¿esto puede / puede funcionar junto con la construcción del enrutador que se muestra arriba (con cada configuración de objeto modelo es baseurl y NSURLRquest)? Si es así, ¿puedes dar un ejemplo simple?

Soy nuevo en la biblioteca de Alamofire y rápido. Entonces, sé que hay muchos agujeros en mi comprensión, ¡pero solo estoy tratando de entender lo mejor que puedo! Cualquier información ayuda. Gracias.