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的解決方案】:https://kunnan.blog.csdn.net/article/details/78148401

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