Как отправить данные XML POST из приложения iOS в приложение Django? - PullRequest
4 голосов
/ 08 мая 2011

Я пытаюсь внедрить онлайн-таблицу лидеров в игровое приложение для iOS, используя Django для обработки запросов POST от iDevice и сохранения результатов.Я понял, как заставить Django сериализовать объекты в XML, и мой iPhone может читать и отображать результаты.Тем не менее, я не могу получить свой iPhone в POST XML на мой сервер 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 или вКод Джанго.Разве 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 - это <QueryDict: {u'score': [u'9'], u'player_name': [u'test']}>.

Все еще не совсем уверен, что делать со всем этим.

Согласно предложению Раду , явзглянул на highScoreData с NSLog, сразу после добавления его в request.HTTPBody, и получил результат <706c6179 65725f6e 616d653d 74657374 3b73636f 72653d39>.

Я огромный новичок Obj-C, так что, опять же, любая помощь приветствуется!Еще раз спасибо.

1 Ответ

1 голос
/ 12 февраля 2012

Поскольку вы контролируете обе стороны, я бы упустил сложность XML-кодирования данных и использовал бы RestKit или какую-то другую инфраструктуру, облегчающую связь с Django.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...