簡體   English   中英

NSURLConnection sendAsynchronousRequest想要身份驗證,但NSURLConnection不需要

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM