linkedin

Hay momentos en la vida de todos en los que sabemos que debemos sentarnos y hacer algo desagradable por nuestro propio bien: preparar una declaración de la renta, hacer un perfil de OkCupid, borrar un perfil de OkCupid, afeitarnos los dedos de los pies, etc. Obligarse a aprender una nueva API puede parecer igual de poco divertido, pero a menudo hay que hacerlo.

ASIHTTPRequest. ¿Qué puedo decir? No tengo ningún problema con ella. Me encanta. Es simple y me permite crear rápidamente código que envía peticiones HTTP en sólo unas pocas líneas. Aquí hay un ejemplo donde envío un Post y un File:

ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:remoteUrl]; [request setPostValue:self.fileName.text forKey:@"name"]; [request setFile:filePath forKey:@"filename"]; [request setDelegate:self]; [request startAsynchronous];

Esto me encanta: establezco el valor Post y su clave, establezco el File y su clave, me hago un delegado y ¡comienzo la subida! El protocolo me avisa cuando ha terminado y puedo seguir adelante.

Tristemente, ASIHTTPRequest fue escrito por un hombre que se cansó de lidiar con sus fanáticos y críticos gritones. Así que decidió abandonar el proyecto. Tal es la bendición/problema de los proyectos de código abierto: son libres/tenuinos. Aunque el código sigue existiendo (y sigue funcionando), no lo actualizará para ninguna versión futura de iOS. Incluso dijo en su blog que era hora de que todos siguiéramos adelante. Entra AFNetworking.

La buena gente de Gowalla (antes Alamofire) ha creado una API de solicitud HTTP que mucha gente está empezando a utilizar. Pero quiero decir empezando. Es realmente nueva. Incluso me he asomado al código de otra persona que he visto que implementaba la librería de AFNetworking para ver cómo la usaban; no están tho. La incluyeron y la abandonaron para seguir usando ASIHTTPRequest. :)

Así que en cuanto a la documentación todavía no hay mucho por ahí. Esto me deja en la posición de tener que enseñar a mí mismo.

Primera tarea: Instalar la documentación de AFNetworking en Xcode

Una de las mejores herramientas de Xcode es su capacidad para mostrarte la documentación de un elemento en dos clics. Para mi gran sorpresa, descubrí que también se puede instalar la documentación de APIs de terceros si la proporcionan, como hace Gowalla. Pero primero debes adquirir una herramienta llamada appledoc e instalarla. Viene como un proyecto Xcode E incluye un script de instalación. Así que si usted utiliza que usted estará en la calle fácil. Luego sigue las instrucciones de Gowalla para instalar su documentación desde GitHub. Ahora, cuando necesites documentación para una clase, método, etc. de AFNetworking, ¡estará disponible en el mismo lugar que la documentación de la Fundación Apple!

Will-Code-Img_0.png

Segunda tarea: Poner en marcha la carga de archivos

Ahora, esto fue difícil. El código necesario para hacer lo mismo que arriba es mucho más largo (no veo cómo esto es una ventaja. Me gustan las cosas sucintas.)

AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:remoteUrl]; NSMutableURLRequest *afRequest = [httpClient multipartFormRequestWithMethod:@"POST" path:@"/fotos" parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) { [formData appendPartWithFileData:photoImageData name:self.fileName.text fileName:[NSString stringWithFormat:@"%@.jpg", self.fileName.text] mimeType:@"image/jpeg"]; } ]; AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:afRequest]; [operation setUploadProgressBlock: ^(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite) { NSLog(@"Enviado %d de %d bytes", totalBytesWritten, totalBytesExpectedToWrite); } ]; NSOperationQueue *queue = [[NSOperationQueue alloc] init]; [queue addOperation:operation]; [self takeADeepBreath];

Vale. Ese código es una locura difícil de leer a simple vista. Desglosémoslo.

AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:remoteUrl];

Esto inits una nueva instancia del objeto AFHTTPClient que es donde a menudo se hace el trabajo pesado en esta API. Tenga en cuenta el método de conveniencia para poner en la URL en su inicialización. Pero también note que esta es la URL base. Esto nos permite hacer llamadas fáciles a otras URLs relativas que necesitemos simplemente añadiendo el /[directorio].

