Problema de request de XML de AFNetworking

Estoy usando AFNetworking-2 con respuesta JSON y funcionaba bien y ahora tengo que convertirlo a XML en lugar de usar JSON porque la respuesta del server está en XML. Después de haber buscado, llegué con este código pero no funciona.

Con Charles, encontré que la request es incorrecta "Fail to parse data (org.xml.sax.SAXParseException: Content not allowed is prolog)"

¿Dónde estaría mi problema?

Mi código:

  NSString *urlString = BaseURLString; NSURL *url = [[NSURL alloc] initWithString:urlString]; NSString *value = @"<r_PM act=\"login\" loginname=\"1234\" password=\"12345678\" />"; NSString *message = [value stringByReplacingOccurrencesOfString:@"[\\\"" withString:@""]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]]; [request setHTTPMethod: @"POST"]; [request setValue:@"text/xml" forHTTPHeaderField:@"content-type"]; [request setHTTPBody:[[NSString stringWithFormat:@"%@",message] dataUsingEncoding:NSUTF8StringEncoding]]; AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; // Make sure to set the responseSerializer correctly operation.responseSerializer = [AFXMLParserResponseSerializer serializer]; [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { NSXMLParser *XMLParser = (NSXMLParser *)responseObject; [XMLParser setShouldProcessNamespaces:YES]; // Leave these commented for now (you first need to add the delegate methods) XMLParser.delegate = self; [XMLParser parse]; } failure:^(AFHTTPRequestOperation *operation, NSError *error) { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error Retrieving Weather" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alertView show]; }]; [operation start]; } 

Aquí hay un ejemplo que funciona bien:

 - (void)viewDidLoad { [super viewDidLoad]; NSString *value = @"<r_PM act=\"login\" loginname=\"1234\" password=\"12345678\"/>"; NSString *authenticationURL = @"http://demo.example.com/ex/mob/"; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:authenticationURL]]; NSString *message = [value stringByReplacingOccurrencesOfString:@"[\\\"" withString:@""]; [request setHTTPMethod: @"POST"]; [request setValue:@"text/xml" forHTTPHeaderField:@"content-type"]; [request setHTTPBody:[[NSString stringWithFormat:@"%@",message] dataUsingEncoding:NSUTF8StringEncoding]]; NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; [urlConnection start]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { NSString *responseText = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@", responseText); } 

Cuando utiliza AFHTTPRequestSerializer su cuerpo se crea utilizando la encoding de parameters de formulario URL. Su ejemplo de no AFNetworking está utilizando XML, por lo que el cuerpo se ve diferente.

Querrá hacer algo como esto:

En lugar de utilizar el POST:… método de conveniencia, use el serializador y luego configure y ponga en queue su operación manualmente:

 NSMutableURLRequest *request = [requestSerializer requestWithMethod:@"POST" URLString:[[NSURL URLWithString:urlString] absoluteString] parameters:parameters error:nil]; request.HTTPBody = [[NSString stringWithFormat:@"%@",message] dataUsingEncoding:NSUTF8StringEncoding]; AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:request success:<# success block #> failure:<# failure block #>]; [manager.operationQueue addOperation:operation]; 

Si tiene que hacer esto, puede subclass AFHTTPRequestSerializer y crear un serializador personalizado para su server.

Pero realmente deberías decirle a tu equipo de serveres que sigas aceptando JSON; es mucho más sencillo trabajar con la mayoría de las aplicaciones.

Para ampliar la respuesta de Aaron (que probablemente debería aceptar), si su server espera una request XML y está enviando una respuesta XML, puede hacer algo como:

 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; manager.responseSerializer = [AFXMLParserResponseSerializer serializer]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request setHTTPBody:[xmlRequestString dataUsingEncoding:NSUTF8StringEncoding]]; [request setHTTPMethod:@"POST"]; [request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"]; [request setValue:@"application/xml" forHTTPHeaderField:@"Accept"]; NSOperation *operation = [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) { NSXMLParser *parser = responseObject; parser.delegate = self; if (![parser parse]) { // handle parsing error here } else { // use parsed data here } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { // handle network related errors here }]; [manager.operationQueue addOperation:operation]; 

En lo anterior, configuré dos encabezados, Content-Type (que informa al server que estás enviando una request XML) y Accept (que informa al server que estás esperando y aceptará la respuesta XML). Estos no son necesariamente necesarios, pero probablemente sean una buena práctica. También hay algunas variaciones que algunas veces se usan aquí (por ejemplo, text/xml es posible, o también hay otros valores de Content-Type relevantes), pero depende de lo que su server espera. Pero el objective es ser un buen ciudadano HTTP y especificar estos encabezados.

Obviamente, esto supone que también ha implementado los methods NSXMLParserDelegate para analizar realmente la respuesta XML, pero eso está más allá del scope de esta pregunta. Si no está familiarizado con NSXMLParser , le sugiero que consulte la Guía de progtwigción XML impulsada por events de Apple o google "ejemplo NSXMLParser" o "tutorial NSXMLParser" para get más información.


Por cierto, noto que estás creando tu cadena XML manualmente. Algunos campos (especialmente la contraseña) pueden include algunos caracteres reservados dentro de los campos XML. Entonces, si crea su XML manualmente, asegúrese de replace < , > y & en los valores que incrusta en su XML con &lt; , &gt; y &amp; , respectivamente