2009-06-14 15 views
13

Sto provando a far funzionare un piccolo client Twitter e ho riscontrato un problema durante il test delle chiamate API che richiedono l'autenticazione.Autenticazione HTTP di base su iPhone

La mia password contiene caratteri speciali, quindi quando provo a utilizzare il seguente codice non funziona.

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

ho iniziato a guardare in Base64 e mettendo l'autenticazione nelle intestazioni. Ho trovato il post Dave Dribin's sulla sua implementazione di base64 e sembrava avere un senso. Tuttavia, quando ho provato a usarlo, il compilatore ha iniziato a lamentarsi di come non potesse trovare le librerie di openssl. Quindi ho letto che avevo bisogno di collegarmi nella libreria libcrypto, ma non sembra esistere per iphone.

Ho letto anche persone che dicono che Apple non permetterà app che usano le librerie crittografiche, il che non ha senso per me.

Quindi ora sono piuttosto bloccato e confuso. Qual è il modo più semplice per ottenere l'autenticazione di base nella mia app?

Cheers

risposta

15

Due cose. In primo luogo devi usare i metodi asincroni piuttosto che il metodo sincrono/classe.

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

L'autenticazione è gestito mediante l'attuazione di questo metodo nella delegato:

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

e probabilmente anche bisogno di implementare questi metodi troppo:

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

Utilizzando il metodo asincrono tende a dare comunque un'esperienza utente migliore, quindi nonostante la complessità extra vale la pena fare anche senza la possibilità di fare l'autenticazione.

+0

ho cambiato la chiamata sendSynchronous a initWithRequest: Richiesta delegato: auto e quindi configurare il didReceiveAuthenticationChallenge nel delegato, ma non viene richiamato nulla. Ho provato altri metodi delegati NSURLConnection e non hanno funzionato neanche. Qualche idea? – Meroon

+0

Ho capito perché i metodi dei delegati non funzionavano. Stavo chiamando initWithRequest da un metodo di classe che non funzionerà. Grazie per l'aiuto. – Meroon

+0

Scusate, risposta tersa inutilmente (ma felice che ci siete arrivati ​​alla fine).L'ho ampliato. Spero che ora sia un po 'più utile. –

0

È possibile direttamente giardini.L scrivere scarica la password nome utente & in URL principale cioè https://username:[email protected]/

Prima di tutto è necessario chiamare NSURLConnection lima Delegato: -

  • (BOOL) Collegamento: (NSURLConnection *) canAuthenticateAgainstProtectionSpace collegamento: (NSURLProtectionSpace *) protectionSpace

    {

    ritorno SÌ; }

e quindi chiamare - connessione (void): (NSURLConnection *) Collegamento didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *) sfida

{ 
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"); 
     } 
} 
Problemi correlati