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