带有完成处理程序的NSURLConnection sendAsynchronousRequestvalidation

一般来说,我喜欢用NSURL的sendAsynchronousRequest类方法使用完成处理程序块来“消灭和忘记”,但是在需要身份validation时,似乎可能不是一个选项。

当使用这样的完成处理程序样式请求时:

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

什么是处理身份validation的正确方法? 我需要分配和初始化NSURLConnection并设置一个委托,而不是使用这种类方法风格? 我想我明白如何使用委托函数正确进行身份validation,但我试图弄清楚是否可以将它包含在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]; } } 

我认为completionHandler方法适用于基本的请求。 也许你可以考虑使用AFNetworking,因为我使用块方法和身份validation。

编辑….你有没有尝试将身份validation标头添加到NSURLRequest? 创build一个NSMutableURLRequest:

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

并像这样添加authentication头文件:

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

即使这个问题现在已经解决了,我想添加一个不需要第三方库的解决scheme:

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