IOS學習筆記 -- 網路編程

來源:互聯網
上載者:User

標籤:des   http   使用   檔案   資料   os   

一.HTTP協議
1.面試題: 聊一下HTTP協議(表達對HTTP協議的看法)
* HTTP協議的全稱: 超文字傳輸通訊協定 (HTTP), 定製傳輸資料的規範(用戶端和伺服器之間的資料轉送規範)
* 描述HTTP協議完整的通訊過程

2.通訊過程
1> 請求
* 用戶端 --> 伺服器
* 請求的內容
a."請求行" : 要求方法\請求資源路徑\HTTP協議版本
GET /MJServer/login?username=123&pwd=123&method=get&type=JSON HTTP/1.1

b."要求標頭" : 用戶端的資訊
Host: 192.168.1.200:8080
User-Agent: iPhone Simulator; iPhone OS 7.1; en_US
Accept: text/html
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate

c."請求體" : POST請求才需要有, 存放具體資料
* 比如檔案資料
* 比如POST請求的參數資料

2> 響應
* 伺服器 --> 用戶端
* 響應的內容
a."狀態行" : HTTP協議版本\狀態代碼\狀態資訊, 也可稱為"響應行"
HTTP/1.1 200 OK

b."回應標頭" : 伺服器資訊\返回資料的類型\返回資料的長度
Server: Apache-Coyote/1.1
Content-Type: application/json;charset=UTF-8
Content-Length: 248

c."實體內容" : 返回給用戶端的具體內容, 也可稱為"響應體"
* 比如伺服器返回的JSON資料
* 比如伺服器返回的檔案資料

3.HTTP請求的方法
1> GET
* 參數都拼接在URL後面
* 參數有限制

2> POST
* 參數都在請求體
* 參數沒有限制
* 檔案上傳只能用POST

3> HEAD : 獲得回應標頭資訊, 不擷取響應體

4.iOS中發送GET\POST請求的手段
1> NSURLConnection
* 蘋果原生
* 使用起來, 比ASI\AFN複雜

2> ASI
* 基於CFNetwork
* 提供了非常多強大的功能, 使用簡單

3> AFN
* 基於NSURLConnection
* 提供了常用的功能, 使用簡單

4> 建議
* 為了提高開發效率和減少調試花費的時間, 盡量使用著名的簡單的第三方架構
* 因此, 處理HTTP請求, 更建議使用ASI後者AFN

二.NSURLConnection
1.發送請求
1> 發送一個同步請求
+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error;

2> 發送一個非同步請求(block)
+ (void)sendAsynchronousRequest:(NSURLRequest*) request
queue:(NSOperationQueue*) queue
completionHandler:(void (^)(NSURLResponse* response, NSData* data, NSError* connectionError)) handler;

