ios - afhttprequestoperation - afnetworking 3
Se busca: ejemplo actualizado para JSON/POST con autenticación básica usando AFNetworking-2 (1)
ACTUALIZACIÓN: Se encontró que la parte JSON de lo siguiente funciona para PUT / POST, pero NO para GET / HEAD / DELETE
Después de algunas discusiones, y ayuda fuera de SO, conseguí algo que funcionaba, que quería dejar como recuerdo. Al final, me impresionó mucho AFNetworking-2. Era tan simple que intentaba hacerlo más difícil de lo que debería haber sido. Dado un método jsonDict
que devuelve el paquete json para enviar, creé lo siguiente:
- (void) submitAuthenticatedRest_PUT
{
// it all starts with a manager
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
// in my case, I''m in prototype mode, I own the network being used currently,
// so I can use a self generated cert key, and the following line allows me to use that
manager.securityPolicy.allowInvalidCertificates = YES;
// Make sure we a JSON serialization policy, not sure what the default is
manager.requestSerializer = [AFJSONRequestSerializer serializer];
// No matter the serializer, they all inherit a battery of header setting APIs
// Here we do Basic Auth, never do this outside of HTTPS
[manager.requestSerializer
setAuthorizationHeaderFieldWithUsername:@"basic_auth_username"
password:@"basic_auth_password"];
// Now we can just PUT it to our target URL (note the https).
// This will return immediately, when the transaction has finished,
// one of either the success or failure blocks will fire
[manager
PUT: @"https://101.202.303.404:5555/rest/path"
parameters: [self jsonDict]
success:^(AFHTTPRequestOperation *operation, id responseObject){
NSLog(@"Submit response data: %@", responseObject);} // success callback block
failure:^(AFHTTPRequestOperation *operation, NSError *error){
NSLog(@"Error: %@", error);} // failure callback block
];
}
3 instrucciones de configuración, seguidas de 2 mensajes enviados, realmente es así de fácil.
EDITAR / AÑADIR: Aquí hay un ejemplo de implementación de @jsonDict:
- (NSMutableDictionary*) jsonDict
{
NSMutableDictionary *result = [[NSMutableDictionary alloc] init];
result[@"serial_id"] = self.serialID;
result[@"latitude"] = [NSNumber numberWithDouble: self.location.latitude];
result[@"longitude"] = [NSNumber numberWithDouble: self.location.longitude];
result[@"name"] = self.name;
if ([self hasPhoto])
{
result[@"photo-jpeg"] = [UIImageJPEGRepresentation(self.photo, 0.5)
base64EncodedStringWithOptions: NSDataBase64Encoding76CharacterLineLength];
}
return result;
}
Simplemente debe devolver un diccionario con claves de cadena y objetos simples como valores (NSNumber, NSString, NSArray (creo), etc.). El codificador JSON hace el resto por ti.
Tengo una aplicación de juguete que envía un https JSON / POST utilizando la seguridad de autenticación básica. Me han dicho que debería considerar el uso de AFNetworking. He podido instalar AFNetwork-2 en mi proyecto XCode (ios7 target, XCode5) muy bien. Pero ninguno de los ejemplos parece ser relevante para las versiones actuales de AFNetworking-2, sino versiones anteriores. Los documentos de AFNetworking son bastante escasos, por lo que estoy luchando para armar las piezas. El código que no es de AFNetworking es algo así como
NSURL *url = [NSURL URLWithString:@"https://xxx.yyy.zzz.aaa:bbbbb/twig_monikers"];
NSMutableURLRequest *request = [NSMutableURLRequest
requestWithURL:url
cachePolicy: NSURLRequestUseProtocolCachePolicy
timeoutInterval: 10.0];
NSData *requestData = [NSJSONSerialization dataWithJSONObject: [self jsonDict] options: 0 error: nil];
[request setHTTPMethod: @"POST"];
[request setValue: @"application/json" forHTTPHeaderField: @"Accept"];
[request setValue: @"application/json" forHTTPHeaderField: @"Content-Type"];
[request setValue:[NSString stringWithFormat: @"%d", [requestData length]] forHTTPHeaderField: @"Content-Length"];
NSData *plainPassText = [@"app_pseudouser:sample_password" dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64PassText = [plainPassText base64EncodedStringWithOptions: NSDataBase64Encoding76CharacterLineLength];
[request setValue:[NSString stringWithFormat: @"Basic %@", base64PassText] forHTTPHeaderField: @"Authorization"];
FailedCertificateDelegate *fcd=[[FailedCertificateDelegate alloc] init];
NSURLConnection *c=[[NSURLConnection alloc] initWithRequest:request delegate:fcd startImmediately:NO];
[c setDelegateQueue:[[NSOperationQueue alloc] init]];
[c start];
NSData *data=[fcd getData];
if (data)
NSLog(@"Submit response data: %@", [NSString stringWithUTF8String:[data bytes]]);
No estoy buscando a alguien que escriba mi código para mí. Parece que no puedo encontrar la forma de asignar las partes de AFNetworking-2 a eso. Cualquier enlaces, o ejemplos, o explicaciones muy bienvenidos.
ACTUALIZACIÓN 1
Lo anterior es una versión sin AF que se sabe que funciona. Moviéndome tratando de obtener todo de una vez, solo intenté:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer
setAuthorizationHeaderFieldWithUsername:@"app_pseudouser"
password:@"sample_password"];
AFHTTPRequestOperation *operation =
[manager
PUT: @"https://172.16.214.214:44321/twig_monikers"
parameters: [self jsonDict]
success:^(AFHTTPRequestOperation *operation, id responseObject){
NSLog(@"Submit response data: %@", responseObject);}
failure:^(AFHTTPRequestOperation *operation, NSError *error){
NSLog(@"Error: %@", error);}
];
Que produce el siguiente error:
2013-10-09 11:41:38.558 TwigTag[1403:60b] Error: Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn’t be completed. (NSURLErrorDomain error -1012.)" UserInfo=0x1662c1e0 {NSErrorFailingURLKey=https://172.16.214.214:44321/twig_monikers, NSErrorFailingURLStringKey=https://172.16.214.214:44321/twig_monikers}
Observando en el lado del servidor, nada lo logra. No sé si es porque el https, o qué, pero puedo volver a colocar la aplicación en el código original, y se soluciona.