NSMutableURLRequest *afRequest = [httpClient

Tiene sentido. Eso es lo que realmente estamos haciendo: Hacer peticiones URL. Aquí usamos nuestra instancia de AFHTTPClient para empezar a sacar la información que queremos poner en nuestra petición.

multipartFormRequestWithMethod:@"POST" path:@"/photos"

Vamos a publicar en el directorio web de fotos que es uno de nuestra URL base. También podríamos Put o Delete.

parámetros:nil

Esto todavía no lo sé. Que alguien me mande un email y me lo diga :)

constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {

“BLOQUES!!!!!?????” Sí. Bloques. Es hora de hacerse un hombre y usar un bloque. Y ahora que lo he hecho, ya no tengo miedo. Me parece que los bloques funcionan como pequeñas funciones dentro de métodos. Supongo que esto nos ahorra un poco de espacio al no tener que declararlos, etc. Pero son muy intimidantes. Especialmente cuando no te los enseñan en los cursos de introducción al iPhone.

Imagina un bloque así: es una función que puede ser llamada como argumento. Cuando lo digo así, ¡suena REALMENTE útil!

Después de los dos puntos se pone una zanahoria (^) para definir el principio del bloque. Le sigue el tipo de retorno (en este caso una instancia del objeto AFMultipartFormData llamada formData. Abre una llave y empieza la función

formData appendPartWithFileData:photoImageData name:self.fileName.text fileName:[NSString stringWithFormat:@”%@.jpg”, self.fileName.text] mimeType:@”image/jpeg”];`

Un mensaje y terminamos con este. Pero espera. ¿Cómo es que estamos utilizando el retorno en la función? Bueno, tal vez ‘retorno’ es la palabra equivocada. ¿Lo que realmente es un argumento? ¿Un argumento que es rellenado por el método que lo llama? Oy. …

formData es una instancia de AFMultipartFormData que el método nos da para jugar en el bloque (glibly.) Y en este caso estamos tomando esa instancia y rellenándola con los datos que queremos enviar en nuestro cuerpo HTTP:

el archivo (en este caso una foto),

el valor de la clave ‘name’ (que estoy extrayendo de un UITextField) y

la clave ‘fileName’ (que aquí es sólo el ‘nombre’ con una extensión.

}

];

¡Ahora cierra ese bloque Y el mensaje original!

Si lo miras así, ya tenemos nuestra petición HTTP Post lista para funcionar. En ASIHTTP sólo tendrías que decirle startSynchronous o startAsynchronous para ponerlo en marcha. Aquí debemos aceptar que las buenas aplicaciones hacen uso de Grand Central Dispatch.

AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:afRequest];

AFHTTPRequestOperation hereda de AFURLConnectionOperation que a su vez hereda de NSOperation. NSOperation es la clase que nos permite encapsular tareas individuales y pasarlas a los procesadores con más control. Podemos tomar tareas y ponerlas en cola por hilos y el compilador o el sistema operativo o algo realmente sabe en qué núcleo del procesador ponerlas para que puedan ejecutarse simultáneamente

Los beneficios de esto son obvios: pásalo a un núcleo para que otras tareas se detengan esperando a que se agote el tiempo de espera de tu URL rota o a que tu enorme archivo se cargue a través de Edge. Cuando se utiliza correctamente, puede evitar bloqueos relacionados con HTTP en su aplicación.

[operación setUploadProgressBlock: ^(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite) { NSLog(@"Enviado %d de %d bytes", totalBytesWritten, totalBytesExpectedToWrite); } ];

¡ALERTA DE BLOQUEO! Pero vuelve a ser útil. Este bloque analiza nuestro progreso de subida por nosotros y nos da los datos para que hagamos con ellos lo que queramos. Desglosémoslo: nos da 3 ints con los que jugar:

bytesWritten, totalBytesWritten, y totalBytesExpectedToWrite

¿Quieres hacer una barra de progreso? Este es su modelo Este bloque se ejecuta CADA VEZ QUE SE ENVÍA UN PAQUETE dándonos variables útiles constantemente actualizadas. (¡Realmente estoy empezando a amar estas cosas!)

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

Resulta que no puedes poner estas NSOperations directamente a trabajar. Tienes que ponerlas en una NSOperationQueue. Ojalá no tuvieras que hacerlo. Ojalá pudieras enviarles un mensaje de inicio y que se pusieran en marcha. Quizás algún día.

[cola addOperation:operación];

¡Compilar y listo! Observa cómo tu aplicación publica una imagen.

Si está buscando la solución para sustituir ASHttpRequest por AFNetworking, ¡póngase en contacto con nosotros hoy mismo!

¿Necesita más ayuda?

¿Crees que podría ser el momento de traer ayuda adicional?

Door3.com