如何将 XML POST 数据从 iOS 应用程序发送到 Django 应用程序?
我正在尝试在 iOS 游戏应用程序中实现在线排行榜,使用 Django 处理来自 iDevice 的 POST 请求并存储分数。我已经弄清楚如何让 Django 将对象序列化为 XML,并且我的 iPhone 可以读取并显示分数。然而,我一生都无法让我的 iPhone 将 XML POST 到我的 Django 服务器。
下面是我用来发布分数的函数...
iOS (Objective-C) 控制器:
- (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];
}
}
上述方法成功发送请求,并将其正确解释为 CONTENT_TYPE: text/xml
,但是处理请求的 Django 视图似乎无法理解它,几乎将其解释为纯文本。下面是我的 Django 视图...
Django (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 ) )
说实话,我不确定问题出在 Objective-C 还是 Django 代码中。 Objective-C 是否未以正确的格式发送 XML?或者 Django 服务器没有正确处理该 XML?
任何见解将不胜感激。提前致谢。
更新:
我让它工作,通过编辑 iOS 控制器来设置请求的 HTTPBody,如下所示:
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];
出于某种原因,在其中放置一个分号让 Django 识别它,将值分配给 HighScore 类的新实例,然后保存它。测试服务器上的日志记录表明 request.POST
为
。
仍然不太确定这一切是怎么回事。
根据Radu的建议,我用 NSLog 查看了 highScoreData,在将其附加到 request.HTTPBody 后,立即查看结果是 <706c6179 65725f6e 616d653d 74657374 3b73636f 72653d39>
。
我是一个巨大的 Obj-C 菜鸟,所以再次感谢任何帮助!再次感谢。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
由于您控制双方,因此我会降低 xml 编码数据的复杂性,并使用 RestKit 或其他一些框架来轻松与 Django 通信。
Since you control both sides, I'd drop the complexity of xml encoding the data and use RestKit or some other framework that makes it easy to communicate with Django.