Запрос JSON POST на iPhone (с использованием HTTPS) - PullRequest
11 голосов
/ 03 ноября 2010

У меня есть служба WCF, и я пытаюсь использовать ее в приложении для iPhone в качестве запроса JSON POST. Я планирую использовать сериализатор JSON позже, но вот что у меня есть для запроса:

    NSString *jsonRequest = @"{\"username\":\"user\",\"password\":\"letmein\"}";
    NSLog(@"Request: %@", jsonRequest);

    NSURL *url = [NSURL URLWithString:@"https://mydomain.com/Method/"];

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    NSData *requestData = [NSData dataWithBytes:[jsonRequest UTF8String] length:[jsonRequest length]];

    [request setHTTPMethod:@"POST"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [request setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"];
    [request setHTTPBody: requestData];

    [NSURLConnection connectionWithRequest:[request autorelease] delegate:self];

В полученных данных я просто печатаю их на консоль:

- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    NSMutableData *d = [[NSMutableData data] retain];
    [d appendData:data];

    NSString *a = [[NSString alloc] initWithData:d encoding:NSASCIIStringEncoding];

    NSLog(@"Data: %@", a);
}

И в рамках этого ответа я получаю это сообщение:

Data: <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Request Error</title>
    <style>
        <!-- I've took this out as there's lots of it and it's not relevant! -->
    </style>
  </head>
  <body>
    <div id="content">
      <p class="heading1">Request Error</p>
      <p xmlns="">The server encountered an error processing the request. Please see the <a rel="help-page" href="https://mydomain.com/Method/help">service help page</a> for constructing valid requests to the service.</p>
    </div>
  </body>
</html>

Кто-нибудь знает, почему это происходит и где я ошибаюсь?

Я читал об использовании ASIHTTPPost , но не могу запустить демоверсию в iOS4: (

Спасибо

EDIT:

Я только что использовал CharlesProxy , чтобы узнать, что происходит, когда я звоню с iPhone (симулятор), и вот что он мне дал: alt text

Единственное, что я заметил странно, это то, что он говорит: «SSL-прокси не включен для этого хоста: включите в настройках прокси-сервера, местоположения SSL». Кто-нибудь знает, что это значит? (Это также происходит в моем рабочем клиенте Windows).

Я только что запустил это на моем клиенте для Windows, и единственное, что отличается, - это текст запроса и ответа, который зашифрован. Я что-то упустил, чтобы использовать для этого безопасное HTTP-соединение?

НОВОЕ РЕДАКТИРОВАНИЕ: Это работает с не-HTTPS-запросом, таким как: http://maps.googleapis.com/maps/api/geocode/json?address=UK&sensor=true. Итак, я думаю, проблема в том, чтобы заставить iPhone правильно отправлять POST через SSL?

Я также использую эти методы:

- (void) connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]
        forAuthenticationChallenge:challenge];
    }

    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

- (void) connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        return YES;
    }
}

Это позволяет мне зайти так далеко. Если я не использую их, я получаю сообщение об ошибке:

Сертификат для этого сервера недействителен. Возможно, вы подключаетесь к серверу, который притворяется «mydomain.com», что может поставить под угрозу вашу конфиденциальную информацию.

Ответы [ 4 ]

12 голосов
/ 03 ноября 2010

ИСПРАВЛЕНО!

Изменено:

[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

на:

[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

Вам также нужны эти два метода:

- (void) connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]
        forAuthenticationChallenge:challenge];
    }

    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

- (void) connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        return YES;
    }
}
3 голосов
/ 03 ноября 2010

Я вообще не знаю Objective C, но попробуйте установить заголовок Accept на application/json вместо application/jsonrequest.

0 голосов
/ 24 декабря 2014

dic - NSMutable Dictionary с объектом и ключами.baseUrl - URL-адрес веб-службы вашего сервера.

 NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic
                                                       options:NSJSONWritingPrettyPrinted error:nil];
    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
   NSString *encodedString = [jsonString base64EncodedString];

    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@wsName",baseUrl]];
    NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
    [theRequest addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [theRequest setHTTPMethod:@"POST"];
    [theRequest setValue:encodedString forHTTPHeaderField:@"Data"];
0 голосов
/ 28 мая 2013

изменить

NSData *requestData = [NSData dataWithBytes:[jsonRequest UTF8String] length:[jsonRequest length]];

на

NSData *requestData = [jsonRequest dataUsingEncoding:NSUTF8StringEncoding];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...