![](/img/trans.png)
[英]Authentication with NSURLConnection sendAsynchronousRequest with completion handler
[英]NSURLConnection sendAsynchronousRequest wants authentication but NSURLConnection not
我正在嘗試從服務器獲取一些JSON
。 當我想使用便捷方法[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]
此操作時,請求將失敗, 錯誤代碼為-1012 ,表示“ userCancelledAuthentication ”。 可以,但是該URL不會進行身份驗證! 使用[NSURLConnection connectionWithRequest: delegate:]
就可以了,沒有任何身份驗證挑戰(我得到了響應,但沒有委托調用-(void)connection:didReceiveAuthenticationChallenge:
這對我來說真的很奇怪,因為我對兩個電話都使用相同的請求。 我嘗試直接在調用內部分配隊列,然后嘗試使發送請求的對象保留一個全局隊列。 兩者均未通過完成處理程序進行異步請求。 [NSURLConnection connectionWithRequest: delegate:]
調用的響應正是我所期望的。
誰能解釋一下[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]
和[NSURLConnection connectionWithRequest: delegate:]
之間為什么有區別?
在使用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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.