2009-06-14 27 views
13

小さなTwitterクライアントを実行しようとしています。認証が必要なAPI呼び出しをテストするときに問題が発生しました。iPhoneでの基本的なHTTP認証

パスワードに特殊文字が含まれているため、次のコードを使用しようとすると機能しません。

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

私はbase64を調べ、ヘッダーに認証を入れ始めました。彼のbase64の実装ではDave Dribin'sの投稿が見つかりました。それは意味をなさないようでした。しかし、私はそれを使用しようとしたときに、コンパイラはopensslライブラリを見つけられなかったと不満を持ち始めました。だから私はlibcryptoライブラリにリンクする必要があることを読んだが、それはiphoneのために存在しないようだ。

私は、リンゴは暗号ライブラリを使用するアプリケーションを許可しないと言っている読者も読んでいますが、それは私にとって意味のないものです。

だから私はちょっと固まって混乱しています。私のアプリに基本認証を与える最も簡単な方法は何ですか?

乾杯

答えて

15

2つのもの。まず、同期/クラスメソッドではなく、非同期メソッドを使用する必要があります。

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

認証がデリゲートでこのメソッドを実装することにより管理されている:

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

そして、あなたはおそらく、あまりにもこれらのメソッドを実装する必要があります:非同期メソッドを使用して

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

をとにかく優れた複雑さにもかかわらず、より良いユーザーエクスペリエンスを提供する傾向がある認証を行う機能を持たなくても価値がある。

+0

(NSURLAuthenticationChallenge *)挑戦:リクエストのデリゲート:自己とデリゲートでdidReceiveAuthenticationChallengeをセットアップしますが、何も呼び出されません。他のNSURLConnectionデリゲートメソッドを試してみましたが、どちらもうまくいきませんでした。何か案は? – Meroon

+0

私はデリゲートメソッドがうまくいかない理由を理解しました。私は動作しないクラスメソッドからinitWithRequestを呼び出していました。助けてくれてありがとう。 – Meroon

+0

申し訳ありませんが、不必要に簡潔な回答です(ただし、最後にはうれしいです)。私はそれを拡大しました。うまくいけば、もう少し役に立つはずです。 –

0

あなたが直接あなたがNSURLConnection委任ファイルを呼び出すために必要なすべてのhttps://username:[email protected]/

まず、つまりメインURLにユーザー名&パスワードをダウンロード書くasloすることができます: -

  • (BOOL)接続:(NSURLConnection * )接続canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace

    {

    return YES; }

してから呼び出して - (無効)接続:(NSURLConnection *)接続didReceiveAuthenticationChallenge:私はinitWithRequestにsendSynchronousコールを変更

{ 
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"); 
     } 
} 
関連する問題