iOS开发网络多线程之网络请求文件解析

一.网络请求

1. get请求

1> 确定URL

2> 创建请求

3> 发送连接请求(网络请求用异步函数)

  1. - (void)get
  2. {
  3.    // 1.url
  4.    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];
  5.    
  6.    // 2.请求
  7.    NSURLRequest *request = [NSURLRequest requestWithURL:url];
  8.    
  9.    // 3.连接
  10.    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
  11.        
  12.        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
  13.        
  14.        NSLog(@"%@", dict[@"success"]);
  15.        
  16.    }];
  17. }

2. post请求

1> 确定URL

2> 创建请求

   设置请求方法

   设置请求体(用户名和密码包装在请求体中)

3> 发送连接请求(网络请求用异步函数)

  1. - (void)post
  2. {
  3.    // 1.url
  4.    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"];
  5.    
  6.    // 2.请求
  7.    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  8.    
  9.    // 3.请求设置方法
  10.    request.HTTPMethod = @"POST";
  11.    // 设置请求体
  12.    request.HTTPBody = [@"username=lisi&pwd=123456&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];
  13.    
  14.    // 4.连接
  15.    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
  16.        
  17.        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
  18.        
  19.        NSLog(@"%@",dict[@"error"]);
  20.        
  21.    }];
  22. }


3. 中文转码

  1. NSString *str = [NSString stringWithFormat:@"username=文刂Rn&pwd=123456&type=JSON", self.userTextField.text, self.pwdTextField.text];
  2.    
  3. // 中文转码
  4. str = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];


二. JSON文件解析

1. JSON文件解析用NSJSONSerialization对象解析

  1. NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];

2. JSON文件解析后转模型(MJExtention)

如果模型中的变量名和字典中的key有不一样的,需要先声明用什么替换

  1. // 告诉id 用ID替换
  2. [LDVideo setupReplacedKeyFromPropertyName:^NSDictionary *{
  3.  return @{
  4.      @"ID" : @"id"
  5.  };
  6. }];

字典数组转模型

  1. self.videos = [LDVideo objectArrayWithKeyValuesArray:dictArray];

字典转模型

  1. [self.videos addObject:[LDVideo objectWithKeyValues:attributeDict]];

三.XML文件解析

1. NSXMLParser 使用SAX(从根元素开始解析,一个元素一个元素的向下解析)方式解析,可用于大小文件解析

1> 创建NSXMLParser并设置代理,解析在代理方法中实现

  1. - (void)viewDidLoad {
  2.    [super viewDidLoad];
  3.    
  4.    // 1.url
  5.    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=XML"];
  6.    
  7.    // 2.请求
  8.    NSURLRequest *request = [NSURLRequest requestWithURL:url];
  9.    
  10.    // 3.连接
  11.    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
  12.        // 4.解析
  13.        NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
  14.        
  15.        parser.delegate = self;
  16.        
  17.        // 开始解析,会阻塞直到数据解析完毕
  18.        [parser parse];
  19.        
  20.        // 5.刷新
  21.        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
  22.            [self.tableView reloadData];
  23.        }];
  24.        
  25.    }];
  26. }


2> 代理方法实现

  • 开始解析xml文件

  1. // 开始解析xml文件
  2. - (void)parserDidStartDocument:(NSXMLParser *)parser
  3. {
  4. }
  • 开始解析元素,解析出来元素(存放在字典中)后用MJExention转为模型

  1. // 开始解析元素
  2. - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
  3. {
  4.    if ([elementName isEqualToString:@"videos"]) return;
  5.    
  6.    // 设置id用ID转换
  7.    [LDVideo setupReplacedKeyFromPropertyName:^NSDictionary *{
  8.        return @{
  9.                 @"ID" : @"id"
  10.                 };
  11.    }];
  12.    
  13.    // MJExtension 字典转模型
  14.    [self.videos addObject:[LDVideo objectWithKeyValues:attributeDict]];
  15. }
  • 某个元素解析完成

  1. // 某个元素解析完成
  2. - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
  3. {
  4.    
  5. }
  • 整个xml文件解析完毕

  1. // 整个xml文件解析完毕
  2. - (void)parserDidEndDocument:(NSXMLParser *)parser
  3. {
  4.    
  5. }


2. GDataParser解析XML,使用DOM(一次性将整个XML文档加载到内存中解析)方式解析,可用于小文件解析

1> 创建GDataParser对象加载xml二进制数据

2> 解析xml内的元素存放到数组中

