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