2014-04-15 49 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; 
} 
相關問題