3> 遍历数组将对于的值赋值给模型中的属性

  1. - (void)viewDidLoad {
  2.    [super viewDidLoad];
  3.    
  4.    // 1.url
  5.    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=XML"];
  6.    
  7.    // 2.请求
  8.    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
  9.    
  10.    // 3.连接
  11.    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
  12.        
  13.        // 解析xml文件
  14.        GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data options:kNilOptions error:nil];
  15.        
  16.        // 解析video元素
  17.        NSArray *elementArray = [doc.rootElement elementsForName:@"video"];
  18.        
  19.        
  20.        // 遍历数组
  21.        for (GDataXMLElement *element in elementArray) {
  22.            
  23.            LDVideo *video = [[LDVideo alloc] init];
  24.            
  25.            // 将字典中的值赋值给模型对象的属性
  26.            video.ID = [element attributeForName:@"id"].stringValue.integerValue;
  27.            
  28.            video.name = [element attributeForName:@"name"].stringValue;
  29.            
  30.            video.length = [element attributeForName:@"length"].stringValue.integerValue;
  31.            
  32.            video.image = [element attributeForName:@"image"].stringValue;
  33.            
  34.            video.url = [element attributeForName:@"url"].stringValue;
  35.            
  36.            [self.videos addObject:video];
  37.            NSLog(@"%@", [element attributeForName:@"id"]);
  38.            NSLog(@"=====%zd", self.videos.count);
  39.        }
  40.        
  41.        // 刷新UI
  42.        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
  43.            [self.tableView reloadData];
  44.        }];
  45.        
  46.    }];
  47.    
  48. }

四. 小文件下载

1. 直接加载文件的URL进行下载

  1. -(void)dataDownload {
  2.  //1.确定资源路径
  3.   NSURL *url = [NSURLURLWithString:@"http://120.25.226.186:32812/resources/images/minion_01.png"];
  4.  //2.根据URL加载对应的资源
  5.  NSData *data = [NSData dataWithContentsOfURL:url];
  6.  //3.转换并显示数据
  7.  UIImage *image = [UIImage imageWithData:data];
  8.   self.imageView.image = image;
  9. }

2. 发送异步函数请求下载

  1. -(void)connectDownload {
  2. //1.确定请求路径 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_01.png"];
  3. //2.创建请求对象
  4. NSURLRequest *request = [NSURLRequest requestWithURL:url];
  5. //3.使用NSURLConnection发送一个异步请求
  6. [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
  7.    //4.拿到并处理数据
  8.    UIImage *image = [UIImage imageWithData:data];
  9.    self.imageView.image = image;
  10. }];
  11. }

3. 通过NSURLConnection设置代理发送异步请求的方式下载文件

  1. -(void)connectionDelegateDownload {
  2. //1.确定请求路径 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];
  3. //2.创建请求对象
  4. NSURLRequest *request = [NSURLRequest requestWithURL:url];
  5. //3.使用NSURLConnection设置代理并发送异步请求
  6. [NSURLConnection connectionWithRequest:request delegate:self];
  7. }


4. 代理方法

  • 当接收到服务器响应的时候调用,该方法只会调用一次

  1. //当接收到服务器响应的时候调用,该方法只会调用一次
  2. -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
  3. {
  4. //创建一个容器,用来接收服务器返回的数据 self.fileData = [NSMutableData data];
  5. //获得当前要下载文件的总大小(通过响应头得到)
  6. NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
  7. self.totalLength = res.expectedContentLength;
  8. NSLog(@"%zd",self.totalLength);
  9. //拿到服务器端推荐的文件名称
  10. self.fileName = res.suggestedFilename;
  11. }
  • 当接收到服务器返回的数据时会调用 //该方法可能会被调用多次

  1. //当接收到服务器返回的数据时会调用 //该方法可能会被调用多次
  2. -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
  3. {
  4. // NSLog(@"%s",func);
  5. //拼接每次下载的数据
  6. [self.fileData appendData:data];
  7. //计算当前下载进度并刷新UI显示
  8. self.currentLength = self.fileData.length;
  9. NSLog(@"%f",1.0* self.currentLength/self.totalLength);
  10. self.progressView.progress = 1.0* self.currentLength/self.totalLength;
  11. }

  • 当网络请求结束之后调用

  1. //当网络请求结束之后调用
  2. -(void)connectionDidFinishLoading:(NSURLConnection *)connection
  3. {
  4. //文件下载完毕把接受到的文件数据写入到沙盒中保存
  5. //1.确定要保存文件的全路径
  6. //caches文件夹路径
  7. NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
  8. NSString *fullPath = [caches stringByAppendingPathComponent:self.fileName];
  9. //2.写数据到文件中
  10. [self.fileData writeToFile:fullPath atomically:YES];
  11. NSLog(@"%@",fullPath);
  12. }

  • 当请求失败的时候调用该方法

  1. -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
  2. {
  3. NSLog(@"%s",func);
  4. }
posted @ 2015-11-27 12:46  文刂Rn  阅读(411)  评论(0编辑  收藏  举报