Analyse XML avec AFNetworking

Je suis assez nouveau avec iOS et essaye de faire une requête REST et d'aller chercher des données XML, parsingr cela et idéalement mettre dans un object personnalisé. Mais pour l'instant je suis coincé avec datatables XML.

J'ai trouvé cet extrait de code sur 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); }]; } 

Cela fonctionne et récupère un object JSON. Mais je veux get le XML ..

Si j'utilise http://www.raywenderlich.com/downloads/weather_sample/weather.php?format=xml à la place, il y a un object xml. Mais maintenant le code se décompose complètement. J'espérais au less get le xml en tant qu'object ssortingng.

Qu'est-ce que j'ai besoin de changer pour récupérer le file XML et supposer que je veux récupérer un object xml de la structure suivante:

 <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> ... 

Comment puis je faire ça?

UPDATE: Nouveau code ..

 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; AFHTTPRequestSerializer * requestSerializer = [AFHTTPRequestSerializer serializer]; NSSsortingng *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 = [NSSsortingng ssortingngWithUTF8Ssortingng:[data bytes]]; //NSLog(@"Response ssortingng: %@", self.fetchedXML); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"Error: %@", error); }]; 

Mais cela me donne une erreur ..

 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-Powered-By" = "UrlRewriter.NET 2.0.0, ASP.NET"; } }, NSLocalizedDescription=Request failed: unacceptable content-type: text/xml} 

Une idée de ce qui pourrait être le problème?

Je fais une opération similaire dans la version Android de l'application et c'est le code qui fonctionne là-bas et qui fonctionne. Je n'ai jamais défini de type de contenu là-bas ..

 // 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.toSsortingng(httpEntity); 

En fonction de votre code mis à jour, vous devez append un sérialiseur de réponse, et vous devez également traduire le NSData correctement:

 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; AFHTTPRequestSerializer * requestSerializer = [AFHTTPRequestSerializer serializer]; AFHTTPResponseSerializer * responseSerializer = [AFHTTPResponseSerializer serializer]; NSSsortingng *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 = [NSSsortingng ssortingngWithCSsortingng:[data bytes] encoding:NSISOLatin1SsortingngEncoding]; NSLog(@"Response ssortingng: %@", self.fetchedXML); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"Error: %@", error); }]; 

Votre réponse revient sous la forme text / xml et le sérialiseur de réponse par défaut doit être configuré pour accepter cela.

Les données ne reviennent pas en UTF8 mais en ascii, nous devons donc définir cela de manière appropriée.

J'ai donné un coup de feu dans le simulateur et ça marche de mon côté.

edit: semble que datatables sont au format ISO latin-1. ma faute.

  1. Lorsque vous utilisez AFXMLResponseSerializer tant que AFHTTPRequestOperationManager's , le bloc responseObject en succès est un object NSXMLParser , vous devez implémenter NSXMLParser's délégué NSXMLParser's et parsingr xml

  2. Si vous voulez get le xml en tant qu'object string.Utilisez le code ci-dessous:

En utilisant AFHTTPResponseSerializer , puis encoder datatables de réponse en string

  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 ssortingng: %@", [NSSsortingng ssortingngWithUTF8Ssortingng:[data bytes]]); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"Error: %@", error); }]; 

METTRE À JOUR

set User-Agent:

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

Cette bibliothèque est la meilleure -> https://github.com/nicklockwood/XMLDictionary

 NSURL *URL = [NSURL URLWithSsortingng:@"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]; 

vous pouvez essayer d'utiliser XmlReader pour faire ce que vous voulez, c'est assez simple. Regardez ici Comment reloadData dans tableView avec didSelectedRowAtIndexPath et appelez le groupe de methods dedans