3> 發送一個非同步請求(代理方法)
[NSURLConnection connectionWithRequest:request delegate:self];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
[[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];

NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[conn start];

2.檔案下載(大檔案下載)
1> 實現方案 : 邊下載邊寫入(寫到沙箱的某個檔案中)
2> 具體實現步驟
a. 在接收到伺服器的響應時
// 建立一個空檔案 - NSFileManager
[mgr createFileAtPath:self.destPath contents:nil attributes:nil];

// 建立一個跟空檔案相關聯的控制代碼對象 - NSFileHandle
[NSFileHandle fileHandleForWritingAtPath:self.destPath];

b. 在接收到伺服器的資料時
// 利用控制代碼對象將伺服器返回的資料寫到檔案的末尾
// 移動到檔案的尾部
[self.writeHandle seekToEndOfFile];
// 從當前移動的位置(檔案尾部)開始寫入資料
[self.writeHandle writeData:data];

c. 在接收完伺服器返回的資料時
// 關閉控制代碼
[self.writeHandle closeFile];
self.writeHandle = nil;

3.斷點下載
1> 關鍵技術點
* 佈建要求頭Range, 告訴伺服器下載哪一段資料

4.檔案上傳
1> 明確
* 只能用POST請求
* 請求參數都在請求體(檔案參數\非檔案類型的普通參數)

2> 實現步驟
a. 拼接請求體(檔案參數\非檔案類型的普通參數)
* 檔案參數
// 參數的開始標記(分割線)
--heima\r\n
// 參數描述(參數名...)
Content-Disposition: form-data; name="參數名"; filename="檔案名稱"\r\n
// 檔案類型
Content-Type: 檔案的類型MIMEType\r\n
// 檔案的位元據(參數值)
\r\n
檔案的位元據
\r\n

* 非檔案參數(普通參數)
// 參數的開始標記(分割線)
--heima\r\n
// 參數描述(參數名...)
Content-Disposition: form-data; name="參數名"\r\n
// 參數值
\r\n
參數值
\r\n

* 所有參數結束的標記
--heima--\r\n

b. 佈建要求頭
* 請求體的長度
Content-Length : 請求體的長度(位元組長度)

* 請求資料的類型
Content-Type :
// 普通POST請求: application/x-www-form-urlencoded
// 上傳檔案的POST請求 : multipart/form-data; boundary=--heima

5.JSON和XML
1>.JSON 轉換為 OC資料類型
在iOS中,JSON的常見解析方案有4種
第三方架構:JSONKit、SBJson、TouchJSON(效能從左至右,越差)
蘋果原生(內建):NSJSONSerialization(效能最好)
NSJSONSerialization的常見方法
JSON資料 -> OC對象
+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;
OC對象 -> JSON資料
+ (NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;
2>.XML 轉換為 OC資料類型
XML的解析方式有2種
DOM:一次性將整個XML文檔載入進記憶體,比較適合解析小檔案
SAX:從根項目開始,按順序一個元素一個元素往下解析,比較適合解析大檔案
蘋果原生
NSXMLParser:SAX方式解析,使用簡單
第三方架構
libxml2:純C語言,預設包含在iOS SDK中,同時支援DOM和SAX方式解析
GDataXML:DOM方式解析,由Google開發,基於libxml2
a. NSXMLParser
// 傳入XML資料,建立解析器
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
// 設定代理,監聽解析過程
parser.delegate = self;
// 開始解析
[parser parse];
// NSXMLParserDelegate
當掃描到文檔的開始時調用(開始解析)
- (void)parserDidStartDocument:(NSXMLParser *)parser
當掃描到文檔的結束時調用(解析完畢)
- (void)parserDidEndDocument:(NSXMLParser *)parser
當掃描到元素的開始時調用(attributeDict存放著元素的屬性)
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
當掃描到元素的結束時調用
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName

 

三.NSURLCache
緩衝的使用步驟
// 獲得全域的緩衝對象
NSURLCache *cache = [NSURLCache sharedURLCache];

// 設定緩衝容量
cache.memoryCapacity = 1024 * 1024;
cache.diskCapacity = 20 * 1024 * 1024;

// 佈建要求的緩衝策略
request.cachePolicy = NSURLRequestReturnCacheDataElseLoad;

四.ASI
1.緩衝的使用步驟
1> 緩衝單個請求
// 1.獲得全域的緩衝對象(決定緩衝的儲存路徑, 儲存到什麼地方)
ASIDownloadCache *cache = [ASIDownloadCache sharedCache];
// 設定預設的緩衝載入策略
cache.defaultCachePolicy = ASIDoNotReadFromCacheCachePolicy;

// 2.佈建要求對象的緩衝對象(使用哪個緩衝對象)
request.downloadCache = cache;

// 3.佈建要求對象的緩衝載入策略
request.cachePolicy = ASIOnlyLoadIfNotCachedCachePolicy;
// 如果沒有緩衝, 才發送請求

// 4.佈建要求對象的緩衝儲存策略(儲存的時間長度)
request.cacheStoragePolicy = ASICachePermanentlyCacheStoragePolicy;
// 永久儲存

注意, 緩衝載入策略的優先順序 : request.cachePolicy > cache.defaultCachePolicy

2> 緩衝所有請求
// 1.獲得全域的緩衝對象(決定緩衝的儲存路徑, 儲存到什麼地方)
ASIDownloadCache *cache = [ASIDownloadCache sharedCache];
// 設定預設的緩衝載入策略
cache.defaultCachePolicy = ASIOnlyLoadIfNotCachedCachePolicy;

// 2.設定全域緩衝對象
[ASIHTTPRequest setDefaultCache:cache];

2.發送請求
1> 同步請求
[request startSynchronous];

2> 非同步請求
[request startAsynchronous];

3.GET\POST
1> GET請求
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];

2> POST請求
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
// 添加普通參數(非檔案參數)
[request setPostValue:@"zhangsan" forKey:@"username"];
[request setPostValue:@"123" forKey:@"pwd"];

4.檔案下載
// 檔案的儲存路徑(檔案下載到什麼地方)
request.downloadDestinationPath = filepath;
// 設定下載代理(監聽下載進度)
request.downloadProgressDelegate = self.circleView;
// 支援斷點下載
request.allowResumeForFileDownloads = YES;

5.檔案上傳
// 添加檔案參數(file : 需要上傳檔案的路徑)
[request setFile:file forKey:@"file"];
[request setFile:file withFileName:@"123.txt" andContentType:@"text/plain" forKey:@"file"];
[request setData:data withFileName:@"minion.png" andContentType:@"image/png" forKey:@"file"];

// 設定上傳代理(監聽上傳進度)
request.uploadProgressDelegate = self.circleView;

6.監聽請求的過程
1> 代理方法
// 設定代理
request.delegate = self;
// 遵守協議
ASIHTTPRequestDelegate
// 實現協議中的代理方法
- (void)requestStarted:(ASIHTTPRequest *)request;
- (void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data
- (void)requestFinished:(ASIHTTPRequest *)request;
- (void)requestFailed:(ASIHTTPRequest *)request;

2> SEL
// 設定代理
request.delegate = self;
// 設定方法名
[request setDidStartSelector:@selector(start)]; // 開始發送請求, 就會調用代理的start方法
// ....

3> block
[request setStartedBlock:^{
NSLog(@"setStartedBlock ----");
}];

[request setDataReceivedBlock:^(NSData *data) {
NSLog(@"setDataReceivedBlock ----");
}];

[request setCompletionBlock:^{
NSLog(@"setCompletionBlock ----");
}];

[self setFailedBlock:^{
NSLog(@"setFailedBlock ----");
}];

7.通過request對象獲得伺服器的響應
1> 獲得回應標頭資訊
@property (atomic, retain) NSDictionary *responseHeaders;

2> 獲得響應體(實體內容)
- (NSData *)responseData; // 直接返回伺服器的位元據
- (NSString *)responseString; // 將位元據轉成字串(方便調試)

五.AFN
1.GET\POST
1> GET請求
// 1.獲得要求管理者
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];

// 2.封裝請求參數
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"username"] = @"123";
params[@"pwd"] = @"123";

