2014-04-15 50 views
0

我试图从服务器获取一些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:]之间存在这种差异吗?

回答

0

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

另一方面,如果您使用NSURLConnection sendAsynchronousRequest:queue:completionHandler:(如果需要进行身份验证以下载请求),则必须将所需凭据指定为URL的一部分。如果身份验证失败或缺少凭证,则连接将尝试继续,而无需凭据,也是根据Apple文档。

所以,你没有回应代表电话-(void)connection:didReceiveAuthenticationChallenge:,因为没有认证是真的需要,这就是为什么NSURLConnection connectionWithRequest: delegate:最适合这种情况。

+0

感谢您的输入。虽然,也是一个像completionHandler一样传递的块,它仍然强烈引用其中代码所引用的对象。因为我不需要认证,所以'NSURLConnection sendAsynchronousRequest:queue:completionHandler:'应该也可以,不是吗?但这样做的请求失败。 – TAKeanice

+0

是的,在文档中它也应该是可能的。发生的事情很奇怪。 – Winston

+0

作为解决方法,我制作了自己的自我保留对象来镜像此功能。不过,我很想知道失败背后的原因 – TAKeanice

0

我现在建立了一些解决方法,模仿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; 
} 
相关问题