NSURLConnection sendAsynchronousRequest需要身份验证,但NSURLConnection不是
我试图从服务器获取一些JSON
。当我想用便捷方法[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]
完成时,请求失败,请求失败,代码为,错误代码为-1012,表示“userCancelledAuthentication”。这将是好的,但没有来自该URL的身份验证挑战!制作与[NSURLConnection connectionWithRequest: delegate:]
作品的连接就好了,没有任何身份验证质询(I'm得到的回应,而不是委托调用-(void)connection:didReceiveAuthenticationChallenge:
)NSURLConnection sendAsynchronousRequest需要身份验证,但NSURLConnection不是
这真是奇怪,我因为使用了两个调用相同的请求I'm。 我试着直接在调用中分配队列,然后尝试使发送请求的对象保留全局队列。两者都没有使完成处理程序的异步请求工作。来自[NSURLConnection connectionWithRequest: delegate:]
的回应正是我所期望的。
有人可以解释为什么[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]
和[NSURLConnection connectionWithRequest: delegate:]
之间存在这种差异吗?
在下载过程中NSURLConnection connectionWithRequest: delegate:
的情况下,连接保持对委托的强烈引用。正如Apple文档所述,它会在连接完成加载,失败或取消时释放强大的引用。
另一方面,如果您使用NSURLConnection sendAsynchronousRequest:queue:completionHandler:
(如果需要进行身份验证以下载请求),则必须将所需凭据指定为URL的一部分。如果身份验证失败或缺少凭证,则连接将尝试继续,而无需凭据,也是根据Apple文档。
所以,你没有回应代表电话-(void)connection:didReceiveAuthenticationChallenge:
,因为没有认证是真的需要,这就是为什么NSURLConnection connectionWithRequest: delegate:
最适合这种情况。
我现在建立了一些解决方法,模仿NSURLConnection的sendAsynchronousRequest
方法。该文件在下面。应该很容易迁移现有的代码,因为块的参数是相同的,只有operationQueue不需要
由类方法分配的对象自己保留,直到请求结束。
的.H
#import <Foundation/Foundation.h>
@interface SNSPApiRequest : NSObject
+(void)startRequest:(NSURLRequest *)request withCompletionHandler:(void (^)(NSURLResponse *, NSData *, NSError *))requestFinished;
@end
的.M
#import "SNSPApiRequest.h"
@interface SNSPApiRequest()
@property NSURLConnection *connection;
@property (strong, nonatomic) void (^requestFinished)(NSURLResponse *response, NSData *responseData, NSError *error);
@property (strong, nonatomic) void (^deconstructSelf)();
@property (strong, nonatomic) NSURLResponse *response;
@property (strong, nonatomic) NSMutableData *data;
@end
@implementation SNSPApiRequest
+(void)startRequest:(NSURLRequest *)request withCompletionHandler:(void (^)(NSURLResponse *, NSData *, NSError *))requestFinished {
SNSPApiRequest *apirequest = [[SNSPApiRequest alloc] init];
apirequest.data = [[NSMutableData alloc] init];
apirequest.requestFinished = requestFinished;
apirequest.deconstructSelf = ^{apirequest.connection = nil;apirequest.response = nil;apirequest.data = nil;};
apirequest.connection = [[NSURLConnection alloc] initWithRequest:request delegate:apirequest];
}
#pragma mark - NSUrlConnectionDataDelegate
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.data appendData:data];
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
self.response = response;
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
self.requestFinished(self.response, self.data, nil);
self.deconstructSelf();
self.deconstructSelf = nil;
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
self.requestFinished(self.response, nil, error);
self.deconstructSelf();
self.deconstructSelf = nil;
}
感谢您的输入。虽然,也是一个像completionHandler一样传递的块,它仍然强烈引用其中代码所引用的对象。因为我不需要认证,所以'NSURLConnection sendAsynchronousRequest:queue:completionHandler:'应该也可以,不是吗?但这样做的请求失败。 – TAKeanice
是的,在文档中它也应该是可能的。发生的事情很奇怪。 – Winston
作为解决方法,我制作了自己的自我保留对象来镜像此功能。不过,我很想知道失败背后的原因 – TAKeanice