zoukankan      html  css  js  c++  java
  • 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. }
  • 相关阅读:
    Java面向对象(继承、抽象类)
    Java面向对象(类、封装)
    Java基础语法(Eclipse)
    JavaScript new对象的四个过程
    原生js实现深复制
    es6 实现双链表
    快速排序
    跨域问题
    pm2 使用
    js冒泡排序
  • 原文地址:https://www.cnblogs.com/Xfsrn/p/5000325.html
Copyright © 2011-2022 走看看