Ios NSURLConnection sendAsynchronousRequest需要身份验证,但NSURLConnection不需要

Ios NSURLConnection sendAsynchronousRequest需要身份验证,但NSURLConnection不需要,ios,objective-c,web-services,nsurlconnection,Ios,Objective C,Web Services,Nsurlconnection,我试图从服务器上获取一些JSON。当我想用便利方法[NSURLConnection sendAsynchronousRequest:queue:completionHandler://code>完成该操作时,请求失败,错误代码为-1012,这意味着“UserCanceledAuthentication”。那没关系,但是没有来自该URL的身份验证挑战!使用[NSURLConnection connectionWithRequest:delegate:建立连接工作正常,没有任何身份验证质询(我收到了

我试图从服务器上获取一些
JSON
。当我想用便利方法
[NSURLConnection sendAsynchronousRequest:queue:completionHandler://code>完成该操作时,请求失败,错误代码为-1012,这意味着“UserCanceledAuthentication”。那没关系,但是没有来自该URL的身份验证挑战!使用
[NSURLConnection connectionWithRequest:delegate:
建立连接工作正常,没有任何身份验证质询(我收到了响应,但不是委托调用
-(void)连接:didReceiveAuthenticationChallenge:

这对我来说真的很奇怪,因为我对两个调用都使用相同的请求。 我尝试直接在调用内部分配队列,然后尝试使发送请求的对象保留一个全局队列。两者都没有使带有完成处理程序的异步请求工作。
[NSURLConnection connectionWithRequest:delegate:
调用的响应正是我所期望的


有人能解释一下为什么
[NSURLConnection sendAsynchronousRequest:queue:completionHandler:][/code>和
[NSURLConnection connectionWithRequest:delegate:]

如果是
NSURLConnection connectionWithRequest:delegate:
下载过程中,连接会保持对委托的强引用。正如Apple文档所述,当连接完成加载、失败或被取消时,它会释放强引用

另一方面,如果使用
NSURLConnection sendAsynchronousRequest:queue:completionHandler:
如果下载请求需要身份验证,则必须将所需凭据指定为URL的一部分。如果身份验证失败,或者凭据丢失,连接将尝试在没有凭据的情况下继续,这也是根据Apple docs的说法


因此,您没有响应委托调用
-(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

谢谢你的意见。不过,还有一个块(如作为completionHandler传递的块)维护对其中代码引用的对象的强引用。因为我不需要身份验证,
NSURLConnection sendAsynchronousRequest:queue:completionHandler:
也应该可以,不是吗?但是这样做的请求失败了。是的,根据文档,这也应该是可能的。现在发生的事情很奇怪。作为一种解决方法,我制作了自己的自保留对象来镜像这个功能。尽管如此,我还是很想找出失败背后的原因。事实上,这件事也开始困扰我。。。但是也许它就是这样设计的。谢谢:D因为我没有找到关于这个方法的任何其他线索,我认为我只是疯了,或者解决方案太简单了。如果你想,我可以给你代码,我用来镜像功能。它甚至不需要操作队列
#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;
}