2010-11-03 23 views
11

Tengo un servicio WCF alojado y estoy tratando de usarlo en una aplicación de iPhone como una solicitud JSON POST. Pienso en el uso del serializador JSON más tarde, pero esto es lo que tengo para la solicitud:Solicitud JSON POST en el iPhone (usando HTTPS)

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]; 

En mis datos recibidos Estoy imprimirlo en la consola:

- (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); 
} 

Y dentro de este respuesta me sale este mensaje:

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> 

¿Alguien sabe por qué sucede esto y dónde me estoy equivocando?

que he leído sobre el uso de ASIHTTPPost lugar pero no puedo conseguir la demo para funcionar en iOS4 :(

Gracias

EDIT:

acabo acostumbrado a CharlesProxy a sniff de lo que pasa cuando llamo desde el iPhone (simulador) y esto es lo que me dio: alt text

la única cosa extraña que he notado es que dice " SSL Proxying no habilitado para este host: habilitar en Proxy Settings, SSL locations ". Alguien sabe que significa esto? (Esto también ocurre en mi cliente Windows).

Acabo de ejecutar esto en mi cliente de Windows y lo único que es diferente es el texto de Solicitud y respuesta que está encriptado. ¿Me falta algo para usar una conexión HTTP segura para hacer esto?

EDIT NUEVA: Esto funciona con una solicitud no HTTPS como: http://maps.googleapis.com/maps/api/geocode/json?address=UK&sensor=true. ¿Entonces supongo que el problema es conseguir que el iPhone envíe el POST correctamente sobre SSL?

También estoy usando estos métodos:

- (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; 
    } 
} 

Esto me permite llegar hasta aquí. Si no los uso recibo un mensaje de error diciendo:

El certificado para este servidor no es válido. Es posible que se conecte a un servidor que pretende ser "midominio.com", lo que podría poner en riesgo su información confidencial.

+0

¿Puedes ver los registros en tu servidor si tienen algo interesante en ellos? – willcodejavaforfood

+0

No tengo acceso a ellos ahora mismo. Sin embargo, sé que el servicio está configurado y funciona con otros clientes. –

Respuesta

12

¡CORREGIDO!

modificado: Se

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

a:

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

También es necesario que estos dos métodos:

- (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; 
    } 
} 
+0

por cierto, ¿no se olvidó de "devolver NO;" en la última línea del último método? – Artem

+0

No estoy seguro, yo devuelva SÍ a un método nulo. No recuerdo por qué ahora. –

+0

@ ing0 ¿puede traducir esta línea a una lista rápida [request setValue: @ "application/x-www-form-urlencoded" forHTTPHeaderField: @ "Content-Type"] ; –

3

No sé Objective C en absoluto, pero trata de establecer la cabecera Accept a application/json en lugar de application/jsonrequest.

+0

Probé eso antes. ¿Debería ser así de todos modos? ¡Lo hice de nuevo y todavía recibo la misma respuesta! :( –

+1

'application/json' es definitivamente el tipo MIME correcto para datos JSON. Consulte http://stackoverflow.com/questions/477816/the-right-json-content-type – Jon

+0

OK gracias. Probablemente sea uno de ¡muchos errores! :) +1 –

0

cambio

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

a

NSData *requestData = [jsonRequest dataUsingEncoding:NSUTF8StringEncoding]; 
0

DIC es Diccionario NSMutable con el objeto y llaves. baseUrl es la URL de servicio web de su servidor.

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"]; 
Cuestiones relacionadas