// 3.發送GET請求
[mgr GET:@"http://192.168.1.200:8080/MJServer/login" parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"請求成功---%@", responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"請求失敗---%@", error);
}];


2> POST請求
// 1.獲得要求管理者
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];

// 2.封裝請求參數
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"username"] = @"123";
params[@"pwd"] = @"123";

// 3.發送POST請求
[mgr POST:@"http://192.168.1.200:8080/MJServer/login" parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"請求成功---%@", responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"請求失敗---%@", error);
}];

2.檔案上傳
// 1.獲得要求管理者
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];

// 2.發送請求(做檔案上傳)
#warning parameters : 只能放非檔案參數
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"username"] = @"zhangsan";

[mgr POST:@"http://192.168.1.200:8080/MJServer/upload" parameters:params
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
// 一定要在這個block中添加檔案參數

// 負載檔案資料
NSString *file = [[NSBundle mainBundle] pathForResource:@"test.txt" ofType:nil];
NSData *data = [NSData dataWithContentsOfFile:file];

// 拼接檔案參數
[formData appendPartWithFileData:data name:@"file" fileName:@"123.txt" mimeType:@"text/plain"];
}
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"上傳成功----%@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"上傳失敗----%@", error);
}];

六.網路狀態監控
1.Reachability
// 監聽網路狀態改變的通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkStateChange) name:kReachabilityChangedNotification object:nil];

