#import "ViewController.h" @interface ViewController ()<NSURLConnectionDataDelegate> /** 註釋 */ @property (nonatomic, strong) NSMutableData *resultData; @end @implementation ViewController #pragma mark ---------------------- #pragma mark lazy loading -(NSMutableData *)resultData { if (_resultData == nil) { _resultData = [NSMutableData data]; } return _resultData; } #pragma mark ---------------------- #pragma mark Events -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [self delegate]; } /* 請求:請求頭(NSURLRequest默認包含)+請求體(GET沒有) 響應:響應頭(真實類型--->NSHTTPURLResponse)+響應體(要解析的數據) */ #pragma mark ---------------------- #pragma mark Methods -(void)sync { /* GET:http://120.25.226.186:32812/login?username=123&pwd=456&type=JSON 協議+主機地址+接口名稱+?+參數1&參數2&參數3 post:http://120.25.226.186:32812/login 協議+主機地址+接口名稱 */ //GET,沒有請求體 //1.肯定請求路徑 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"]; //2.建立請求對象 //請求頭不須要設置(默認的請求頭) //請求方法--->默認爲GET NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url]; //3.發送請求 //真實類型:NSHTTPURLResponse NSHTTPURLResponse *response = nil; /* 第一個參數:請求對象 第二個參數:響應頭信息 第三個參數:錯誤信息 返回值:響應體 */ //該方法是阻塞的,即若是該方法沒有執行完則後面的代碼將得不到執行 NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil]; //4.解析 data--->字符串 //NSUTF8StringEncoding NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]); NSLog(@"%zd",response.statusCode); } -(void)async { //1.肯定請求路徑 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"]; //2.建立請求對象 //請求頭不須要設置(默認的請求頭) NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url]; //3.發送異步請求 /* 第一個參數:請求對象 第二個參數:隊列 決定代碼塊completionHandler的調用線程 第三個參數:completionHandler 當請求完成(成功|失敗)的時候回調 response:響應頭 data:響應體 connectionError:錯誤信息 */ [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc]init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { //4.解析數據 NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]); NSHTTPURLResponse *res = (NSHTTPURLResponse *)response; NSLog(@"%zd",res.statusCode); NSLog(@"%@",[NSThread currentThread]); }]; } -(void)delegate { //1.肯定請求路徑 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=123&pwd=123&type=JSON"]; //2.建立請求對象 NSURLRequest *request = [NSURLRequest requestWithURL:url]; //3.設置代理,發送請求 //3.1 //[NSURLConnection connectionWithRequest:request delegate:self]; //3.2 //[[NSURLConnection alloc]initWithRequest:request delegate:self]; //3.3 設置代理,時候發送請求須要檢查startImmediately的值 //(startImmediately == YES 會發送 | startImmediately == NO 則須要調用start方法) NSURLConnection * connect = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO]; //調用開始方法 [connect start]; // [connect cancel];//取消 } #pragma mark ---------------------- #pragma mark NSURLConnectionDataDelegate //1.當接收到服務器響應的時候調用 -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { NSLog(@"%s",__func__); } //2.接收到服務器返回數據的時候調用,調用屢次 -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { NSLog(@"%s",__func__); //拼接數據 [self.resultData appendData:data]; } //3.當請求失敗的時候調用 -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { NSLog(@"%s",__func__); } //4.請求結束的時候調用 -(void)connectionDidFinishLoading:(NSURLConnection *)connection { NSLog(@"%s",__func__); NSLog(@"%@",[[NSString alloc]initWithData:self.resultData encoding:NSUTF8StringEncoding]); } @end
二:POST請求ios
#import "ViewController.h" @interface ViewController () @end @implementation ViewController -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [self post]; } -(void)post { //1.肯定請求路徑 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"]; //2.建立可變請求對象 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //3.修改請求方法,POST必須大寫 request.HTTPMethod = @"POST"; //設置屬性,請求超時 request.timeoutInterval = 10; //設置請求頭User-Agent //注意:key必定要一致(用於傳遞數據給後臺) [request setValue:@"ios 10.1" forHTTPHeaderField:@"User-Agent"]; //4.設置請求體信息,字符串--->NSData request.HTTPBody = [@"username=520it&pwd=123&type=JSON" dataUsingEncoding:NSUTF8StringEncoding]; //5.發送請求 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { //6.解析數據,NSData --->NSString NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]); }]; } @end
###0 補充(static)服務器
static關鍵字會在聲明變量的時候分配內存,在程序運行期間只分配一次內存。以後再訪問時,實際都是在訪問原先分配的內存網絡
若是使用static來修飾局部變量,那麼局部變量在代碼塊結束後將不會回收,下次使用保持上次使用後的值。app
若是使用static來修飾全局變量,那麼表示該全局變量只在本文件中有效,外界沒法使用extern來引用。static變量的做用域被限制在定義變量的當前文件中,其它文件是不能訪問的。框架
####1.NSURLConnection使用異步
- 1.1 NSURLConnection同步請求(GET)async
(1)步驟ide
01 設置請求路徑post
02 建立請求對象(默認是GET請求,且已經默認包含了請求頭)atom
03 使用NSURLSession sendsync方法發送網絡請求
04 接收到服務器的響應後,解析響應體
(2)相關代碼
```objc
//1.肯定請求路徑
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=XML"];
// NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=XML"];
//2.建立一個請求對象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.把請求發送給服務器
//sendSynchronousRequest 阻塞式的方法,會卡住線程
NSHTTPURLResponse *response = nil;
NSError *error = nil;
/*
第一個參數:請求對象
第二個參數:響應頭信息,當該方法執行完畢以後,該參數被賦值
第三個參數:錯誤信息,若是請求失敗,則error有值
*/
//該方法是阻塞式的,會卡住線程
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
//4.解析服務器返回的數據
NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
```
- 1.2 NSURLConnection異步請求(GET-SendAsync)
(1)相關說明
01 該方法不會卡住當前線程,網絡請求任務是異步執行的
(2)相關代碼
```objc
//1.肯定請求路徑
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it"];
//2.建立一個請求對象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.把請求發送給服務器,發送一個異步請求
/*
第一個參數:請求對象
第二個參數:回調方法在哪一個線程中執行,若是是主隊列則block在主線程中執行,非主隊列則在子線程中執行
第三個參數:completionHandlerBlock塊:接受到響應的時候執行該block中的代碼
response:響應頭信息
data:響應體
connectionError:錯誤信息,若是請求失敗,那麼該參數有值
*/
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc]init] completionHandler:^(NSURLResponse * __nullable response, NSData * __nullable data, NSError * __nullable connectionError) {
//4.解析服務器返回的數據
NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
//轉換並打印響應頭信息
NSHTTPURLResponse *r = (NSHTTPURLResponse *)response;
NSLog(@"--%zd---%@--",r.statusCode,r.allHeaderFields);
}];
```
- 1.3 NSURLConnection異步請求(GET-代理)
(1)步驟
01 肯定請求路徑
02 建立請求對象
03 建立NSURLConnection對象並設置代理
04 遵照NSURLConnectionDataDelegate協議,並實現相應的代理方法
05 在代理方法中監聽網絡請求的響應
(2)設置代理的幾種方法
```objc
/*
設置代理的第一種方式:自動發送網絡請求
[[NSURLConnection alloc]initWithRequest:request delegate:self];
*/
/*
設置代理的第二種方式:
第一個參數:請求對象
第二個參數:誰成爲NSURLConnetion對象的代理
第三個參數:是否立刻發送網絡請求,若是該值爲YES則馬上發送,若是爲NO則不會發送網路請求
NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO];
//調用該方法控制網絡請求的發送
[conn start];
*/
//設置代理的第三種方式:使用類方法設置代理,會自動發送網絡請求
NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self];
//取消網絡請求
//[conn cancel];
```
(3)相關的代理方法
```objc
/*
1.當接收到服務器響應的時候調用
第一個參數connection:監聽的是哪一個NSURLConnection對象
第二個參數response:接收到的服務器返回的響應頭信息
*/
- (void)connection:(nonnull NSURLConnection *)connection didReceiveResponse:(nonnull NSURLResponse *)response
/*
2.當接收到數據的時候調用,該方法會被調用屢次
第一個參數connection:監聽的是哪一個NSURLConnection對象
第二個參數data:本次接收到的服務端返回的二進制數據(多是片斷)
*/
- (void)connection:(nonnull NSURLConnection *)connection didReceiveData:(nonnull NSData *)data
/*
3.當服務端返回的數據接收完畢以後會調用
一般在該方法中解析服務器返回的數據
*/
-(void)connectionDidFinishLoading:(nonnull NSURLConnection *)connection
/*4.當請求錯誤的時候調用(好比請求超時)
第一個參數connection:NSURLConnection對象
第二個參數:網絡請求的錯誤信息,若是請求失敗,則error有值
*/
- (void)connection:(nonnull NSURLConnection *)connection didFailWithError:(nonnull NSError *)error
```
(4)其它知識點
```objc
01 關於消息彈窗第三方框架的使用
SVProgressHUD
02 字符串截取相關方法
- (NSRange)rangeOfString:(NSString *)searchString;
- (NSString *)substringWithRange:(NSRange)range;
```
- 1.4 NSURLConnection發送POST請求
(1)發送POST請求步驟
a.肯定URL路徑
b.建立請求對象(可變對象)
c.修改請求對象的方法爲POST,設置請求體(Data)
d.發送一個異步請求
e.補充:設置請求超時,處理錯誤信息,設置請求頭(如獲取客戶端的版本等等,請求頭是可設置可不設置的)
(2)相關代碼
```objc
//1.肯定請求路徑
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"];
//2.建立請求對象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//2.1更改請求方法
request.HTTPMethod = @"POST";
//2.2設置請求體
request.HTTPBody = [@"username=520it&pwd=520it" dataUsingEncoding:NSUTF8StringEncoding];
//2.3請求超時
request.timeoutInterval = 5;
//2.4設置請求頭
[request setValue:@"ios 9.0" forHTTPHeaderField:@"User-Agent"];
//3.發送請求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * __nullable response, NSData * __nullable data, NSError * __nullable connectionError) {
//4.解析服務器返回的數據
if (connectionError) {
NSLog(@"--請求失敗-");
}else
{
NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
}
}];
```
- 1.5 URL中文轉碼問題
```objc
//1.肯定請求路徑
NSString *urlStr = @"http://120.25.226.186:32812/login2?username=小碼哥&pwd=520it";
NSLog(@"%@",urlStr);
//中文轉碼操做
urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@",urlStr);
NSURL *url = [NSURL URLWithString:urlStr];
```