iOS小技能:1. iOS 實現json資料提交 2. 對同一個URL的多次請求進行資料快取 3. 檢查網路狀態

語言: CN / TW / HK

“我正在參加「掘金·啟航計劃」”

前言

iOS 實現json資料提交(傳送JSON資料給伺服器)

1.一定要使用POST請求

2.設定請求頭 [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

3.設定JSON資料為請求體

I NSURLConnection 基本使用

1.1 常用類

NSURL:請求地址 NSURLRequest:一個NSURLRequest物件就代表一個請求,它包含的資訊有:一個NSURL物件請求方法;請求頭、請求體;請求超時… … NSMutableURLRequest:NSURLRequest的子類 NSURLConnection:負責傳送請求,建立客戶端和伺服器的連線;傳送NSURLRequest的資料給伺服器,並收集來自伺服器的響應資料

1.2NSURLConnection的使用步驟

``` 建立一個NSURL物件,設定請求路徑 傳入NSURL建立一個NSURLRequest物件,設定請求頭和請求體 使用NSURLConnection傳送NSURLRequest

```

1.3 NSURLConnection傳送請求

NSURLConnection常見的傳送請求方法有以下幾種 - 1)同步請求

objectivec + (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error;

  • 2)非同步請求:根據對伺服器返回資料的處理方式的不同,又可以分為2種: block回撥

objectivec + (void)sendAsynchronousRequest:(NSURLRequest*) request queue:(NSOperationQueue*) queue completionHandler:(void (^)(NSURLResponse* response, NSData* data, NSError* connectionError)) handler;

採用block的好處:網路請求準備和處理返回資料的程式碼比較集中。靈活(block可以作為引數)。不用像代理一樣實現多個協議方法。

  • 代理

```objectivec - (id)initWithRequest:(NSURLRequest)request delegate:(id)delegate; + (NSURLConnection)connectionWithRequest:(NSURLRequest)request delegate:(id)delegate; - (id)initWithRequest:(NSURLRequest)request delegate:(id)delegate startImmediately:(BOOL)startImmediately;//在startImmediately = NO的情況下,需要呼叫start方法開始傳送請求- (void)start; //成為NSURLConnection的代理,最好遵守NSURLConnectionDataDelegate協議 @protocol NSURLConnectionDataDelegate @optional - (nullable NSURLRequest )connection:(NSURLConnection )connection willSendRequest:(NSURLRequest )request redirectResponse:(nullable NSURLResponse )response;// - (void)connection:(NSURLConnection )connection didReceiveResponse:(NSURLResponse )response;//開始接收到伺服器的響應時呼叫 - (void)connection:(NSURLConnection )connection didReceiveData:(NSData )data;//接收到伺服器返回的資料時呼叫(伺服器返回的資料比較大時會呼叫多次)

  • (nullable NSInputStream )connection:(NSURLConnection )connection needNewBodyStream:(NSURLRequest *)request;
  • (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite;
  • (nullable NSCachedURLResponse )connection:(NSURLConnection )connection willCacheResponse:(NSCachedURLResponse *)cachedResponse;
  • (void)connectionDidFinishLoading:(NSURLConnection *)connection;//伺服器返回的資料完全接收完畢後呼叫 @end

@protocol NSURLConnectionDelegate @optional - (void)connection:(NSURLConnection )connection didFailWithError:(NSError )error;//請求出錯時呼叫(比如請求超時) ```

1.4 iOS 實現json資料提交


API

objectivec /設定請求超時等待時間(超過這個時間就算超時,請求失敗) - (void)setTimeoutInterval:(NSTimeInterval)seconds; //設定請求方法(比如GET和POST) - (void)setHTTPMethod:(NSString*)method; //設定請求體 - (void)setHTTPBody:(NSData*)data; //設定請求頭 - (void)setValue:(NSString*)value forHTTPHeaderField:(NSString*)field;

建立POST請求

```objectivec NSString urlStr = @"http://192.168.1.102:8080/MJServer/login"; NSURL url = [NSURL URLWithString:urlStr]; NSMutableURLRequest request = [NSMutableURLRequest requestWithURL:url]; request.HTTPMethod = @"POST"; // 請求體 NSString bodyStr = @"username=123&pwd=123";

request.HTTPBody = [bodyStr dataUsingEncoding:NSUTF8StringEncoding]; ```

傳送JSON給伺服器

objectivec //1.一定要使用POST請求 //2.設定請求頭 [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; //3.設定JSON資料為請求體

多值引數

