2009-06-14 4 views
13

Ich versuche, einen kleinen Twitter-Client zum Laufen zu bringen, und beim Testen von API-Aufrufen, die eine Authentifizierung erfordern, stieß ich auf ein Problem.Einfache HTTP-Authentifizierung auf dem iPhone

Mein Passwort enthält Sonderzeichen. Wenn ich versuche, den folgenden Code zu verwenden, funktioniert das nicht.

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

Ich begann in base64 suchen und die Authentifizierung in die Header setzen. Ich fand Dave Dribin's Post auf seiner Base64-Implementierung, und es schien Sinn zu machen. Als ich jedoch versuchte, es zu benutzen, begann der Compiler darüber zu klagen, wie er die openssl-Bibliotheken nicht finden konnte. Also las ich, dass ich in der libcrypto-Bibliothek verlinken musste, aber für das iPhone scheint es nicht zu existieren.

Ich habe auch Leute gelesen, die sagen, dass Apple keine Apps erlaubt, die Crypto-Bibliotheken verwenden, was für mich keinen Sinn ergibt.

So jetzt bin ich irgendwie fest und verwirrt. Was ist der einfachste Weg, um grundlegende Authentifizierung in meiner App zu erhalten?

Prost

Antwort

15

Zwei Dinge. Zuerst müssen Sie die asynchronen Methoden anstelle der synchronen/Klassenmethode verwenden.

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

Die Authentifizierung durch die Implementierung dieser Methode in Ihre Stellvertretung verwaltet:

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

Und Sie werden wahrscheinlich brauchen auch zu, diese Methoden zu implementieren:

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

von der Asynchron-Methode verwenden neigt dazu, eine bessere Benutzererfahrung trotzdem zu geben, also trotz der zusätzlichen Komplexität lohnt sich auch ohne die Möglichkeit, Authentifizierung zu tun.

+0

ich den sendSynchronous Aufruf initWithRequest geändert: Anfrage delegieren: Selbst und Dann richten Sie die didReceiveAuthenticationChallenge im Delegate ein, aber nichts wird aufgerufen. Ich habe versucht, andere NSURLConnection Delegate-Methoden und sie auch nicht funktioniert. Irgendwelche Ideen? – Meroon

+0

Ich fand heraus, warum die Delegiertenmethoden nicht funktionierten. Ich habe initWithRequest von einer Klassenmethode aufgerufen, die nicht funktioniert. Danke für die Hilfe. – Meroon

+0

Entschuldigung, unnötig knappe Antwort (aber glücklich, dass Sie am Ende dort angekommen sind).Ich habe es erweitert. Hoffentlich ist es jetzt ein bisschen nützlicher. –

0

Sie können auch direkt schreiben aslo den Benutzernamen & Passwort in Haupt-URL herunterladen dh https://username:[email protected]/

Zunächst einmal müssen Sie NSURLConnection Delegate-Datei aufzurufen: -

  • (BOOL) Anschluss: (NSURLConnection *) Verbindung canAuthenticateAgainstProtectionSpace: (NSURLProtectionSpace *) protectionSpace

    {

    zurück JA; }

und rufen Sie dann - (void) Verbindung: (NSURLConnection *) Verbindung didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *) Herausforderung

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