Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
189 views
in Technique[技术] by (71.8m points)

ios - Parsing XML with AFNetworking

I am fairly new with iOS and is trying to do a REST request and fetch some XML data, parse that and ideally put into a custom Object. But for now I am stuck with the getting XML data.

I found this code snippet on 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);
}];
}

It works and fetches a JSON object. But I want to get the XML..

If I use http://www.raywenderlich.com/downloads/weather_sample/weather.php?format=xml instead there is an xml object. But now the code breaks down completely. I was hoping to at least get the xml as a string object.

What do I need to change to fetch the xml and assumingly I want to fetch a xml object of following structure:

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

How can I do that?

UPDATE: New code..

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);
}];

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

Any idea what could be the problem?

I am doing similar operation in the Android version of the app and this is the code that works there and that work. I never set any content type there..

// 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);
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Based on your updated code, you need to add a response serializer, and you also need to translate the NSData properly:

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);
      }];

Your response is coming back as text/xml, and the default response serializer needs to be set to accept that.

The data isn't coming back as UTF8 but ascii, so we need to set that appropriately as well.

I gave it a shot in the simulator and it's working on my end.

edit: seems the data is in ISO latin-1 format. my bad.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...