前言:蘋果官方提供的網絡請求API有兩種: NSURLConnection、NSURLSession。
還有,目前的用的最多是主流架構:AFNetworking
iOS 7之前,隻有 NSURLConncetion
iOS 9之後,蘋果官方放棄NSURLConnection,推薦使用NSURLSession
本文将介紹iOS原生API和AFN的使用。
蘋果官方API:
以下将分别講述這兩種請求的簡單使用:
- NSURLConnection:
-(void)demo1{
//通路百度首頁
//1. 建立一個網絡請求
NSURL *url = [NSURL URLWithString:@"http://m.baidu.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//2. 發送網絡請求 網絡請求是個耗時操作,在子線程發送
//第一種發送網絡請求的方式
/*
* 利用 NSUrlConnection 發送一個異步的網絡請求
*
* @param NSURLRequest 網絡請求
*
* @return
*/
//queue:操作隊列,決定網絡請求完成後的Block(completionHandler) 回調在那條線程執行
//[NSOperationQueue mainQueue] 主線程
//completionHandler :block 回調:網絡請求完成之後,就會自動調用這個 Block
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//response : 響應:伺服器的響應
//data:二進制資料:伺服器傳回的資料。(就是我們想要的内容)
//coonectionError:連結錯誤的資訊
NSLog(@"網絡響應:response:%@",response);
//根據傳回的二進制資料,生成字元串!NSUTF8StringEncoding:編碼方式
NSString *html = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
//在用戶端直接打開一個網頁!
//用戶端伺服器:UIWebView
//執行個體化一個用戶端浏覽器
UIWebView *web = [[UIWebView alloc]initWithFrame:self.view.bounds];
//加載html字元串:baseURL:基準的位址:相對路徑/絕對路徑
[web loadHTMLString:html baseURL:nil];
//将浏覽器加載到view上
[self.view addSubview:web];
// //在本地儲存百度首頁
// [data writeToFile:@"/Users/Liu/Desktop/baidu.html" atomically:YES];
NSLog(@"網路連結錯誤 connectionError響應:response:%@",connectionError);
}];
}
- NSURLSession:
//NSURLSession
-(void)demo2{
//通路百度首頁
//1. 建立一個網絡請求
NSURL *url = [NSURL URLWithString:@"http://m.baidu.com"];
//2.建立請求對象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.獲得會話對象
NSURLSession *session=[NSURLSession sharedSession];
//4.根據會話對象建立一個Task(發送請求)
/*
第一個參數:請求對象
第二個參數:completionHandler回調(請求完成【成功|失敗】的回調)
data:響應體資訊(期望的資料)
response:響應頭資訊,主要是對伺服器端的描述
error:錯誤資訊,如果請求失敗,則error有值
*/
NSURLSessionDataTask *dataTask=[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//response : 響應:伺服器的響應
//data:二進制資料:伺服器傳回的資料。(就是我們想要的内容)
//error:連結錯誤的資訊
NSLog(@"網絡響應:response:%@",response);
//根據傳回的二進制資料,生成字元串!NSUTF8StringEncoding:編碼方式
NSString *html = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
//在用戶端直接打開一個網頁!
//用戶端伺服器:UIWebView
//将浏覽器加載到view上
dispatch_async(dispatch_get_main_queue(), ^{
//執行個體化一個用戶端浏覽器
UIWebView *web = [[UIWebView alloc]initWithFrame:self.view.bounds];
//加載html字元串:baseURL:基準的位址:相對路徑/絕對路徑
[web loadHTMLString:html baseURL:nil];
[self.view addSubview:web];
});
// //在本地儲存百度首頁
// [data writeToFile:@"/Users/Liu/Desktop/baidu.html" atomically:YES];
}
];
//5.執行任務
[dataTask resume];
}
-
使用NSURLSession發送GET請求的方法和NSURLConnection類似,整個過程如下:
1)确定請求路徑(一般由公司的背景開發人員以接口文檔的方式提供),GET請求參數直接跟在URL後面
2)建立請求對象(預設包含了請求頭和請求方法【GET】),此步驟可以省略
3)建立會話對象(NSURLSession)
4)根據會話對象建立請求任務(NSURLSessionDataTask)
5)執行Task
6)當得到伺服器傳回的響應後,解析資料(XML|JSON|HTTP)
-
使用NSURLSession發送POST請求的方法和NSURLConnection類似,整個過程如下:
1)确定請求路徑(一般由公司的背景開發人員以接口文檔的方式提供)
2)建立可變的請求對象(因為需要修改),此步驟不可以省略
3)修改請求方法為POST
4)設定請求體,把參數轉換為二進制資料并設定請求體
5)建立會話對象(NSURLSession)
6)根據會話對象建立請求任務(NSURLSessionDataTask)
7)執行Task
8)當得到伺服器傳回的響應後,解析資料(XML|JSON|HTTP)
//post方法
//1.建立會話對象
NSURLSession *session=[NSURLSession sharedSession];
//2.根據會話對象建立task
NSURL *url=[NSURL URLWithString:@"http://123.207.175.144/Test1.php"];
//3.建立可變的請求對象
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];
//4.修改請求方法為POST
request.HTTPMethod=@"POST";
//5.設定請求體
request.HTTPBody=[@"Login=1" dataUsingEncoding:NSUTF8StringEncoding];
//6.根據會話對象建立一個Task(發送請求)
/*
第一個參數:請求對象
第二個參數:completionHandler回調(請求完成【成功|失敗】的回調)
data:響應體資訊(期望的資料)
response:響應頭資訊,主要是對伺服器端的描述
error:錯誤資訊,如果請求失敗,則error有值
*/
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error){
//8.解析資料
NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(@"%@",dict);
}];
//7.執行任務
[dataTask resume];
有的時候,我們可能需要監聽網絡請求的過程(如下載下傳檔案需監聽檔案下載下傳進度),那麼就需要用到代理方法。
//代理方法
#import "ViewController.h"
@interface ViewController ()<NSURLSessionDataDelegate>
@property (nonatomic, strong) NSMutableData *responseData;
@end
@implementation ViewController
-(NSMutableData *)responseData
{
if (_responseData == nil) {
_responseData = [NSMutableData data];
}
return _responseData;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//[self performSelector:@selector(getAndSynchronousMethod)];
[self delegateTest];
}
-(void)delegateTest
{
//1.确定請求路徑
NSURL *url = [NSURL URLWithString:@"http://123.207.175.144/Test1.php?Login=1"];
//2.建立請求對象
//請求對象内部預設已經包含了請求頭和請求方法(GET)
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.獲得會話對象,并設定代理
/*
第一個參數:會話對象的配置資訊defaultSessionConfiguration 表示預設配置
第二個參數:誰成為代理,此處為控制器本身即self
第三個參數:隊列,該隊列決定代理方法在哪個線程中調用,可以傳主隊列|非主隊列
[NSOperationQueue mainQueue] 主隊列: 代理方法在主線程中調用
[[NSOperationQueue alloc]init] 非主隊列: 代理方法在子線程中調用
*/
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
//4.根據會話對象建立一個Task(發送請求)
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
//5.執行任務
[dataTask resume];
}
//1.接收到伺服器響應的時候調用該方法
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
//在該方法中可以得到響應頭資訊,即response
NSLog(@"didReceiveResponse--%@",[NSThread currentThread]);
//注意:需要使用completionHandler回調告訴系統應該如何處理伺服器傳回的資料
//預設是取消的
/*
NSURLSessionResponseCancel = 0, 預設的處理方式,取消
NSURLSessionResponseAllow = 1, 接收伺服器傳回的資料
NSURLSessionResponseBecomeDownload = 2,變成一個下載下傳請求
NSURLSessionResponseBecomeStream 變成一個流
*/
completionHandler(NSURLSessionResponseAllow);
}
//2.接收到伺服器傳回資料的時候會調用該方法,如果資料較大那麼該方法可能會調用多次
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
NSLog(@"didReceiveData--%@",[NSThread currentThread]);
//拼接伺服器傳回的資料
[self.responseData appendData:data];
}
//3.當請求完成(成功|失敗)的時候會調用該方法,如果請求失敗,則error有值
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
NSLog(@"didCompleteWithError--%@",[NSThread currentThread]);
if(error == nil)
{
//解析資料
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:self.responseData options:kNilOptions error:nil];
NSLog(@"%@",dict);
}
}
@end
如果傳回的字元有漢字,可以為NSDictionary提供一個分類,重寫系統中的方法。
//重寫Dictionary
#import "NSDictionary+Log.h"
@implementation NSDictionary (Log)
-(NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level
{
//初始化可變字元串
NSMutableString *string = [NSMutableString string];
//拼接開頭[
[string appendString:@"["];
//拼接字典中所有的鍵值對
[self enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
[string appendFormat:@"%@:",key];
[string appendFormat:@"%@",obj];
}];
//拼接結尾]
[string appendString:@"]"];
return string;
}
@end
AFNetworking:
AFNetworking開源庫封裝了原生的方法,
iOS9.0之後,
由于NSURLConnection的棄用,
AFNetworking的使用也有一些改變。
注:使用前需要導入AFN架構:AFN架構位址
- GET請求:
//GET請求
-(void)demo1{
NSString *urlString = @"http://www.liubaiqi.cn";
AFHTTPSessionManager *manger =[AFHTTPSessionManager manager];
[manger GET:urlString parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"成功");
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@",error);
}];
}
- POST請求:
//POST請求
-(void)demo2{
NSString *urlString = @"http://192.168.1.101:8080";
AFHTTPSessionManager *manger =[AFHTTPSessionManager manager];
NSMutableDictionary *parameter= @{@"":@"",@"":@""};
[manger POST:urlString parameters:parameter progress:^(NSProgress * _NonnulluploadProgress){
}success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"成功");
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@",error);
}];
}
- Download請求:
//DownLoad請求
-(void)demo3{
//1. 建立NSURLSessionConfiguration
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
//2. 建立管理者對象
AFURLSessionManager *manager = [[AFURLSessionManager alloc]initWithSessionConfiguration:configuration];
//3. 設定url
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/1.mp4"];
//4. 建立請求對象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//5. 下載下傳任務
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
//列印下載下傳進度
NSLog(@"%lf",*downloadProgress.completedUnitCount/downloadProgress.totalUnitCount);
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
//設定下載下傳路徑
NSURL *documentsDirectoryURL = [[NSFileManager defaultManager]URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
//下載下傳完成
NSLog(@"File downloaded to : %@",filePath);
}];
//啟動任務
[downloadTask resume];
}
- Upload請求:
//UpLoad請求
-(void)demo4{
//建立NSURLSessionConfiguration
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
//建立管理者對象
AFURLSessionManager *manager = [[AFURLSessionManager alloc]initWithSessionConfiguration:configuration];
//設定url
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1"];
//建立請求對象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//檔案路徑
NSURL *filePath = [NSURL fileURLWithPath:@"file://Users/Liu/Desktop/Note"];
//上傳任務
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:filePath progress:nil completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if(error){
//錯誤
NSLog(@"Error:%@",error);
}else{
//成功
NSLog(@"Success %@ %@",response,responseObject);
}
}];
//啟動任務
[uploadTask resume];
}
- 網絡狀态:
//網絡狀态
-(void)demo5{
//1. 建立網絡監測者
AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
[manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
//監測網絡改變
switch (status) {
case AFNetworkReachabilityStatusUnknown:
NSLog(@"未知網絡狀态");
break;
case AFNetworkReachabilityStatusNotReachable:
NSLog(@"無網絡");
break;
case AFNetworkReachabilityStatusReachableViaWWAN:
NSLog(@"蜂窩資料網絡");
break;
case AFNetworkReachabilityStatusReachableViaWiFi:
NSLog(@"WiFi網絡");
break;
default:
break;
}
}];
}
本文參考了組長的blog,以及自己學習時整理的一些小demo。
如果有錯誤,希望各位大神指出,我修改。
作者:MrLiuQ
連結:https://www.jianshu.com/p/c34f0740f178
來源:簡書