objectivec 有時候一個引數名,可能會對應多個值 http://192.168.1.103:8080/KNServer/weather?place=北京&place=河南&place=湖南 伺服器的place屬性是一個數組*/

II NSURLCache

2.1 快取的實現:

一般只對GET請求進行快取,不必對POST請求進行快取:

GET請求一般用來查詢資料;POST請求一般是發大量資料給伺服器處理(變動性比較大)

在iOS中,可以使用NSURLCache類快取資料:

iOS 5之前:只支援 記憶體快取;i

OS 5開始:同時支援 記憶體快取 和 硬碟快取

  • 快取原理:一個NSURLRequest對應一個NSCachedURLResponse
  • 快取技術:資料庫

2.2 NSURLCache的常見用法

```objectivec //獲得全域性快取物件(沒必要手動建立) NSURLCache *cache = [NSURLCache sharedURLCache]; //設定記憶體快取的最大容量(位元組為單位,預設為512KB) - (void)setMemoryCapacity:(NSUInteger)memoryCapacity; //設定硬碟快取的最大容量(位元組為單位,預設為10M) - (void)setDiskCapacity:(NSUInteger)diskCapacity; //硬碟快取的位置:沙盒/Library/Caches

//取得某個請求的快取 - (NSCachedURLResponse )cachedResponseForRequest:(NSURLRequest)request; //清除某個請求的快取 - (void)removeCachedResponseForRequest:(NSURLRequest*)request; //清除所有的快取 - (void)removeAllCachedResponses;

/例子/ //要想對某個GET請求進行資料快取,非常簡單 NSMutableURLRequest request = [NSMutableURLRequest requestWithURL:url]; // 設定快取策略 request.cachePolicy = NSURLRequestReturnCacheDataElseLoad;//只要設定了快取策略,系統會自動利用NSURLCache進行資料快取 / 快取策略 iOS對NSURLRequest提供了7種快取策略:(實際上能用的只有3種) NSURLRequestUseProtocolCachePolicy // 預設的快取策略(取決於協議) NSURLRequestReloadIgnoringLocalCacheData // 忽略快取,重新請求---1 NSURLRequestReloadIgnoringLocalAndRemoteCacheData // 未實現 NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData // 忽略快取,重新請求 NSURLRequestReturnCacheDataElseLoad// 有快取就用快取,沒有快取就重新請求--2 NSURLRequestReturnCacheDataDontLoad// 有快取就用快取,沒有快取就不發請求,當做請求出錯處理(用於離線模式)---3 NSURLRequestReloadRevalidatingCacheData // 未實現

*/

```

2.3 使用快取的注意事項


  • 1.如果請求某個URL的返回資料:

``` 經常更新:不能用快取!比如股票、彩票資料 一成不變:果斷用快取 偶爾更新:可以定期更改快取策略 或者 清除快取

```

  • 2.如果大量使用快取,會越積越大,建議:定期清除快取

III Reachability

3.1 檢查網路狀態:

蘋果官方提供了一個叫Reachability的示例程式,便於開發者檢測網路狀態

根據使用者的網路狀態進行智慧處理,節省使用者流量,提高使用者體驗;--------WIFI\3G網路:自動下載高清圖片;----低速網路:只下載縮圖;—沒有網路:只顯示離線的快取資料

3.2 Reachability的使用步驟

新增框架SystemConfiguration.framework----

新增原始碼(Reachability.h\Reachability.m)---包含標頭檔案:#import "Reachability.h"

```objectivec // 是否WIFI + (BOOL) IsEnableWIFI { return ([[Reachability reachabilityForLocalWiFi] currentReachabilityStatus] != NotReachable); } // 是否3G + (BOOL) IsEnable3G { return ([[Reachability reachabilityForInternetConnectionen] currentReachabilityStatus] != NotReachable); }

//網路監控 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name: kReachabilityChangedNotification object: nil]; self.netReachability = [Reachability reachabilityForInternetConnection]; [self.netReachability startNotifier]; - (void)dealloc{ [self.netReachability stopNotifier];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kReachabilityChangedNotification object:nil];

} ```

see also

公號:iOS逆向

其他相關的文章:

  1. iOS接收json格式【 unacceptable content-type: text/plain的解決方案】:http://kunnan.blog.csdn.net/article/details/78148401

  2. iOS實現key=value&key=value形式的資料提交【Post 提交請求資料格式為application/x-www-form-urlencoded的方案】(基於AFNetworkSDK):http://kunnan.blog.csdn.net/article/details/77128793