1 HTTP两种请求方案
1),苹果原生
NSURLConnect:经典简单
NSURLSession:iOS7新出,功能较强大
CFNetwork:NSURL*的底层,纯C语言
2),第三方框架(建议使用,提高效率)
ASIHttpRequest:功能十分强大,但停止更新
AFNetworking:主流,简单易用,更新十分快
MKNetworkKit:简单,但少用
2 HTTP的通信过程
1).请求
1> 请求行 : 请求方法、请求路径、HTTP协议的版本
GET /MJServer/resources/images/1.jpg HTTP/1.1
2> 请求头 : 客户端的一些描述信息
* User-Agent : 客户端的环境(软件环境)
3> 请求体 : POST请求才有这个东西
* 请求参数,发给服务器的数据
2).响应
1> 状态行(响应行): HTTP协议的版本、响应状态码、响应状态描述
HTTP/1.1 200 OK
2> 响应头:服务器的一些描述信息
* Content-Type : 服务器返回给客户端的内容类型
* Content-Length : 服务器返回给客户端的内容的长度(比如文件的大小)
3> 实体内容(响应体)
* 服务器返回给客户端具体的数据,比如文件数据
3 移动端HTTP请求分析数据的步骤
1.拼接"请求URL" + "?" + "请求参数"
* 请求参数的格式:参数名=参数值
* 多个请求参数之间用&隔开:参数名1=参数值1&参数名2=参数值2
* 比如:http://localhost:8080/MJServer/login?username=123&pwd=456
2.发送请求
3.解析服务器返回的数据
3.1 iOS中发送HTTP请求方式
1).GET
1> 特点
* 所有请求参数都拼接在url后面
2> 缺点
* 在url中暴露了所有的请求数据,不太安全
* url的长度有限制,不能发送太多的参数
3> 使用场合
* 如果仅仅是向服务器索要数据,一般用GET请求
* 默认就是GET请求
4> 如何发送一个GET请求
// 1.URL
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
// 2.请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 3.发送请求(子线程发送)
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
ompletionHandler:^(NSURLResponse *response,
NSData *data,
NSError *connectionError) {
}];
//发送一个同步请求(在主线程发送请求)
NSData *data = [NSURLConnection sendSynchronousRequest:request
returningResponse:nil error:nil];
2).POST
1> 特点
* 把所有请求参数放在请求体(HTTPBody)中
* 理论上讲,发给服务器的数据的大小是没有限制
2> 使用场合
* 除开向服务器索要数据以外的请求,都可以用POST请求
* 如果发给服务器的数据是一些隐私、敏感的数据,绝对要用POST请求
3> 如何发送一个POST请求
// 1.创建一个URL : 请求路径
NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/login"];
// 2.创建一个请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 设置请求方法
request.HTTPMethod = @"POST";
// 设置请求体 : 请求参数
NSString *param = [NSString stringWithFormat:@"username=%@&pwd=%@", username, pwd];
// NSString --> NSData
request.HTTPBody = [param dataUsingEncoding:NSUTF8StringEncoding];
// 3.发送请求(子线程发送)
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
ompletionHandler:^(NSURLResponse *response,
NSData *data,
NSError *connectionError) {
}];
//发送一个同步请求(在主线程发送请求)
NSData *data = [NSURLConnection sendSynchronousRequest:request
returningResponse:nil error:nil];
3.2 解析服务器返回的数据
1)JSON解析
1>特点
*JSON解析规律
* { } --> NSDictionary @{ }
* [ ] --> NSArray @[ ]
* " " --> NSString @" "
* 10 --> NSNumber @10
*数据量少,服务器常用返回的数据
// 3.发送请求(子线程发送)
* request : 需要发送的请求
* queue : 一般用主队列,存放handler这个任务
* handler : 当请求完毕后,会自动调用这个block
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
ompletionHandler:^(NSURLResponse *response,
NSData *data,
NSError *connectionError) {
// 解析服务器返回的JSON数据
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableLeaves
error:nil];
NSString *error = dict[@"error"];
if (error) return;
else {
NSString *success = dict[@"success"];
}
}];
2)XML解析
1.语法
1> 文档声明
<?xml version="1.0" encoding="UTF-8" ?>
2> 元素
* videos和video是元素(节点)
* video元素是videos元素的子元素
3> 属性
<videos>
<video name="小黄人 第01部" length="10"/>
<video name="小黄人 第01部" length="10"/>
</videos>
* name和length叫做元素的属性
2.解析
1> SAX解析
*逐个元素往下解析,适合大文件
* NSXMLParser
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
ompletionHandler:^(NSURLResponse *response,
NSData *data,
NSError *connectionError) {
if (connectionError || data == nil) {
[MBProgressHUD showError:@"网络繁忙,请稍后再试!"];
return;
}
// 解析XML数据
// 1.创建XML解析器 -- SAX -- 逐个元素往下解析
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
// 2.设置代理 重要!
parser.delegate = self;
// 3.开始解析(同步执行)
[parser parse];
// 4.刷新表格
[self.tableView reloadData];
}];
/**
* 解析到一个元素的开始就会调用
* @param elementName 元素名称
* @param attributeDict 属性字典
*/
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
if ([@"videos" isEqualToString:elementName]) return;
HMVideo *video = [HMVideo videoWithDict:attributeDict];
[self.videos addObject:video];
}
// 解析到文档的开头时会调用
- (void)parserDidStartDocument:(NSXMLParser *)parser
/* 解析到一个元素的结束就会调用
* @param elementName 元素名称
*/
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
// 解析到文档的结尾时会调用(解析结束)
- (void)parserDidEndDocument:(NSXMLParser *)parser
2> DOM解析
*一口气将整个XML文档加载进内存,适合小文件,使用最简单
* GDataXML的使用步骤:
1>导入这个GDataXML文件
2>添加libxml2.dylib这个动态库
3>在Bulid Settings的Header Search Paths 添加路径 /usr/include/libxml2
4>在Bulid Phases的Compile Sources 找到CDataXMLNode 添加 -fno-objc-arc,通知编译器这是非arc
// 3.发送请求
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
ompletionHandler:^(NSURLResponse *response,
NSData *data,
NSError *connectionError) {
if (connectionError || data == nil) {
[MBProgressHUD showError:@"网络繁忙,请稍后再试!"];
return;
}
// 解析XML数据
// 加载整个XML数据
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data
options:0 error:nil];
// 获得文档的根元素 -- videos元素
GDataXMLElement *root = doc.rootElement;
// 获得根元素里面的所有video元素
NSArray *elements = [root elementsForName:@"video"];
// 遍历所有的video元素
for (GDataXMLElement *videoElement in elements) {
HMVideo *video = [[HMVideo alloc] init];
/ 取出元素的属性
video.id = [videoElement attributeForName:@"id"].stringValue.intValue;
video.name = [videoElement attributeForName:@"name"].stringValue;
video.image = [videoElement attributeForName:@"image"].stringValue;
video.url = [videoElement attributeForName:@"url"].stringValue;
// 添加到数组中
[self.videos addObject:video];
}
// 刷新表格
[self.tableView reloadData];
}];
4 数据安全
4.1.网络数据加密
1> 加密对象:隐私数据,比如密码、银行信息
2> 加密方案
* 提交隐私数据,必须用POST请求
* 使用加密算法对隐私数据进行加密,比如MD5
3> 加密增强:为了加大破解的难度
* 对明文进行2次MD5 : MD5(MD5($pass))
* 先对明文撒盐,再进行MD5 : MD5($pass.$salt) 撒盐是添加一些干扰数据
* 先MD5加密,再打乱暗文顺序
4.2.本地存储加密
1> 加密对象:重要的数据,比如游戏数据
4.3.代码安全问题
1> 现在已经有工具和技术能反编译出源代码:逆向工程
* 反编译出来的都是纯C语言的,可读性不高
* 最起码能知道源代码里面用的是哪些框架
5 监测网络状态
5.1.主动监测监测网络状态
// 是否WIFI 类方法
+ (BOOL)isEnableWIFI {
return ([[Reachability reachabilityForLocalWiFi]
currentReachabilityStatus] != NotReachable);
}
// 是否3G
+ (BOOL)isEnable3G {
return ([[Reachability reachabilityForInternetConnection]
currentReachabilityStatus] != NotReachable);
}
5.2.使用通知监控网络状态
1>使用苹果官方提供的 Reachability类
1> 监听通知
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(networkStateChange)
name:kReachabilityChangedNotification object:nil];
2> 开始监听网络状态
// 获得Reachability对象
self.reachability = [Reachability reachabilityForInternetConnection];
// 开始监控网络
[self.reachability startNotifier];
5.3.移除监听
- (void)delloc
{
[self.reachability stopNotifier];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
6 iOS7:NSURLSession
1> NSURLSessionDataTask
* 用途:用于非文件下载的GET\POST请求
NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request];
NSURLSessionDataTask *task = [self.session dataTaskWithURL:url];
NSURLSessionDataTask *task = [self.session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
}];
2> NSURLSessionDownloadTask
* 用途:用于文件下载(小文件、大文件)
NSURLSessionDownloadTask *task = [self.session downloadTaskWithRequest:request];
NSURLSessionDownloadTask *task = [self.session downloadTaskWithURL:url];
NSURLSessionDownloadTask *task = [self.session downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
}];
7 下载
6.1.小文件下载
* 直接使用NSData
* NSURLConnection发送异步请求的方法
1.block形式 - 除开大文件下载以外的操作,都可以用这种形式
//使用了block就不需要使用代理方法
[NSURLConnection sendAsynchronousRequest:<#(NSURLRequest *)#> queue:<#(NSOperationQueue *)#> completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
}];
6.2.大文件下载(断点下载)
1>利用NSURLConnection和它的代理方法
@property (nonatomic, strong) NSFileHandle *writeHandle;
@property (nonatomic, assign) long long totalLength;
@property (nonatomic, assign) long long currentLength;
@property (nonatomic, strong) NSURLConnection *conn;
1> 发送一个请求
// 1.URL
NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/resources/videos.zip"];
// 2.请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 3.下载(创建完conn对象后,会自动发起一个异步请求)
//要遵守NSURLConnectionDataDelegate协议
[NSURLConnection connectionWithRequest:request delegate:self];
2>#pragma mark - NSURLConnectionDataDelegate代理方法
在代理方法中处理服务器返回的数据
/**
在接收到服务器的响应时:
1.创建一个空的文件
2.用一个句柄对象关联这个空的文件,目的是:方便后面用句柄对象往文件后面写数据
*/
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
// 文件路径
NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *filepath = [caches stringByAppendingPathComponent:@"videos.zip"];
// 创建一个空的文件 到 沙盒中
NSFileManager *mgr = [NSFileManager defaultManager];
[mgr createFileAtPath:filepath contents:nil attributes:nil];
// 创建一个用来写数据的文件句柄
self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:filepath];
}
/**
在接收到服务器返回的文件数据时,利用句柄对象往文件的最后面追加数据
*/
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// 移动到文件的最后面
[self.writeHandle seekToEndOfFile];
// 将数据写入沙盒
[self.writeHandle writeData:data];
}
/**
在所有数据接收完毕时,关闭句柄对象
*/
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// 关闭文件
[self.writeHandle closeFile];
self.writeHandle = nil;
}
3,断点下载
- (IBAction)download:(UIButton *)sender {
// 状态取反
sender.selected = !sender.isSelected;
if (sender.selected) { // 继续(开始)下载
// 1.URL
NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/resources/videos.zip"];
// 2.请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 设置请求头
NSString *range = [NSString stringWithFormat:@"bytes=%lld-", self.currentLength];
[request setValue:range forHTTPHeaderField:@"Range"];
// 3.下载(创建完conn对象后,会自动发起一个异步请求)
self.conn = [NSURLConnection connectionWithRequest:request delegate:self];
} else { // 暂停
[self.conn cancel];
self.conn = nil;
}
}
2>利用NSURLSession和它的代理方法
@property (nonatomic, strong) NSURLSessionDownloadTask *task;
@property (nonatomic, strong) NSData *resumeData;
@property (nonatomic, strong) NSURLSession *session;
//遵守NSURLSessionDownloadDelegate代理协议
- (NSURLSession *)session
{
if (!_session) {
// 获得session
NSURLSessionConfiguration *cfg = [NSURLSessionConfiguration defaultSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:cfg delegate:self delegateQueue:[NSOperationQueue mainQueue]];
}
return _session;
}
-(IBAction)download:(UIButton *)sender {
// 按钮状态取反
sender.selected = !sender.isSelected;
if (self.task == nil) { // 开始(继续)下载
if (self.resumeData) { // 恢复
[self resume];
} else { // 开始
[self start];
}
} else { // 暂停
[self pause];
}
}
//从零开始
- (void)start
{
// 1.创建一个下载任务
NSURL *url = [NSURL URLWithString:@"http://192.168.15.172:8080/MJServer/resources/videos/minion_01.mp4"];
self.task = [self.session downloadTaskWithURL:url];
// 2.开始任务
[self.task resume];
}
//恢复(继续)
- (void)resume
{
// 传入上次暂停下载返回的数据,就可以恢复下载
self.task = [self.session downloadTaskWithResumeData:self.resumeData];
// 开始任务
[self.task resume];
// 清空
self.resumeData = nil;
}
//暂停
- (void)pause
{
__weak typeof(self) vc = self;
[self.task cancelByProducingResumeData:^(NSData *resumeData) {
// resumeData : 包含了继续下载的开始位置\下载的url
vc.resumeData = resumeData;
vc.task = nil;
}];
}
#pragma mark - NSURLSessionDownloadDelegate
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location
{
NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
// response.suggestedFilename : 建议使用的文件名,一般跟服务器端的文件名一致
NSString *file = [caches stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
// 将临时文件剪切或者复制Caches文件夹
NSFileManager *mgr = [NSFileManager defaultManager];
[mgr moveItemAtPath:location.path toPath:file error:nil];
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didWriteData:(int64_t)bytesWritten
totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
NSLog(@"获得下载进度--%@", [NSThread currentThread]);
// 获得下载进度
self.progressView.progress = (double)totalBytesWritten / totalBytesExpectedToWrite;
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didResumeAtOffset:(int64_t)fileOffset
expectedTotalBytes:(int64_t)expectedTotalBytes
{
}
8 上传
1,文件上传的步骤
1.设置请求头
* 目的:告诉服务器请求体里面的内容并非普通的参数,而是包含了文件参数
[request setValue:@"multipart/form-data; boundary=标识" forHTTPHeaderField:@"Content-Type"];
2.设置请求体
* 作用:存放参数(文件参数和非文件参数)
1> 非文件参数
[body appendData:HMEncode(@"--标识\r\n")];
[body appendData:HMEncode(@"Content-Disposition: form-data; name=\"username\"\r\n")];
[body appendData:HMEncode(@"\r\n")];
[body appendData:HMEncode(@"张三")];
[body appendData:HMEncode(@"\r\n")];
2> 文件参数
[body appendData:HMEncode(@"--heima\r\n")];
[body appendData:HMEncode(@"Content-Disposition: form-data; name=\"file\"; filename=\"test123.png\"\r\n")];
[body appendData:HMEncode(@"Content-Type: image/png\r\n")];
[body appendData:HMEncode(@"\r\n")];
[body appendData:imageData];
[body appendData:HMEncode(@"\r\n")];
3> 结束标记 :参数结束的标记
[body appendData:HMEncode(@"--标识--\r\n")];
2,封装好的实例
=========================================封装好的实例=========================================
//filename要上传的文件名字,mimeType文件类型,fileDate上传的文件数据,通常是url获取文件地址,params是含有多参数的键值对的字典
eg:1,fileDate
NSURL *url = [[NSBundle mainBundle] URLForResource:@"autolayout" withExtension:@"txt"];
NSData *data = [NSData dataWithContentsOfURL:url];
2,params
NSDictionary *params = @{
@"username" : @"李四",
@"pwd" : @"123",
@"age" : @30,
@"height" : @"1.55"
};
- (void)upload:(NSString *)filename mimeType:(NSString *)mimeType fileData:(NSData *)fileData params:(NSDictionary *)params
{
// 1.请求路径
NSURL *url = [NSURL URLWithString:@"xxxxx"];
// 2.创建一个POST请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
// 3.设置请求体
NSMutableData *body = [NSMutableData data];
// 3.1.文件参数,具体参数格式可以使用charles工具截取观察。\r\n硬性换行
//str转换为data
#define HMEncode(str) [str dataUsingEncoding:NSUTF8StringEncoding]
#define HMNewLien @"\r\n"
#define HMFileBoundary @"xxxxxxx" 标识
[body appendData:HMEncode(@"--")];
[body appendData:HMEncode(HMFileBoundary)];
[body appendData:HMEncode(HMNewLien)];
NSString *disposition = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"%@\"", filename];
[body appendData:HMEncode(disposition)];
[body appendData:HMEncode(HMNewLien)];
NSString *type = [NSString stringWithFormat:@"Content-Type: %@", mimeType];
[body appendData:HMEncode(type)];
[body appendData:HMEncode(HMNewLien)];
[body appendData:HMEncode(HMNewLien)];
[body appendData:fileData];
[body appendData:HMEncode(HMNewLien)];
// 3.2.非文件参数
/* [params enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop)
*遍历parames这个字典的键值,有多少对,就自动遍历多少次
*/
[params enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[body appendData:HMEncode(@"--")];
[body appendData:HMEncode(HMFileBoundary)];
[body appendData:HMEncode(HMNewLien)];
NSString *disposition = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"", key];
[body appendData:HMEncode(disposition)];
[body appendData:HMEncode(HMNewLien)];
[body appendData:HMEncode(HMNewLien)];
[body appendData:HMEncode([obj description])];
[body appendData:HMEncode(HMNewLien)];
}];
// 3.3.结束标记
[body appendData:HMEncode(@"--")];
[body appendData:HMEncode(HMFileBoundary)];
[body appendData:HMEncode(@"--")];
[body appendData:HMEncode(HMNewLien)];
request.HTTPBody = body;
// 4.设置请求头(告诉服务器这次传给你的是文件数据,告诉服务器现在发送的是一个文件上传请求)
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", HMFileBoundary];
[request setValue:contentType forHTTPHeaderField:@"Content-Type"];
// 5.发送请求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
NSLog(@"%@", dict);
}];
}
ps:获取文件类型的方法MIMEType
1.百度搜索
2.查找服务器下面的某个xml文件
apache-tomcat-6.0.41\conf\web.xml
3.加载文件时通过Reponse获得
- (NSString *)MIMEType:(NSURL *)url
{
// 1.创建一个请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 2.发送请求(返回响应)
NSURLResponse *response = nil;
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
// 3.获得MIMEType
return response.MIMEType;
}
9,解压缩
一、技术方案
1.第三方框架:SSZipArchive
2.依赖的动态库:libz.dylib
二、压缩1
1.第一个方法
/**
zipFile :产生的zip文件的最终路径
directory : 需要进行的压缩的文件夹路径
*/
[SSZipArchive createZipFileAtPath:zipFile withContentsOfDirectory:directory];
2.第一个方法
/**
zipFile :产生的zip文件的最终路径
files : 这是一个数组,数组里面存放的是需要压缩的文件的路径的集合
files = @[@"/Users/apple/Destop/1.png", @"/Users/apple/Destop/3.txt"]
*/
[SSZipArchive createZipFileAtPath:zipFile withFilesAtPaths:files];
三、解压缩
/**
zipFile :需要解压的zip文件的路径
dest : 解压到什么地方
*/
[SSZipArchive unzipFileAtPath:zipFile toDestination:dest];
10 AFNetwork
*一般只用于下载小文件
1,发送请求
一、2大管理对象
1.AFHTTPRequestOperationManager
* 对NSURLConnection的封装
2.AFHTTPSessionManager
* 对NSURLSession的封装
二、AFHTTPRequestOperationManager的具体使用
1.创建管理者
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
2.封装请求参数
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"username"] = @"哈哈哈";
params[@"pwd"] = @"123";
3.发送请求
NSString *url = @"http://localhost:8080/MJServer/login";
[mgr POST/GET:url parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject) {
// 请求成功的时候调用这个block
//responseObject 如果是json数据,就默认解析为字典
NSLog(@"请求成功---%@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// 请求失败的时候调用调用这个block
NSLog(@"请求失败");
}];
三、对服务器返回数据的解析
1.AFN可以自动对服务器返回的数据进行解析
* 默认将服务器返回的数据当做JSON来解析
2.设置对服务器返回数据的解析方式
1> 当做是JSON来解析(默认做法)
* mgr.responseSerializer = [AFJSONResponseSerializer serializer];
* responseObject的类型是NSDictionary或者NSArray
2> 当做是XML来解析
* mgr.responseSerializer = [AFXMLParserResponseSerializer serializer];
* responseObject的类型是NSXMLParser
3> 直接返回data
* 意思是:告诉AFN不要去解析服务器返回的数据,保持原来的data即可
* mgr.responseSerializer = [AFHTTPResponseSerializer serializer];
3.注意
* 服务器返回的数据一定要跟responseSerializer对得上
2,下载
//AFNetwork的下载必须配合NSURLConnection或者NSURLSession才行
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:@"http://www.baidu.com/img/bdlogo.png"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
NSLog(@"File downloaded to: %@", filePath);
}];
[downloadTask resume];
11 ASI
*功能十分强大,但已停止更新
3,上传
//上传和下载基本相同,都是发送请求,但发送请求的方法不一样
// 1.创建一个管理者
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
// 2.封装参数(这个字典只能放非文件参数)
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"username"] = @"123";
// 3.发送一个请求
NSString *url = @"http://192.168.15.172:8080/MJServer/upload";
[mgr POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
NSData *fileData = UIImageJPEGRepresentation(self.imageView.image, 1.0);
[formData appendPartWithFileData:fileData name:@"file" fileName:@"haha.jpg" mimeType:@"image/jpeg"];
// 不是用这个方法来设置文件参数
// [formData appendPartWithFormData:fileData name:@"file"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"上传成功");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"上传失败");
}];
4,监控网络状态
AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];
[mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
// 当网络状态发生改变的时候调用这个block
switch (status) {
case AFNetworkReachabilityStatusReachableViaWiFi:
NSLog(@"WIFI");
break;
case AFNetworkReachabilityStatusReachableViaWWAN:
NSLog(@"自带网络");
break;
case AFNetworkReachabilityStatusNotReachable:
NSLog(@"没有网络");
break;
case AFNetworkReachabilityStatusUnknown:
NSLog(@"未知网络");
break;
default:
break;
}
}];
// 开始监控
[mgr startMonitoring];
其他:
1 NSMutableURLRequest的常用方法
1>.设置超时
request.timeoutInterval = 5;
* NSURLRequest是不能设置超时的,因为这个对象是不可变的
*NSMutableURLRequest并不代表就是post请求,也可以是get请求。系统默认是get请求,使用这个,代表url可改
九、URL转码
1.URL中不能包含中文,得对中文进行转码(加上一堆的%)
NSString *urlStr = @"http://localhost/login?username=喝喝&pwd=123";
urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// urlStr == @"http://localhost/login?username=%E5%96%9D%E5%96%9D&pwd=123"