iOS开发网络多线程之网络请求文件解析
一.网络请求
1. get请求
1> 确定URL
2> 创建请求
3> 发送连接请求(网络请求用异步函数)
- (void)get
{
// 1.url
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];
// 2.请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 3.连接
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(@"%@", dict[@"success"]);
}];
}
2. post请求
1> 确定URL
2> 创建请求
设置请求方法
设置请求体(用户名和密码包装在请求体中)
3> 发送连接请求(网络请求用异步函数)
- (void)post
{
// 1.url
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"];
// 2.请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 3.请求设置方法
request.HTTPMethod = @"POST";
// 设置请求体
request.HTTPBody = [@"username=lisi&pwd=123456&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];
// 4.连接
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(@"%@",dict[@"error"]);
}];
}
3. 中文转码
NSString *str = [NSString stringWithFormat:@"username=文刂Rn&pwd=123456&type=JSON", self.userTextField.text, self.pwdTextField.text];
// 中文转码
str = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
二. JSON文件解析
1. JSON文件解析用NSJSONSerialization对象解析
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
2. JSON文件解析后转模型(MJExtention)
如果模型中的变量名和字典中的key有不一样的,需要先声明用什么替换
// 告诉id 用ID替换
[LDVideo setupReplacedKeyFromPropertyName:^NSDictionary *{
return @{
@"ID" : @"id"
};
}];
字典数组转模型
self.videos = [LDVideo objectArrayWithKeyValuesArray:dictArray];
字典转模型
[self.videos addObject:[LDVideo objectWithKeyValues:attributeDict]];
三.XML文件解析
1. NSXMLParser 使用SAX(从根元素开始解析,一个元素一个元素的向下解析)方式解析,可用于大小文件解析
1> 创建NSXMLParser并设置代理,解析在代理方法中实现
- (void)viewDidLoad {
[super viewDidLoad];
// 1.url
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=XML"];
// 2.请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 3.连接
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// 4.解析
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
// 开始解析,会阻塞直到数据解析完毕
[parser parse];
// 5.刷新
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self.tableView reloadData];
}];
}];
}
2> 代理方法实现
开始解析xml文件
// 开始解析xml文件
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
}
开始解析元素,解析出来元素(存放在字典中)后用MJExention转为模型
// 开始解析元素
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:@"videos"]) return;
// 设置id用ID转换
[LDVideo setupReplacedKeyFromPropertyName:^NSDictionary *{
return @{
@"ID" : @"id"
};
}];
// MJExtension 字典转模型
[self.videos addObject:[LDVideo objectWithKeyValues:attributeDict]];
}
某个元素解析完成
// 某个元素解析完成
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
}
整个xml文件解析完毕
// 整个xml文件解析完毕
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
}
2. GDataParser解析XML,使用DOM(一次性将整个XML文档加载到内存中解析)方式解析,可用于小文件解析
1> 创建GDataParser对象加载xml二进制数据
2> 解析xml内的元素存放到数组中
3> 遍历数组将对于的值赋值给模型中的属性
- (void)viewDidLoad {
[super viewDidLoad];
// 1.url
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=XML"];
// 2.请求
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
// 3.连接
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// 解析xml文件
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data options:kNilOptions error:nil];
// 解析video元素
NSArray *elementArray = [doc.rootElement elementsForName:@"video"];
// 遍历数组
for (GDataXMLElement *element in elementArray) {
LDVideo *video = [[LDVideo alloc] init];
// 将字典中的值赋值给模型对象的属性
video.ID = [element attributeForName:@"id"].stringValue.integerValue;
video.name = [element attributeForName:@"name"].stringValue;
video.length = [element attributeForName:@"length"].stringValue.integerValue;
video.image = [element attributeForName:@"image"].stringValue;
video.url = [element attributeForName:@"url"].stringValue;
[self.videos addObject:video];
NSLog(@"%@", [element attributeForName:@"id"]);
NSLog(@"=====%zd", self.videos.count);
}
// 刷新UI
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self.tableView reloadData];
}];
}];
}
四. 小文件下载
1. 直接加载文件的URL进行下载
-(void)dataDownload {
//1.确定资源路径
NSURL *url = [NSURLURLWithString:@"http://120.25.226.186:32812/resources/images/minion_01.png"];
//2.根据URL加载对应的资源
NSData *data = [NSData dataWithContentsOfURL:url];
//3.转换并显示数据
UIImage *image = [UIImage imageWithData:data];
self.imageView.image = image;
}
2. 发送异步函数请求下载
-(void)connectDownload {
//1.确定请求路径 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_01.png"];
//2.创建请求对象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.使用NSURLConnection发送一个异步请求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//4.拿到并处理数据
UIImage *image = [UIImage imageWithData:data];
self.imageView.image = image;
}];
}
3. 通过NSURLConnection设置代理发送异步请求的方式下载文件
-(void)connectionDelegateDownload {
//1.确定请求路径 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];
//2.创建请求对象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.使用NSURLConnection设置代理并发送异步请求
[NSURLConnection connectionWithRequest:request delegate:self];
}
4. 代理方法
当接收到服务器响应的时候调用,该方法只会调用一次
//当接收到服务器响应的时候调用,该方法只会调用一次
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
//创建一个容器,用来接收服务器返回的数据 self.fileData = [NSMutableData data];
//获得当前要下载文件的总大小(通过响应头得到)
NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
self.totalLength = res.expectedContentLength;
NSLog(@"%zd",self.totalLength);
//拿到服务器端推荐的文件名称
self.fileName = res.suggestedFilename;
}
- 当接收到服务器返回的数据时会调用 //该方法可能会被调用多次
//当接收到服务器返回的数据时会调用 //该方法可能会被调用多次
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// NSLog(@"%s",func);
//拼接每次下载的数据
[self.fileData appendData:data];
//计算当前下载进度并刷新UI显示
self.currentLength = self.fileData.length;
NSLog(@"%f",1.0* self.currentLength/self.totalLength);
self.progressView.progress = 1.0* self.currentLength/self.totalLength;
}
当网络请求结束之后调用
//当网络请求结束之后调用
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//文件下载完毕把接受到的文件数据写入到沙盒中保存
//1.确定要保存文件的全路径
//caches文件夹路径
NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *fullPath = [caches stringByAppendingPathComponent:self.fileName];
//2.写数据到文件中
[self.fileData writeToFile:fullPath atomically:YES];
NSLog(@"%@",fullPath);
}
当请求失败的时候调用该方法
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"%s",func);
}