// 建立Reachability
self.conn = [Reachability reachabilityForInternetConnection];
// 開始監控網路(一旦網路狀態發生改變, 就會發出通知kReachabilityChangedNotification)
[self.conn startNotifier];

// 處理網路狀態改變
- (void)networkStateChange
{
// 1.檢測wifi狀態
Reachability *wifi = [Reachability reachabilityForLocalWiFi];

// 2.檢測手機是否能上網路(WIFI\3G\2.5G)
Reachability *conn = [Reachability reachabilityForInternetConnection];

// 3.判斷網路狀態
if ([wifi currentReachabilityStatus] != NotReachable) { // 有wifi
NSLog(@"有wifi");
} else if ([conn currentReachabilityStatus] != NotReachable) { // 沒有使用wifi, 使用手機內建網路進行上網
NSLog(@"使用手機內建網路進行上網");
} else { // 沒有網路
NSLog(@"沒有網路");
}
}

2.AFN
// 1.獲得網路監控的管理者
AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];

// 2.設定網路狀態改變後的處理
[mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
// 當網路狀態改變了, 就會調用這個block
switch (status) {
case AFNetworkReachabilityStatusUnknown: // 未知網路
NSLog(@"未知網路");
break;

case AFNetworkReachabilityStatusNotReachable: // 沒有網路(斷網)
NSLog(@"沒有網路(斷網)");
break;

case AFNetworkReachabilityStatusReachableViaWWAN: // 手機內建網路
NSLog(@"手機內建網路");
break;

case AFNetworkReachabilityStatusReachableViaWiFi: // WIFI
NSLog(@"WIFI");
break;
}
}];

// 3.開始監控
[mgr startMonitoring];

七.ASI和AFN有什麼區別
1.效能(重點)
* ASI基於底層的CFNetwork架構
* AFN基於NSURLConnection
* 運行效能: ASI > ASN

2.處理伺服器資料
1> AFN : 根據伺服器返回資料的資料, 進行自動解析
* 伺服器返回的是JSON資料, 自動轉換為NSDictionary或者NSArray
* 伺服器返回的是XML資料, 自動轉換為NSXMLParser

2> ASI : 並沒有對伺服器的資料進行解析, 直接返回NSData位元據

3.處理請求的過程
1> AFN : success和failure兩個block
2> ASI : 有3種方式處理請求過程(代理方法\SEL\block)

3.ASI的特色(重點)
1> 緩衝

2> 下載和上傳
* 輕鬆監聽請求進度
* 輕鬆實現斷點下載(ASI沒有斷點上傳功能, 斷點上傳得使用socket技術)

3> 提供了很多擴充介面(比如做資料壓縮)
* ASIDataCompressor.h
* ASIDataDecompressor.h

4> ASIHttpRequest繼承自NSOperation
* 能用隊列統一管理所有請求
* 請求之間能依賴

5> ASINetworkQueue
* 統一管理所有請求
* 5個下載\上傳請求 --> ASINetworkQueue : 監聽5個請求的總進度
* 監聽所有請求的開始\失敗\完畢
* shouldCancelAllRequestsOnFailure
YES : 隊列中某個請求失敗了, 其他所有請求都取消
NO : 隊列中的某個請求失敗了, 其他請求不受影響, 繼續請求

4.AFN的特色
1> 使用簡單
2> 內建了網路監控功能

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.