2009-06-14 19 views
13

Estoy tratando de ejecutar un pequeño cliente de Twitter y me encontré con un problema al probar las llamadas a la API que requieren autenticación.Autenticación HTTP básica en el iPhone

Mi contraseña tiene caracteres especiales, por lo que cuando intento utilizar el siguiente código, no funciona.

NSString *post = [NSString stringWithFormat:@"status=%@", [status stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; 
NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; 

NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]]; 

NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease]; 
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://%@:%@@%@/statuses/update.json", username, password, TwitterHostname]]; 
[request setURL:url]; 
[request setHTTPMethod:@"POST"]; 
[request setValue:postLength forHTTPHeaderField:@"Content-Length"]; 
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; 
[request setHTTPBody:postData]; 

NSURLResponse *response; 
NSError *error; 
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; 

Empecé a buscar en base64 y poner la autenticación en los encabezados. Encontré Dave Dribin's publicación en su implementación de base64, y parecía tener sentido. Sin embargo, cuando traté de usarlo, el compilador comenzó a quejarse de que no podía encontrar las bibliotecas de openssl. Así que leí que necesitaba vincular en la biblioteca libcrypto, pero no parece existir para iphone.

También he leído personas que dicen que Apple no permitirá las aplicaciones que usan bibliotecas de cifrado, lo cual no tiene sentido para mí.

Así que ahora estoy un poco atascado y confundido. ¿Cuál es la forma más fácil de obtener autenticación básica en mi aplicación?

Cheers

Respuesta

15

Dos cosas. En primer lugar, debe utilizar los métodos async en lugar del método síncrono/clase.

NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:req] 
                   cachePolicy:NSURLRequestUseProtocolCachePolicy 
                  timeoutInterval:30.0]; 

// create the connection with the request 
// and start loading the data 
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; 

La autenticación se gestiona mediante la aplicación de este método en su delegado:

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge; 

Y es probable que también es necesario para poner en práctica estos métodos también:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response; 
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data; 
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error; 
- (void)connectionDidFinishLoading:(NSURLConnection *)connection; 

Utilizando el método asíncrono tiende a dar una mejor experiencia de usuario de todos modos, a pesar de la complejidad adicional, vale la pena hacerlo incluso sin la capacidad de realizar la autenticación.

+0

he cambiado la llamada sendSynchronous a initWithRequest: solicitud delegado: uno mismo y luego configura el evento didReceiveAuthenticationChallenge en el delegado, pero no se llama a nada. Probé otros métodos de delegado de NSURLConnection y tampoco funcionaron. ¿Algunas ideas? – Meroon

+0

Descubrí por qué los métodos de delegado no funcionaban. Estaba llamando a initWithRequest desde un método de clase que no funcionará. Gracias por la ayuda. – Meroon

+0

Lo siento, respuesta innecesariamente concisa (pero feliz de que hayas llegado al final).Lo he expandido. Espero que sea un poco más útil ahora. –

0

Usted directamente puede aslo descargar el nombre de usuario contraseña & en URL principal es decir https://username:[email protected]/

En primer lugar es necesario llamar a NSURLConnection archivo Delegado escribir: -

  • (BOOL) Conexión: (NSURLConnection *) canAuthenticateAgainstProtectionSpace conexión: (NSURLProtectionSpace *) protectionSpace

    {

    return SÍ; }

y luego llamar - Conexión (void): (NSURLConnection *) Conexión didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *) desafío

{ 
if ([challenge previousFailureCount] == 0) 
     { 
      NSURLCredential *newCredential; 

      newCredential = [NSURLCredential credentialWithUser:@"username" 
                 password:@"password" 
                persistence:NSURLCredentialPersistenceForSession]; 
      NSLog(@"NEwCred:- %@ %@", newCredential, newCredential); 
      [[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge]; 
     } 
     else 
     { 
      [[challenge sender] cancelAuthenticationChallenge:challenge]; 
      NSLog (@"failed authentication"); 
     } 
} 
Cuestiones relacionadas