How to send XML POST data from iOS app to Django app?

I am trying to embed an online leaderboard in a game app for iOS using Django to handle POST requests from iDevice and store points. I figured out how to get Django to serialize objects in XML, and my iPhone can read and display grades. However, I can’t transfer my iPhone POST XML to my Django server for life.

Below is the function that I use to post ratings ...

iOS (Objective-C) Controller:

- (void) submitHighScore { NSLog(@"Submitting high score..."); NSString *urlString = HIGH_SCORES_URL; NSURL *url = [NSURL URLWithString: urlString]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: url]; [request setHTTPMethod: @"POST"]; [request setValue: @"text/xml" forHTTPHeaderField: @"Content-Type"]; NSMutableData *highScoreData = [NSMutableData data]; [highScoreData appendData: [[NSString stringWithFormat: @"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"] dataUsingEncoding: NSUTF8StringEncoding]]; [highScoreData appendData: [[NSString stringWithFormat: @"<player_name>%@</player_name", @"test"] dataUsingEncoding: NSUTF8StringEncoding]]; [highScoreData appendData: [[NSString stringWithFormat: @"<score>%d</score>", 0] dataUsingEncoding: NSUTF8StringEncoding]]; [highScoreData appendData: [[NSString stringWithFormat: @"</xml>"] dataUsingEncoding: NSUTF8StringEncoding]]; [request setHTTPBody: highScoreData]; [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible: YES]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest: request delegate: self]; if (!connection) { NSLog(@"Request to send high scores appears to be invalid."); [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible: NO]; } } 

The above method successfully sends the request and correctly interprets it as CONTENT_TYPE: text/xml , but the Django view processing the request does not seem to make any sense, interpreting it almost as if it were just plain text, Below is my view on Django. ..

Django View (Python):

 from django.http import HttpResponse, HttpResponseBadRequest from django.shortcuts import render_to_response from django.template import RequestContext from django.core import serializers from django.core.exceptions import ValidationError from django.views.decorators.csrf import csrf_exempt from modologger.taptap.models import HighScore @csrf_exempt def leaderboard( request, xml = False, template_name = 'apps/taptap/leaderboard.html' ): """Returns leaderboard.""" if xml == True: # xml is set as True or False in the URLConf, based on the URL requested if request.method == 'POST': postdata = request.POST.copy() print postdata # here, postdata is evaluated as: # <QueryDict: {u'<?xml version': [u'"1.0" encoding="UTF-8" ?><player_name>test</player_name<score>0</score></xml>']}> for deserialized_object in serializers.deserialize('xml', postdata): # this fails, returning a 500 error try: deserialized_object.object.full_clean() except ValidationError, e: return HttpResponseBadRequest deserialized_object.save() else: high_score_data = serializers.serialize( 'xml', HighScore.objects.all() ) return HttpResponse( high_score_data, mimetype = 'text/xml' ) else: high_scores = HighScore.objects.all() return render_to_response( template_name, locals(), context_instance = RequestContext( request ) ) 

To be honest, I'm not sure if the problem is Objective-C or Django code. Is Objective-C not sending XML in the correct format? Or is the Django server not processing this XML correctly?

Any insight would be greatly appreciated. Thanks in advance.

Update:

I got it to work by editing the iOS controller to set the HTTPBody request like this:

 NSMutableData *highScoreData = [NSMutableData data]; [highScoreData appendData: [[NSString stringWithFormat: @"player_name=%@;", @"test"] dataUsingEncoding: NSUTF8StringEncoding]]; [highScoreData appendData: [[NSString stringWithFormat: @"score=%d", 0] dataUsingEncoding: NSUTF8StringEncoding]]; [request setHTTPBody: highScoreData]; 

For some reason, putting a semicolon enabled Django to recognize it, assign values ​​to a new instance of the HighScore class, and save it. The record on the test server indicates request.POST is <QueryDict: {u'score': [u'9'], u'player_name': [u'test']}> .

Still not quite sure what to make of all this.

As suggested by Radu , I took a look at highScoreData with NSLog, immediately after adding it to request.HTTPBody, and the result is <706c6179 65725f6e 616d653d 74657374 3b73636f 72653d39> .

I am a huge Obj-C noob, so again any help is appreciated! Thanks again.

+4
source share
1 answer

Since you manage both sides, I would throw away the complexity of coding xml data and use RestKit or some other structure that simplified the connection with Django.

+1
source

All Articles