[英]What is the main difference between NSURLConnection connectionWithRequest:delegate and sendAsynchronousRequest:queue:completionHandler?
[英]sendAsynchronousRequest:queue:completionHandler: With Delegate Methods
我有一台安装了自签名SSL证书的服务器。 但是,一旦我调用以下方法,它不会得到任何响应。 一旦将URL更改回http,就可以使用。
- (void)getAccountInfoWithCompletion:(void (^)(NSDictionary *json_response, NSError *error))completion
{
NSURLRequest *request = [NSURLRequest requestWithURL:
[NSURL URLWithString:
[NSString stringWithFormat:@"%@/api/account/%d/get_info", BASE_HOST_URL_IP, [self getUserID]]
]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (error)
{
if (completion)
{
//completion(@"error", error);
}
} else {
NSString *response_string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *json_object = [NSJSONSerialization JSONObjectWithData:[response_string dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
if (completion)
{
completion(json_object, error);
}
}
}];
}
我之所以成为代表,是因为我可以在自己的应用中使用自签名证书。 以下教程是我正在使用的教程,但是后来我意识到我不能将其委托与完成处理方法一起使用。 我需要保留completionHandler方法。
http://www.cocoanetics.com/2010/12/nsurlconnection-with-self-signed-certificates/
为了收到SSL站点的响应,我该怎么办?
在您描述的情况下,(几乎)您必须使用委托。
这里发生的是sendAsynchronousRequest:queue:completion:
使用URL加载系统的默认行为。 URL加载系统会看到您的自签名证书,无法对其进行验证,因此它无法信任它-并且将无法连接。 您应该看到NSError传递给完成处理程序,该处理程序填充了有关该问题的信息。
在技术说明2232:HTTPS服务器信任评估中对此进行了详细描述。
要允许您的自签名证书,您不能使用sendAsynchronousRequest:queue:completion:
除非您有办法使自签名证书受信任并存储在钥匙串中-在iOS上,这仅在托管设备中才实用。 对于测试,仅用于测试,您可以使用私有的Apple API来更改默认的信任行为。
对于生产代码,必须实现NSURLConnectionDelegate,该NSURLConnectionDelegate可以处理对服务器提供的凭据的评估并允许您的自签名证书。 在技术说明2232中也对此进行了概述(如果没有对此进行概述)。如果未正确实施此操作,则可能会在应用中创建一个安全漏洞-不好,mmmmmk?
我不建议遵循您参考的《助剂学》的指导。 该材料已经过时并且质量令人怀疑。 请参考NSURLConnectionDelegate的文档和提及的Technote 2232 。 如果您想对一般的移动应用传输级安全性的更多信息,也有很多 的 资源可用。
如果仍然要使用自签名证书,则可以实现SSL公钥固定,以将远程(自签名)公钥与应用程序中存储的已知本地值进行匹配。 这比仅匹配主机名要好得多。 让你开始一些示例代码是在这里
ViewController.h:
@interface ViewController : UIViewController <NSURLSessionDelegate>
@end
ViewController.m:
- (void)getAccountInfoWithCompletion:(void (^)(NSDictionary *json_response, NSError *error))completion
{
NSURLRequest *request = [NSURLRequest requestWithURL:
[NSURL URLWithString:
[NSString stringWithFormat:@"%@/api/account/%d/get_info", BASE_HOST_URL_IP, [self getUserID]]
]];
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration ephemeralSessionConfiguration];
defaultConfigObject.requestCachePolicy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue: [NSOperationQueue mainQueue]];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
if (error == nil && data != nil)
{
NSString *response_string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *json_object = [NSJSONSerialization JSONObjectWithData:[response_string dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
if (completion)
{
completion(json_object, error);
}
}
}];
[dataTask resume];
}
新的漂亮的委托方法,使我们可以代替NSURLConnection的sendAsynchronousRequest方法(无法处理SSL)
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler
{
NSString *host = challenge.protectionSpace.host;
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
if ([host rangeOfString:@"yourHost.net"].location != NSNotFound)
{
completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
}
else
{
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge,nil);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.