ios开发进阶之网络04 数据解析 文件下载上传
来源:互联网 发布:淘宝全球购假货曝光 编辑:程序博客网 时间:2024/06/04 00:24
一 JSON
- 什么是JSON
- JSON是一种轻量级的数据格式,一般用于数据交互
- 服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外)
- JSON和OC对象转换后对应数据类型
{} -> NSDictionary @{} [] -> NSArray @[] "jack" -> NSString @"jack" 10 -> NSNumber @10 10.5 -> NSNumber @10.5 true -> NSNumber @1 false -> NSNumber @0 null -> NSNull
- JSON解析方案
- 第三方框架:JSONKit、SBJson、TouchJSON(性能从左到右,越差)
- 苹果原生(自带):NSJSONSerialization(性能最好)
- NSJSONSerialization的常见方法
// JSON数据 → OC对象+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;
- NSJSONReadingOptions
- NSJSONReadingMutableContainers = (1UL << 0)
- 创建出来的数组和字典就是可变
- NSJSONReadingMutableLeaves = (1UL << 1)
- 数组或者字典里面的字符串是可变的, iOS7以后无效
- NSJSONReadingAllowFragments
- 允许解析出来的对象不是字典或者数组,比如直接是字符串或者NSNumber
- NSJSONReadingMutableContainers = (1UL << 0)
// OC对象 → JSON数据 + (NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;
- 格式化服务器返回的JSON数据
- 在线格式化:http://tool.oschina.net/codeformat/json
- 将服务器返回的字典或者数组写成plist文件
- 复杂JSON数据解析案例代码
@interface ViewController ()@property (nonatomic, strong) NSArray *videos; /**< 视屏信息 */@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; self.tableView.rowHeight = 150; NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=JSON"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]; self.videos = dict[@"videos"]; // 注意: 拿到数据之后一定要刷新表格 [self.tableView reloadData]; }]; }#pragma mark - datasource- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.videos.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ // 1.创建cell UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; // 2.取出对应行的字典 NSDictionary *dict = self.videos[indexPath.row]; // 2.1设置数据 cell.textLabel.text = dict[@"name"]; cell.detailTextLabel.text = [NSString stringWithFormat:@"时长:%@", dict[@"length"]]; NSString *urlStr = [NSString stringWithFormat:@"http://120.25.226.186:32812/%@", dict[@"image"]]; urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; [cell.imageView sd_setImageWithURL:[NSURL URLWithString:urlStr] placeholderImage:nil]; // 3.返回cell return cell;}// 监听点击- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ // 1.取出选中行对应的字典 NSDictionary *dict = self.videos[indexPath.row]; // 2.根据字典中的URL属性拼接视屏的地址 NSString *urlStr = [NSString stringWithFormat:@"http://120.25.226.186:32812/%@", dict[@"url"]]; urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSURL *url = [NSURL URLWithString:urlStr]; // 3.播放视屏 MPMoviePlayerViewController *vc = [[MPMoviePlayerViewController alloc] initWithContentURL:url]; // 4.显示控制器 [self presentViewController:vc animated:YES completion:nil];}@end
二 字典转模型框架
- Mantle
- 所有模型都必须继承自MTModel
- JSONModel
- 所有模型都必须继承自JSONModel
- MJExtension
- 不需要强制继承任何其他类
设计框架需要考虑的问题
- 侵入性
- 侵入性大就意味着很难离开这个框架
- 易用性
- 比如少量代码实现N多功能
- 扩展性
- 很容易给这个框架增加新框架
利用苹果官方API播放视频
// 创建视频播放器MPMoviePlayerViewController *vc = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:urlStr]];// 显示视频[self presentViewController:vc animated:YES completion:nil];
三 XML
- 什么是XML
- 全称是Extensible Markup Language,译作“可扩展标记语言”
- 跟JSON一样,也是常用的一种用于交互的数据格式
- 一般也叫XML文档(XML Document)
XML语法
文档声明
- 声明XML文档的类型
元素(Element)
- 一个元素包括了开始标签和结束标签
属性(Attribute)
- 一个元素可以拥有多个属性
- XML的解析方式
- SAX
- 大小文件都可以
- NSXMLParser
- DOM
- 最好是小文件
- GDataXML
- SAX
四 XML-SAX解析 NSXMLParser
- 创建解析器来解析
// 创建XML解析器NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];// 设置代理parser.delegate = self;// 开始解析XML(parse方法是阻塞式的)[parser parse];
- 代理对象要遵守NSXMLParserDelegate协议,实现代理方法
/** * 解析到某个元素的结尾(比如解析</videos>) */- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{}/** * 解析到某个元素的开头(比如解析<videos>) */- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{}/** * 开始解析XML文档 */- (void)parserDidStartDocument:(NSXMLParser *)parser{}/** * 解析完毕 */- (void)parserDidEndDocument:(NSXMLParser *)parser{}
五 XML-DOM解析
- GDataXML基于libxml2库,得做以下配置:
- GDataXML是非ARC的,因此得设置编译参数
- 具体用法
// 加载整个文档GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil];// 获得根节点doc.rootElement;// 获得其他节点[element elementsForName:@"video"];// 获得节点的属性[element attributeForName:@"name"].stringValue;
六 小文件下载
- 方法一
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_15.png"]; NSData *data = [NSData dataWithContentsOfURL:url];
- 方法二
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_15.png"]; [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:url] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { }];
七 大文件下载
- 如果是大文件下载,建议使用NSURLSession或者第三方框架
- (void)viewDidLoad { [super viewDidLoad]; NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_15.mp4"]; [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:url] delegate:self];}#pragma mark - NSURLConnectionDataDelegate- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response{ // 判断如果有数据, 就不需要重新创建 if (self.currentLength) return; // 获取文件总大小// self.contentLength = [response.allHeaderFields[@"Content-Length"] integerValue]; self.contentLength = response.expectedContentLength; NSLog(@"%@", XMGFile); // 创建一个空的文件 [[NSFileManager defaultManager] createFileAtPath:XMGFile contents:nil attributes:nil]; // 创建文件句柄 self.handle = [NSFileHandle fileHandleForWritingAtPath:XMGFile];}// 不将文件保存到内存中,一边下载一边写入磁盘中,防止内存暴增- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ // 指定数据的写入位置 -- 文件内容的最后面 [self.handle seekToEndOfFile]; // 写入数据 [self.handle writeData:data]; // 拼接总长度 self.currentLength += data.length; self.progressView.progress = 1.0 * self.currentLength / self.contentLength; NSLog(@"%f", self.progressView.progress);}// 下载完毕一定要关闭文件句柄- (void)connectionDidFinishLoading:(NSURLConnection *)connection{ // 关闭handle [self.handle closeFile]; self.handle = nil; // 清空长度 self.currentLength = 0; self.contentLength = 0;}- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{}
八 输出流
- 用NSOutputStream可以将网络请求的资源回来的数据保存到本地文件
- (NSOutputStream *)outputStream{ if (!_outputStream) { /* 第一个参数: 告诉系统数据流需要输出到哪个文件中 第二个参数: 如果传入YES, 代表每次都在上一次的后面追加 如果传入NO, 代表每次都从头开始 */ _outputStream = [NSOutputStream outputStreamToFileAtPath:self.path append:YES]; // 注意: 如果想利用输出流写入数据, 一定要打开数据流 // 如果数据流打开的文件不存在, 那么会自动创建个新的 [_outputStream open]; } return _outputStream;}
// 接收到服务器的数据调用(会调用一次或多次)- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ // 直接写入数据 /* 第一个参数: 需要写入的数据 第二个参数: 写入数据的大小 */ [self.outputStream write:data.bytes maxLength:data.length]; // 计算进度 self.currentLength += data.length; self.progressView.progress = 1.0 * self.currentLength / self.totalLength;}// 接收完毕时调用- (void)connectionDidFinishLoading:(NSURLConnection *)connection{ // 关闭输出流 [self.outputStream close]; self.outputStream = nil;}
九 文件断点下载
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; // 拿到当前已经下载文件的大小 NSString *path = [@"minion_01.mp4" cacheDir]; NSFileManager *manager = [NSFileManager defaultManager]; NSDictionary *dict = [manager attributesOfItemAtPath:path error:nil]; //设置请求头 /* 表示头500个字节:bytes= 0-499 表示第二个500个字节:bytes= 500-999 表示最后500个字节:bytes= -500 表示500字节以后的范围:bytes= 500- 第一个和最后一个字节:bytes=0-0,-1 同时指定几个范围:bytes= 300~499,500-899 */ // 注意:从文件中获取出来的大小一定要先转换为integerVa,否则是null NSString *range = [NSString stringWithFormat:@"bytes:%zd-",[dict[NSFileSize] integerValue]]; [request setValue:range forHTTPHeaderField:@"Range"]; [NSURLConnection connectionWithRequest:request delegate:self];
十 文件压缩/解压缩
- ZipArchive
- 下载地址:https://github.com/ZipArchive/ZipArchive
- 需要引入libz.dylib框架
- 压缩
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray *)paths;+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath;
- 解压缩
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination
十一 文件上传
[request setValue:@"multipart/form-data; boundary=分割线" forHTTPHeaderField:@"Content-Type"];
设置请求体
- 文件参数
--分割线\r\nContent-Disposition: form-data; name="参数名"; filename="文件名"\r\nContent-Type: 文件的MIMEType\r\n\r\n文件数据\r\n
- 非文件参数
--分割线\r\nContent-Disposition: form-data; name="参数名"\r\n\r\n参数值\r\n
- 结束标记
参数结束的标记--分割线--\r\n
注意事项
- 请求体比请求头分割线前面
多两个--
- 结束标记比请求体后面
多两个--
十二 MIMEType
- 请求体比请求头分割线前面
利用NSURLConnection
- 万能类型 application/octet-
部分文件的MIMEType
- (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;}
- C语言API(了解)
+ (NSString *)mimeTypeForFileAtPath:(NSString *)path{ if (![[NSFileManager alloc] init] fileExistsAtPath:path]) { return nil; } CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (CFStringRef)[path pathExtension], NULL); CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass (UTI, kUTTagClassMIMEType); CFRelease(UTI); if (!MIMEType) { return @"application/octet-stream"; } return NSMakeCollectable(MIMEType);}
1 0
- ios开发进阶之网络04 数据解析 文件下载上传
- iOS 开发之网络——文件上传&文件下载
- AF ios开发之网络数据的下载与上传
- ios开发之网络数据的下载与上传
- ios开发之网络数据的下载与上传 要实现网络数据的下载与上传,主要有三种方式
- iOS开发: 网络解析数据之JSON解析
- iOS多线程与网络开发之小文件上传
- iOS之文件上传、下载(上传)
- IOS开发网络篇之使用NSConnection下载数据
- iOS之文件上传、下载(下载)
- iOS多线程与网络开发之解析json数据
- iOS开发 - 第04篇 - 网络 - 03 - 数据安全 & 文件下载
- ios网络数据下载和JSON解析
- iOS开发网络篇之文件下载、大文件下载、断点下载
- iOS开发网络篇之文件下载、大文件下载、断点下载
- iOS开发网络篇之文件下载、大文件下载、断点下载
- iOS开发网络篇之文件下载、大文件下载、断点下载
- iOS开发网络篇之文件下载、大文件下载、断点下载
- 串口驱动程序设计
- Apache Shiro 简介
- 【more effective c++读书笔记】【第4章】效率(1)
- android服务调用
- HDU 4462 Scaring the Birds (2012年杭州赛区现场赛J题)
- ios开发进阶之网络04 数据解析 文件下载上传
- while循环语句,按照既定规律输入数字,提示正确与否
- 鸡兔同笼
- 模板方法模式----深入浅出(二)
- 二叉树的定义、性质、存储
- Swift UIView 常用添加方法
- Android Listview横向滑动
- Apache Shiro 10分钟之旅!
- 8月的总结---适应职场,锤炼自我