2009-06-14 17 views
13

Próbuję uruchomić małego klienta Twittera i napotkałem problem podczas testowania wywołań API wymagających uwierzytelniania.Podstawowe uwierzytelnianie HTTP na iPhonie

Moje hasło zawiera specjalne znaki, więc gdy spróbuję użyć następującego kodu, to nie działa.

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

Zacząłem zaglądać do base64 i umieszczać uwierzytelnianie w nagłówkach. Znalazłem wpis Dave Dribin's na jego implementacji base64 i wydawało się, że ma to sens. Jednak gdy próbowałem go użyć, kompilator zaczął narzekać, że nie mógł znaleźć bibliotek openssl. Czytałem więc, że muszę połączyć w bibliotece libcrypto, ale wydaje się, że nie istnieje dla iPhone'a.

Przeczytałem też ludzi, którzy mówią, że jabłko nie zezwala na aplikacje korzystające z bibliotek kryptograficznych, co nie ma dla mnie sensu.

Więc teraz utknąłem i zdezorientowany. Jaki jest najprostszy sposób na uzyskanie podstawowego uwierzytelnienia w mojej aplikacji?

Pozdrowienia

Odpowiedz

15

Dwie rzeczy. Po pierwsze musisz użyć metod asynchronicznych zamiast metody synchronicznej/klasy.

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

Uwierzytelnianie jest zarządzany przez wdrożenie tej metody w swoim delegatem:

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

A ty pewnie też należy wdrożyć te metody za:

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

Stosując metodę transmisji asynchronicznej zwykle zapewnia lepsze wrażenia użytkownika, więc pomimo dodatkowej złożoności warto to zrobić nawet bez możliwości uwierzytelniania.

+0

Zmieniłem sendSynchronous wezwanie do initWithRequest: wniosek delegata: self i następnie skonfiguruj didReceiveAuthenticationChallenge w delegate, ale nic nie zostanie wywołane. Próbowałem innych metod delegowania NSURLConnection i one też nie działały. Jakieś pomysły? – Meroon

+0

Wyjaśniłem, dlaczego metody delegatów nie działają. Wywoływałam initWithRequest z metody klasy, która nie zadziała. Dzięki za pomoc. – Meroon

+0

Przepraszam, niepotrzebnie lakoniczna odpowiedź (ale szczęśliwy, że dostałeś się tam na końcu).Rozbudowałem to. Mam nadzieję, że teraz jest bardziej użyteczny. –

0

Można bezpośrednio aslo pisać pobrać hasło w głównej zawartości nazwa & tj https://username:[email protected]/

Przede wszystkim trzeba zadzwonić NSURLConnection Delegat file: -

  • (BOOL) gra: (NSURLConnection *) canAuthenticateAgainstProtectionSpace połączenia (NSURLProtectionSpace *) protectionSpace

    {

    return YES; }

a następnie zadzwonić - (void) gra: (NSURLConnection *) didReceiveAuthenticationChallenge gra: (NSURLAuthenticationChallenge *) wyzwanie

{ 
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"); 
     } 
} 
Powiązane problemy