最近需要發送https請求,所以就封裝了一個使用NSURLSession發起HTTPS請求的類,以post請求爲例看代碼。
首先在.h文件中會暴露出一個對象方法,用於發起post請求:
- (void)postRequstUrl:(NSString *)url andJsonParam:(NSString *)jsonParam;
然後會有一個代理用於接受網絡請求的結果:
@protocol FWHttpsDelegate <NSObject>
/**
https請求的結果
*/
- (void)postResponesData:(NSData *)data andUrlRespones:(NSURLResponse *) response andError:(NSError *)error;
@end
代理屬性:
@property (nonatomic,weak)id<FWHttpsDelegate> delegateHttps;
再看具體的實現:
第一步,你需要一個請求類Request,並設置Request的屬性:
NSMutableURLRequest * requst = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
//延時時間
requst.timeoutInterval = self.timeOut > 0? self.timeOut:30;
//請求方式
requst.HTTPMethod = @"POST";
NSData *data = [jsonParam dataUsingEncoding:NSUTF8StringEncoding];
//請求體
requst.HTTPBody = data;
第二步,你要創建一個存儲配置:
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
第三步,通信會話NSURLSession,你最好用NSURLSessionConfiguration,代理,線程來創建一個NSURLSession
NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
第四步,使用session,requst來創建個任務NSURLSessionDataTask:
NSURLSessionDataTask *task = [session dataTaskWithRequest:requst completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if ([self.delegateHttps respondsToSelector:@selector(postResponesData:andUrlRespones:andError:)]) {
[self.delegateHttps postResponesData:data andUrlRespones:response andError:error];
}
}];
最後不要忘了要開始任務:
[task resume];
好了,到了這裏就是一個最簡單的使用NSURLSession發起的post網絡請求了,但是這個明顯跟HTTPS無關,不要急下面我們就來實現個代理讓我們可以發起HTTPS請求。
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler
我自己測試過,很神奇的是這個代理只有當你請求的網絡地址是https的時候纔會調用,所以簡單了我們可以實現這個代理用來處理https網絡請求:
先認識幾個枚舉值,
NSURLSessionAuthChallengeUseCredential 使用證書
NSURLSessionAuthChallengePerformDefaultHandling 忽略證書 默認的做法
NSURLSessionAuthChallengeCancelAuthenticationChallenge 取消請求,忽略證書
NSURLSessionAuthChallengeRejectProtectionSpace 拒絕,忽略證書
簡單的思路是,如果有證書就使用證書,沒有證書就忽略證書,不多說了看代碼:
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler {
//證書的處理方式
NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
//網絡請求證書
__block NSURLCredential *credential = nil;
//判斷服務器返回的證書是否是服務器信任的
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { //受信任的
//獲取服務器返回的證書
credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
if (credential) {
disposition = NSURLSessionAuthChallengeUseCredential;
} else {
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
}
} else {
disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
}
//安裝證書
if (completionHandler) {
completionHandler(disposition, credential);
}
}