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);
This library is the best -> 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];
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.
When you use AFXMLResponseSerializer
as AFHTTPRequestOperationManager's
responseSerializer
, the responseObject in success block is a NSXMLParser
object, you should implemente NSXMLParser's
delegate,and parsing xml
If you want to get the xml as a string object.Use the code below:
Using AFHTTPResponseSerializer
, then encode the response data to 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 string: %@", [NSString stringWithUTF8String:[data bytes]]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
UPDATE
set User-Agent:
AFHTTPRequestSerializer * requestSerializer = [AFHTTPRequestSerializer serializer];
[requestSerializer setValue:@"your user agent" forHTTPHeaderField:@"User-Agent"];
manager.requestSerializer = requestSerializer;
you can try to use XmlReader to do what you want, it's pretty simple. Look here How to reloadData in tableView with didSelectedRowAtIndexPath and call group of methods in it
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With