问题
I'm using AFNetworking-2
with JSON response and it was working fine and now I have to convert it to XML instead of using JSON because the server response is in XML. After I've searched I reached with this code but it is not working.
With Charles I found the request is wrong "Fail to parse data (org.xml.sax.SAXParseException: Content not allowed is prolog)"
Please where would be my issue?
My code:
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];
}
Here is an example which is working fine:
- (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);
}
回答1:
When you use AFHTTPRequestSerializer
your body is created using URL Form Parameter encoding. Your non-AFNetworking example is using XML, so the body looks different.
You'll want to do something like this:
Instead of using the POST:…
convenience method, use the serializer and then set up and enqueue your operation manually:
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];
If you have to do this a bunch, you might want to subclass AFHTTPRequestSerializer
and make a custom serializer for your server.
But really you should just tell your server team to keep accepting JSON - it's much simpler to work with for most applications.
回答2:
To expand on Aaron's answer (which you should probably accept), if your server is expecting a XML request, and is sending XML response, you could do something like:
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];
In the above, I set two headers, Content-Type
(which informs the server that you're sending an XML request) and Accept
(which informs the server that you're expecting and will accept XML response). These are not necessarily required, but are probably good practice. There's also some variations that are sometimes used here (e.g. text/xml
is possible, or there are also some other relevant Content-Type
values, too), but it just depends upon what your server is expecting. But the goal is to be a good HTTP citizen and specify these headers.
Obviously, this assumes that you've also implemented the NSXMLParserDelegate
methods in order to actually parse the XML response, too, but that's beyond the scope of this question. If you're not familiar with NSXMLParser
, I'd suggest you see Apple's Event-Driven XML Programming Guide or google "NSXMLParser example" or "NSXMLParser tutorial" for more information.
By the way, I notice that you're building your XML string manually. Some fields (especially the password) might include some characters that are reserved within XML fields. So if you build your XML manually, make sure you replace <
, >
, and &
in the values your embed in your XML with <
, >
and &
, respectively.
来源:https://stackoverflow.com/questions/27317591/afnetworking-xml-request-issue