2012-10-10 5 views
12

一般に、NSURLのsendAsynchronousRequestクラスメソッドでは、完了ハンドラブロックを使用して「起動し忘れて」いるだけですが、認証が必要な場合はオプションではないようです。NSURLConnectionでの認証完了ハンドラでのsendAsynchronousRequest

このような完了ハンドラスタイルの要求を使用して:

[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.mysite.com/"]] 
             queue:[NSOperationQueue mainQueue] 
          completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { 


          //Do Stuff 

          }]; 

認証を処理するための適切な方法は何ですか? NSURLConnectionを割り当てて初期化し、このクラスメソッドスタイルを使用する代わりにデリゲートを設定する必要がありますか?私はデリゲート関数で正しく認証する方法を理解していると思うが、私はそれをcompletionHandlerブロックに含めることができるかどうか、またはこれを行うより良い方法があるかどうかを調べようとしている。

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 
{ 

    if ([challenge previousFailureCount] > 0) { 
     NSLog(@"Authentication Failure"); 
     [connection cancel]; 
    } 
    else 
    { 

     NSURLCredential *credential = [NSURLCredential credentialWithUser:self.username 
                   password:self.password 
                   persistence:NSURLCredentialPersistenceForSession]; 
     [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; 
    } 

} 

答えて

22

私はcompletionHandlerメソッドは基本的な要求のためのものだと思います。ブロック方法と認証でこれを使用するので、おそらくAFNetworkingの使用を検討することができます。

EDIT .... NSURLRequestに認証ヘッダーを追加しようとしましたか? はNSMutableURLRequestを作成します。

NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.example.com/"]]; 

そして、このような認証ヘッダを追加:

static NSString * AFBase64EncodedStringFromString(NSString *string) { 
    NSData *data = [NSData dataWithBytes:[string UTF8String] length:[string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]]; 
    NSUInteger length = [data length]; 
    NSMutableData *mutableData = [NSMutableData dataWithLength:((length + 2)/3) * 4]; 

    uint8_t *input = (uint8_t *)[data bytes]; 
    uint8_t *output = (uint8_t *)[mutableData mutableBytes]; 

    for (NSUInteger i = 0; i < length; i += 3) { 
     NSUInteger value = 0; 
     for (NSUInteger j = i; j < (i + 3); j++) { 
      value <<= 8; 
      if (j < length) { 
       value |= (0xFF & input[j]); 
      } 
     } 

     static uint8_t const kAFBase64EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/"; 

     NSUInteger idx = (i/3) * 4; 
     output[idx + 0] = kAFBase64EncodingTable[(value >> 18) & 0x3F]; 
     output[idx + 1] = kAFBase64EncodingTable[(value >> 12) & 0x3F]; 
     output[idx + 2] = (i + 1) < length ? kAFBase64EncodingTable[(value >> 6) & 0x3F] : '='; 
     output[idx + 3] = (i + 2) < length ? kAFBase64EncodingTable[(value >> 0) & 0x3F] : '='; 
    } 

    return [[NSString alloc] initWithData:mutableData encoding:NSASCIIStringEncoding]; 
} 

次にあなたが前に呼び出される関数を呼び出しますが、使用して:AFBase64EncodedStringFromString機能がこれです

NSString *basicAuthCredentials = [NSString stringWithFormat:@"%@:%@", userName, password]; 
NSString *authValue = [NSString stringWithFormat:@"Basic %@", AFBase64EncodedStringFromString(basicAuthCredentials)]; 
[urlRequest setValue:authValue forHTTPHeaderField:@"Authorization"]; 

を新しいNSURLリクエスト:

[NSURLConnection sendAsynchronousRequest:urlRequest 
    queue:[NSOperationQueue mainQueue] 
    completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { 

}]; 
+0

' AFBase64EncodedStringFromString'がAで私的な機能であり、それ自体で使用することは意図されていません。代わりに 'AFHTTPClient setAuthorizationHeaderWithUsername:password:'を実行し、 '-requestWithMethod:path:parameters:'で 'NSURLRequest'を作成します(または単に生成されたリクエストから認証ヘッダーをコピーしてください)。 – mattt

+3

サードパーティのライブラリ... – dan

21

問題は今しばらく解消されるにもかかわらず、私はサードパーティのライブラリを必要とdoesnの `tのソリューションを追加したい:

//HTTP Authentication 
NSString *authStr = [NSString stringWithFormat:@"%@:%@", @"Username", @"Password"]]; 
NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding]; 
NSString *authValue = [authData base64Encoding]; 

//Set up Request: 
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init]; 
[request setURL:[NSURL URLWithString:url]]; 
//... 
// Pack in the user credentials 
[request setValue:[NSString stringWithFormat:@"Basic %@",authValue] forHTTPHeaderField:@"Authorization"]; 

// Send the asynchronous request as usual 
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *responseCode, NSData *responseData, NSError *error) { 

    // Do stuff.. 

} 
+0

このコードは、あなたに警告が表示され、 'iOS 9で廃止されました.'を修正しましたので、修正してください:http://stackoverflow.com/questions/30935304/sendasynchronousrequest-was-deprecated-in-ios -9-how-to-alter-code-to-fix – dan

1
NSURLConnection is deprecated in iOS 9, try this code which is from LazyTableImages example from here [https://developer.apple.com/library/ios/samplecode/LazyTableImages/Introduction/Intro.html][1] 
@property (nonatomic, strong) NSURLSessionDataTask *sessionTask; 



    //somwere in your code 

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] 
            initWithURL:[NSURL URLWithString:self.postLink] ]; 

    [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData]; 
    [request setHTTPShouldHandleCookies:NO]; 
    [request setTimeoutInterval:60]; 
    [request setHTTPMethod:@"POST"]; 
    [request addValue:[[NSUserDefaults standardUserDefaults] objectForKey:@"token"] 
    forHTTPHeaderField:@"ACCESSTOKEN"]; 


    self.sessionTask = [[NSURLSession sharedSession] dataTaskWithRequest:request 
                  completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
    //do completion staff here 
    }]; 
関連する問題