Analizando XML con AFNetworking

Soy bastante nuevo con iOS y trato de hacer una request REST y search algunos datos XML, analizarlos e idealmente ponerlos en un object personalizado. Pero por ahora estoy atrapado con la obtención de datos XML.

Encontré este fragment de código en Github / AFNetworking ..

- (void) fetchInterestData{ AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; manager.responseSerializer = [AFXMLResponseSerializer new]; NSDictionary *parameters = @{@"foo": @"bar"}; [manager POST:@"http://www.raywenderlich.com/downloads/weather_sample/weather.php?format=json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { NSLog(@"JSON: %@", responseObject); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"Error: %@", error); }]; } 

Funciona y obtiene un object JSON. Pero quiero get el XML …

Si utilizo http://www.raywenderlich.com/downloads/weather_sample/weather.php?format=xml en su lugar, hay un object xml. Pero ahora el código se descompone por completo. Tenía la esperanza de get al less el xml como un object de cadena.

¿Qué debo cambiar para search el xml y, supuestamente, quiero search un object xml de la siguiente estructura:

 <RootNode> <Banks> <Bank> <BankId>17</BankId> <BankName>Bluestep</BankName> <BankUrl>http://www.bluestep.se</BankUrl> <BankImage> http://smartkalkyl.se/smartfiles/layout/banklogos/bluestep.png </BankImage> <Rates> <Rate> <RateDate>2013-12-05</RateDate> <RateType>5</RateType> <RateInterest>6,23</RateInterest> <RateDescription/> <RateBefore>6,27</RateBefore> <RateChange>False</RateChange> <RateBeforeDate>2013-08-13</RateBeforeDate> </Rate> </Rates> </Bank> <Bank> ... 

¿Cómo puedo hacer eso?

ACTUALIZACIÓN: nuevo código …

 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; AFHTTPRequestSerializer * requestSerializer = [AFHTTPRequestSerializer serializer]; NSString *ua = @"Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25"; [requestSerializer setValue:ua forHTTPHeaderField:@"User-Agent"]; [requestSerializer setValue:@"application/xml" forHTTPHeaderField:@"Content-type"]; manager.requestSerializer = requestSerializer; NSDictionary *parameters = @{@"foo": @"bar"}; [manager POST:@"http://smartkalkyl.se/rateapp.aspx?user=xxxx&pass=xxx" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { NSData * data = (NSData *)responseObject; self.fetchedXML = [NSString stringWithUTF8String:[data bytes]]; //NSLog(@"Response string: %@", self.fetchedXML); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"Error: %@", error); }]; 

Pero esto me da un error …

 2013-12-06 00:04:10.657 TabbedDemo[38335:a0b] Error: Error Domain=AFNetworkingErrorDomain Code=-1016 "Request failed: unacceptable content-type: text/xml" UserInfo=0x8d80ac0 {NSErrorFailingURLKey=http://smartkalkyl.se/rateapp.aspx?user=xxxx&pass=xxxx, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0x8a75230> { URL: http://smartkalkyl.se/rateapp.aspx?user=xxxx&pass=xxxx } { status code: 200, headers { "Cache-Control" = private; "Content-Encoding" = deflate; "Content-Length" = 1260; "Content-Type" = "text/xml; charset=iso-8859-1"; Date = "Thu, 05 Dec 2013 23:03:47 GMT"; Server = "Microsoft-IIS/7.5"; "Set-Cookie" = "ASP.NET_SessionId=ad3zikxbh4bcawxulkhwt2j3; path=/; HttpOnly"; "X-AspNet-Version" = "4.0.30319"; "X-Powenetworking-By" = "UrlRewriter.NET 2.0.0, ASP.NET"; } }, NSLocalizedDescription=Request failed: unacceptable content-type: text/xml} 

¿Alguna idea de cuál podría ser el problema?

Estoy haciendo un funcionamiento similar en la versión de Android de la aplicación y este es el código que funciona allí y que funciona. Nunca establezco ningún tipo de contenido allí …

 // defaultHttpClient DefaultHttpClient httpClient = new DefaultHttpClient(); HttpProtocolParams.setUserAgent(httpClient.getParams(), System.getProperty("http.agent")); HttpPost httpPost = new HttpPost(url); HttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); xml = EntityUtils.toString(httpEntity); 

Según su código actualizado, necesita agregar un serializador de respuesta y también necesita traducir el NSData correctamente:

 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; AFHTTPRequestSerializer * requestSerializer = [AFHTTPRequestSerializer serializer]; AFHTTPResponseSerializer * responseSerializer = [AFHTTPResponseSerializer serializer]; NSString *ua = @"Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25"; [requestSerializer setValue:ua forHTTPHeaderField:@"User-Agent"]; // [requestSerializer setValue:@"application/xml" forHTTPHeaderField:@"Content-type"]; responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/xml", nil]; manager.responseSerializer = responseSerializer; manager.requestSerializer = requestSerializer; NSDictionary *parameters = @{@"foo": @"bar"}; [manager POST:@"http://smartkalkyl.se/rateapp.aspx?user=xxxxx&pass=xxxxxx" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { NSData * data = (NSData *)responseObject; self.fetchedXML = [NSString stringWithCString:[data bytes] encoding:NSISOLatin1StringEncoding]; NSLog(@"Response string: %@", self.fetchedXML); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"Error: %@", error); }]; 

Su respuesta vuelve como text / xml, y el serializador de respuesta pnetworkingeterminado debe establecerse para aceptarlo.

Los datos no regresan como UTF8, pero ASCII, por lo que debemos establecerlo de manera apropiada también.

Lo intenté en el simulador y está trabajando en mi final.

editar: parece que los datos están en formatting ISO latin-1. mi error.

  1. Cuando utiliza AFXMLResponseSerializer como AFHTTPRequestOperationManager's responseSerializer , el responseObject in success block es un object NSXMLParser , debe implementar NSXMLParser's delegado NSXMLParser's y analizar xml

  2. Si desea get el xml como un object de cadena. Utilice el código a continuación:

Utilizando AFHTTPResponseSerializer , codifique los datos de respuesta en cadena

  AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; manager.responseSerializer = [AFHTTPResponseSerializer new]; NSDictionary *parameters = @{@"foo": @"bar"}; [manager POST:@"http://www.raywenderlich.com/downloads/weather_sample/weather.php?format=xml" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { NSData * data = (NSData *)responseObject; NSLog(@"Response string: %@", [NSString stringWithUTF8String:[data bytes]]); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"Error: %@", error); }]; 

ACTUALIZAR

establecer usuario-agente:

  AFHTTPRequestSerializer * requestSerializer = [AFHTTPRequestSerializer serializer]; [requestSerializer setValue:@"your user agent" forHTTPHeaderField:@"User-Agent"]; manager.requestSerializer = requestSerializer; 

Esta biblioteca es la mejor -> https://github.com/nicklockwood/XMLDictionary

 NSURL *URL = [NSURL URLWithString:@"http://maps.googleapis.com/maps/api/directions/xml?origin=Toronto&destination=Montreal&sensor=false"]; NSURLRequest *request = [NSURLRequest requestWithURL:URL]; AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; operation.responseSerializer = [AFXMLDictionaryResponseSerializer serializer]; [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { NSDictionary *d0 = [NSDictionary dictionaryWithXMLParser:(NSXMLParser*)responseObject]; NSLog(@"d0:%@", d0); } failure:nil]; [operation start]; 

puedes intentar usar XmlReader para hacer lo que quieras, es bastante simple. Mire aquí Cómo volver a cargar datos en tableView con didSelectedRowAtIndexPath y llamar a un grupo de methods en él