NSURL
:请求地址
NSURLRequest
:一个
NSURLRequest
对象就代表一个请求,它包含的信息有
一个
NSURL
对象
请求方法、请求头、请求体
请求超时
NSMutableURLRequest
:
NSURLRequest
的子类
NSURLConnection
负责发送请求
,
建立客户端和服务器的连接
发送
NSURLRequest
的数据给服务器,并收集来自服务器的响应数据
使用
NSURLConnection
发送请求的步骤很简单
创建一个
NSURL
对象,设置请求路径
传入
NSURL
创建一个
NSURLRequest
对象,设置请求头和请求体
使用
NSURLConnection
发送
NSURLRequest
NSURLConnection
常见的发送请求方法有以下几种
同步请求
+ (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;
代理
- (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
的代理,最好遵守
NSURLConnection
Data
Delegate
协议
开始接收到服务器的响应时调用
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
接收到服务器返回的数据时调用(服务器返回的数据比较大时会调用多次)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
服务器返回的数据完全接收完毕后调用
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
请求出错时调用(比如请求超时)
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
NSMutableURLRequest
是
NSURLRequest
的子类,常用方法有
设置请求超时等待时间(超过这个时间就算超时,请求失败)
- (void)setTimeoutInterval:(NSTimeInterval)seconds;
设置请求方法(比如
GET
和
POST
)
- (void)setHTTPMethod:(NSString *)method;
设置请求体
- (void)setHTTPBody:(NSData *)data;
设置请求头
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;
创建
GET
请求
NSString *urlStr = [@"http://192.168.1.102:8080/login?username=123&pwd=123" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlStr];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
创建
POST
请求
NSString *urlStr = @"http://192.168.1.102:8080/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
给服务器
一定要使用
POST
请求
设置请求头
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
设置JSON数据为请求体
提交用户的隐私数据
一定要使用
POST
请求
提交用户
的
隐私数据
GET
请求的所有参数都直接暴露在
URL
中
请求的
URL
一般会记录在服务器的访问日志中
服务器的访问日志是黑客攻击的重点对象之一
用户的隐私数据
登录密码
银行账号
数据安全
仅仅用
POST
请求提交用户的隐私数据,还是不能完全解决安全问题
可以利用软件(比如
Charles
)设置代理服务器,拦截查看手机的请求数据
因此:
提交用户的隐私数据时,一定不要明文提交,要加密处理后再提交
常见的加密算法
MD5
\
SHA
\
DES
\
3DES
\
RC2
和
RC4
\
RSA
\
IDEA
\
DSA
\
AES
加密算法的选择
一般公司都会有一套自己的加密方案,按照公司接口文档的规定去加密
什么是
MD5
全称是
Message DigestAlgorithm
5
,译为“消息摘要算法第
5
版”
效果
:
对输入信息生成唯一的
128
位散列值(
32
个字符)
MD5
的特点
输入两个不同的明文不会得到相同的输出值
根据输出值,不能得到原始的明文,即其过程
不可逆
MD5
的应用
由于
MD5
加密算法具有较好的安全性,而且免费,因此该加密算法被广泛使用
主要运用在数字签名、文件完整性验证以及口令加密等方面
结论
用户的隐私数据,只有在用户输入那一刻是明文,其他情况都是密文处理
MD5改进
现在的
MD5
已不再是绝对安全,对此,可以对
MD5
稍作改进,以增加解密的难度
加盐(
Salt
):在明文的固定位置插入随机串,然后再进行
MD5
先加密,后乱序:先对明文进行
MD5
,然后对加密得到的
MD5
串的字符进行乱序
总之宗旨就是:黑客就算攻破了数据库,也无法解密出正确的明文
同一个URL的多次请求
有时候,对同一个
URL
请求多次,返回的数据可能都是一样的
比如服务器上的某张图片,无论下载多少次,返回的数据都是一样的
上面的情况会造成以下问题
用户流量的浪费
程序响应速度不够快
缓存思路– 第一次请求数据
为了提高程序的响应速度,可以考虑使用缓存(内存缓存\硬盘缓存)
第一次请求数据时
内存缓存中没有数据
硬盘缓存中没有数据
当服务器返回数据时,需要做以下步骤
使用服务器的数据(比如解析、显示)
将服务器的数据缓存到硬盘(沙盒)
此时缓存的情况是
内存缓存中有数据
硬盘缓存中有数据
如果程序并没有被关闭,一直在运行
内存缓存中有数据
硬盘缓存中有数据
如果再次请求数据,直接使用内存缓存中的数据即可
缓存的实现
一般只对
GET
请求进行缓存,不必对
POST
请求进行缓存
GET
请求一般用来查询数据
POST
请求一般是发大量数据给服务器处理(变动性比较大)
在
iOS
中,可以使用
NSURLCache
类缓存数据
iOS
5
之前:只支持 内存缓存
iOS
5
开始:同时支持 内存缓存 和硬盘缓存
NSURLCache
了解
缓存原理:一个
NSURLRequest
对应一个
NSCachedURLResponse
缓存技术:数据库
NSURLCache
的常见用法
获得全局缓存对象(没必要手动创建)
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 // 忽略缓存,重新请求
NSURLRequestReloadIgnoringLocalAndRemoteCacheData // 未实现
NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData // 忽略缓存,重新请求
NSURLRequestReturnCacheDataElseLoad
// 有缓存就用缓存,没有缓存就重新请求
NSURLRequestReturnCacheDataDontLoad
// 有缓存就用缓存,没有缓存就不发请求,当做请求出错处理(用于离线模式)
NSURLRequestReloadRevalidatingCacheData // 未实现
缓存看起来很美好,但需要谨慎使用
如果请求某个
URL
的返回数据
经常更新:不能用缓存!比如股票、彩票数据
一成不变:果断用缓存
偶尔更新:可以定期更改缓存策略 或者 清除缓存
如果大量使用缓存,会越积越大,建议
定期清除缓存
检测网络状态
在网络应用中,需要对用户设备的网络状态进行实时监控,目的是
让用户了解自己的网络状态,防止一些误会(比如怪应用无能)
根据用户的网络状态进行智能处理,节省用户流量,提高用户体验
WIFI\3G
网络:自动下载高清图片
低速网络:只下载缩略图
没有网络:只显示离线的缓存数据
苹果官方提供了一个叫
Reachability
的示例程序,便于开发者检测网络状态
Reachability
常见用法
// 是否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];
}