12

一般的に、完了ハンドラー ブロックを使用して NSURL の 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];
    }

}
4

3 に答える 3

22

completionHandler メソッドは基本的なリクエスト用だと思います。ブロックメソッドと認証でこれを使用しているため、AFNetworkingの使用を検討できるかもしれません。

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

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

そして、次のように認証ヘッダーを追加します。

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

AFBase64EncodedStringFromString 関数は次のとおりです。

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[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

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

次に、前に呼び出した関数を呼び出しますが、新しい NSURLRequest を使用します。

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

}];
于 2012-10-16T19:24:48.173 に答える
21

問題はしばらく解決されましたが、サードパーティのライブラリを必要としないソリューションを追加したいと思います。

//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..

}
于 2013-11-13T11:28:51.060 に答える
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
    }];
于 2015-12-28T15:45:42.323 に答える