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. }
时间: 2024-08-13 23:42:10

iOS开发网络多线程之网络请求文件解析的相关文章

iOS开发,如何打包静态库.a文件

1.需求 我们在开发iOS的工作中可能会自己开发一些.a静态库或者打包一下别人的第三方类库包装成自己的.a文件.有时候我们引入一些C++编译的第三方文件时可能会出现编译的错误,但是我们如果打包成.a静态库时就很少会出现OC与C++混编的错误,原因很简单.a静态库文件是编译好的二进制文件,二进制文件与二进制文件互相混编当然没有什么问题.好那么接下来我们开始学习打包吧! 2.实例 接下来我们就以打包IOS开发中常用的网络请求库AFNetworking为实例. 1>我们需要准备好需要打包的AFNetw

iOS开发之多线程编程

iOS开发之多线程编程 1. 多线程简述 1.1什么是多线程? 解决的问题? 多线程是指,编程中在主线程之外开辟的新线程,用于处理一些耗时的.并发的任务.使用多线程可以避免主线程的阻塞,也对一个线程不容易实现的任务提供了思路.在多线程的知识中也涉及队列,锁等概念. 在这里科普一下队列的概念,队列:是管理线程的,相当于线程池,能管理线程什么时候执行.队列分为串行队列和并行队列. 串行队列:队列中的线程按顺序执行(不会同时执行) 并行队列:队列中的线程会并发执行,可能会有一个疑问,队列不是先进先出吗

ios开发中iphone模拟器中程序文件和数据库的存放位置

1.使用命令: chflags nohidden ~/library/ 使隐藏的资源库文件夹显示出来.如果想要隐藏掉,使用:chflags hidden ~/library/ 2.finder中找到:用户->mwsn(这是我的用户名)->资源库->Application Support->iPhone Simulator->7.0(根据你的版本确定是哪个)->Applications 里面有一堆目录,挨个查看,找到你需要的工程的目录->Documents文件夹,你

iOS开发之多线程——GCD介绍

iOS开发之多线程——GCD的介绍 一.简单介绍 1.GCD ( Grand Central Dispatch) 可以翻译为“中枢调度器”.纯C语言,并且提供了非常强大的函数. 2.GCD 有什么优势: GCD是苹果公司为多核的并行运算提出的解决方案 GCD会自动利用更多地CPU 内核 (比如双核.四核) GCD会自动管理线程的生命周期 (创建线程.调度任务.销毁线程) 程序猿只需要告诉GCD想要执行设呢任务,不需要编写任何线程管理代码. 二.任务和队列 GCD中有两个核心概念 (1)任务: 执

QT开发(四十一)——XML文件解析基础

QT开发(四十一)--XML文件解析基础 一.XML文档简介 XML(Extensible Markup Language,可扩展标记语言),是一种通用的文本格式,被广泛运用于数据交换和数据存储,而不是显示数据.XML的标签没有被预定义,用户需要在使用时自行进行定义.XML是W3C(万维网联盟)的推荐标准.相对于数据库表格的二维表示,XML使用的树形结构更能表现出数据的包含关系,作为一种文本文件格式,XML简单明了的特性使得它在信息存储和描述领域非常流行. <?xml version="1

IOS开发之自动布局显示网络请求内容

在上一篇博客中详细的介绍了IOS开发中的相对布局和绝对布局,随着手机屏幕尺寸的改变,在App开发中为了适应不同尺寸的手机屏幕,用自动布局来完成我们想要实现的功能和效果显得尤为重要.本人更喜欢使用相对布局.在下面要学习的例子中暂且先用我们的StoryBoard来设置我们组件的约束,以后会在代码中给我们的元素新建约束.iPhone4,5和将要发布的iPhone6的屏幕的大小都不一样,所以屏幕的适配是我们搞App开发必须要考虑的问题. 我们要完成一个什么例子呢,先上两张程序运行最终的结果图,之后看着图

iOS开发之监听网络连接,改变,断开

做iOS开发时,我们需要监控/监听网络状况,苹果提供了Reachability.h, Reachability.m. 导入Reachability.h 我们可以在 MainViewController的viewDidLoad方法内部写上: [self checkReachability]; 之后,具体方法如下 #pragma mark #pragma mark Reachability Methods #pragma mark - (void)checkReachability { [[NSNo

iOS开发中多线程基础

耗时操作演练 代码演练 编写耗时方法 - (void)longOperation { for (int i = 0; i < 10000; ++i) { NSLog(@"%@ %d", [NSThread currentThread], i); } } 直接调用耗时方法 // 1> 直接调用耗时方法 [self longOperation]; 运行測试效果 在后台运行耗时方法 // 2> 在后台运行耗时方法 [self performSelectorInBackgro

iOS开发之多线程技术——GCD篇

本篇将从四个方面对iOS开发中GCD的使用进行详尽的讲解: 一.什么是GCD 二.我们为什么要用GCD技术 三.在实际开发中如何使用GCD更好的实现我们的需求 一.Synchronous & Asynchronous 同步 & 异步 二.Serial Queues & Concurrent Queues 串行 & 并发 三.Global Queues全局队列 四.Main Queue主队列 五.同步的作用 六.dispatch_time延迟操作 七.线程安全(单例dispa