JSON解析和网络下载

来源:互联网 发布:白苹果刷机数据恢复 编辑:程序博客网 时间:2024/05/29 15:27
# JSON解析和网络下载


##目录


#### 1.网络数据下载简述
#### 2.系统类下载数据
#### 3.JSON解析
#### 4.AFNetworking初步-GET请求
#### 5.AFNetworking初步-图片异步下载


##1.网络数据下载简述


#### 1.什么是网络应用,本地应用?
> 网络应用:类似于QQ、微博、网易新闻、优酷、百度地图等需要通过网络根外界进行数据交互,实时更新数据,使应用保持新鲜,活力的此类应用称为网络应用。(应用的数据来源于网络)。


> 本地应用: 相机, 计算器, 闹钟, 备忘录, 手电筒等数据来源于本地,无需通过网络于外界进行数据交换的应用。


#### 2.什么是客户端, 什么是服务端?


>客户端(Client):移动应用,和用户进行交互。(iOS、android等应用)。通过客户端向服务器发起请求(Request),索取数据。


>服务端(Server):为客户端提供服务、提供数据、提供资源的机器。针对服务端的请求,做出反应,一般指返回数据给客户端。


##2.系统类下载数据


#### 1.NSString


> * NSString类下载数据


```objectivec
// 通过给定的一个url,按照给定的编码方式将数据返回给NSString对象
NSString *my_string = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
```


#### 2.NSData
> * NSData类数据的下载步骤:
  
```objectivec
// 将下载的图片数据转换成NSData数据
 NSArray *array = @[@"http://ww4.sinaimg.cn/large/6860f8cagw1ewd822kncqj20dw0kujt7.jpg",
                    @"http://ww2.sinaimg.cn/large/9dae2c1fgw1ewdhzlf66zj21kw2d8nne.jpg",
                    @"http://ww4.sinaimg.cn/large/9dae2c1fgw1ewdhza7d32j21kw2d8as3.jpg",
                    @"http://ww4.sinaimg.cn/large/006bdUirgw1ewcow3h64wj30go0po41r.jpg",
                    @"http://ww3.sinaimg.cn/large/006bdUirgw1ewcovp5xz2j30go0poju4.jpg",
                    @"http://ww2.sinaimg.cn/large/c27e3f6bgw1ewbpnfp1bdj20ij0rsaeq.jpg",
                    @"http://ww2.sinaimg.cn/large/c27e3f6bgw1ewbpmgq9jvj20ij0rs79f.jpg",
                    @"http://ww3.sinaimg.cn/large/ c27e3f6bgw1ewbpmfjrpsj20ij0rsjwj.jpg"];
 for (int i=0; i<array.count; i++) {
  NSURL *url = [NSURL URLWithString:array[i]];
   // 利用这个下载方式,是同步的。
   NSData *data = [[NSData alloc] initWithContentsOfURL:url];
   // 什么时候下载完成数据,什么时候才能开始对下载的data进行处理。
   UIImageView *imageView = _imageViews[i];
   // 用2进制数据,来创建一个image
   imageView.image = [UIImage imageWithData:data];
  }
```


#### 3.NSURLConnection同步下载
>1、同步下载交互不好,容易出现卡死现象,一般下载数据较小或有特定需求才使用。(在创建一个同步的网络连接的时候我们需要明白一点,并不是是我们的这个同步连接一定会堵塞我们的主线程,如果这个同步的连接是创建在主线程上的,那么这种情况下是会堵塞我们的主线程的,其他的情况下是不一定会堵塞我们的主线程的)。


>* 使用 NSURLConnection 的sendSynchronousRequest:returningResponse:error:类方法,我们可以进行同步请求。


> * 同步下载步骤:


```objectivec
1.创建NSURL
NSURL *url = [[NSURL alloc] initWithString:@"http://www.baidu.com/"];
2.通过URL创建NSURLRequest
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15]; 
/*
  cachePolicy 缓存协议是个枚举类型:
  NSURLRequestUseProtocolCachePolicy 基础策略
  NSURLRequestReloadIgnoringLocalCacheData 忽略本地缓存
  NSURLRequestReturnCacheDataElseLoad 首先使用缓存,如果没有本地缓存,才从原地址下载
  NSURLRequestReturnCacheDataDontLoad 使用本地缓存,从不下载,如果本地没有缓存,则请求失败。此策略多用于离线操作
  NSURLRequestReloadIgnoringLocalAndRemoteCacheData 无视任何的缓存策略,无论是本地还是远程,总是从原地址重新下载
  NSURLRequestReloadRevalidatingCacheData 如果本地缓存是有效的则不下载。其他任何情况都从原地址重新下载
*/
3.建立网络连接NSURLConnection,同步请求数据 
   NSData *receivedData = (NSMutableData *)[NSURLConnection sendSynchronousRwquest:request returningResponse:&response error:&error];
`4.以上三步后,就需要将receivedData进行解析,一般是XML/JSON。 


```




#### 4)NSURLConnection异步下载
>1.异步下载支持应用程序在后台下载数据,在等待下载完成的过程中不会阻塞当前进行中代码的运行。NSURLConnection同步和异步唯一的不同就是NSURLConnection对象的创建方式、在initWithRequest: degate指定其代理方法时就开始下载,其代理方法能获取整个下载过程。


步骤:


```objectivec 
// 异步下载
NSArray *array = @[@"http://ww4.sinaimg.cn/large/6860f8cagw1ewd822kncqj20dw0kujt7.jpg",
                    @"http://ww2.sinaimg.cn/large/9dae2c1fgw1ewdhzlf66zj21kw2d8nne.jpg",
                    @"http://ww4.sinaimg.cn/large/9dae2c1fgw1ewdhza7d32j21kw2d8as3.jpg",
                    @"http://ww4.sinaimg.cn/large/006bdUirgw1ewcow3h64wj30go0po41r.jpg",
                    @"http://ww3.sinaimg.cn/large/006bdUirgw1ewcovp5xz2j30go0poju4.jpg",
                    @"http://ww2.sinaimg.cn/large/c27e3f6bgw1ewbpnfp1bdj20ij0rsaeq.jpg",
                    @"http://ww2.sinaimg.cn/large/c27e3f6bgw1ewbpmgq9jvj20ij0rs79f.jpg",
                    @"http://ww3.sinaimg.cn/large/ c27e3f6bgw1ewbpmfjrpsj20ij0rsjwj.jpg"];
for (int i=0; i<array.count; i++) {
// 1. 将请求的接口字符串,转换成url对象。
NSURL *url = [NSURL URLWithString:array[i]];
// 2. 根据url对象,创建一个请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 3. 根据请求,建立连接,这样,就已经开始请求数据了。但是,数据什么时候请求完成,我们不知道。但是,NSURLConnection知道。所以,要设置代理。 (下载完成,NSURLConnection会调用代理方法,那么我们实现这个方法,就相当于下载完成,调用到我们的方法里了,我们处理下载的数据)。
NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
}
// 当收到服务器的响应的时候,会调用。也就意味着,将要开始下载数据了。
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    NSHTTPURLResponse *r = (NSHTTPURLResponse *)response;
    NSLog(@"收到服务器的响应,状态码:%ld",r.statusCode);
    // 清空_data中得数据。
    //_data.length = 0;
}
// 将请求到的数据,追加到_data中。 这个方法会根据请求的内容的不同,调用多次。
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    NSLog(@"收到数据了");
    [_data appendData:data];
}
// 请求完成,会调用这个方法。 我们可以在这里,处理数据
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    UIImageView *imageView = _imageViews[0];
    imageView.image = [UIImage imageWithData:_data];
}
```


##3.JSON解析


#### 1.JSON数据格式


从结构上看,所有的数据(data)最终都可以分解成三种类型:
> 1. 第一种类型是标量(scalar),也就是一个单独的字符串(string)或数字(numbers),比如"北京"这个单独的词。 
>2. 第二种类型是序列(sequence),也就是若干个相关的数据按照一定顺序并列在一起,又叫做数组(array)或列表(List),比如"北京,上海"。
>3. 第三种类型是映射(mapping),也就是一个名/值对(Name/value),即数据有一个名称,还有一个与之相对应的值,这又称作散列(hash)或字典(dictionary),比如"首都:北京"。


Json的规格非常简单,只用一个页面几百个字就能说清楚,从某种意义上来说这个规格永远不必升级,因为该规定的都规定了。
> 1. 并列的数据之间用逗号(", ")分隔。
> 2. 映射用冒号(": ")表示。
> 3. 并列数据的集合(数组)用方括号("[]")表示。
> 4. 映射的集合(对象)用大括号("{}")表示。




#### 2.使用系统类解析JSON


官方为我们提供的解析JSON数据的类是NSJSONSerialization,首先我们先来看下这个类的几个方法:




* 判断一个数据对象是否可以转化为JSON数据


> + (BOOL)isValidJSONObject:(id)obj;




* 将JSON数据写为NSData数据,其中opt参数的枚举如下,这个参数可以设置,也可以不设置,如果设置,则会输出视觉美观的JSON数据,否则输出紧凑的JSON数据。


> + +(NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;


> +  typedef NS_OPTIONS(NSUInteger, NSJSONWritingOptions) {
     NSJSONWritingPrettyPrinted = (1UL << 0)
}


* 这个方法是解析中数据的核心方法,data是JSON数据对象,可以设置一个opt参数,具体用法如下:
 
 > + +(id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;




```objectivec
typedef NS_OPTIONS(NSUInteger, NSJSONReadingOptions) {
//将解析的数组和字典设置为可变对象
   NSJSONReadingMutableContainers = (1UL << 0),
   //将解析数据的子节点创建为可变字符串对象
   NSJSONReadingMutableLeaves = (1UL << 1),
   //允许解析对象的最上层不是字典或者数组
   NSJSONReadingAllowFragments = (1UL << 2)
}
```
* 将JSON数据写入到输出流,返回的是写入流的字节数
>+ (NSInteger)writeJSONObject:(id)obj toStream:(NSOutputStream *)stream options:(NSJSONWritingOptions)opt error:(NSError **)error;




* 从输入流读取JSON数据
>+ (id)JSONObjectWithStream:(NSInputStream *)stream options:(NSJSONReadingOptions)opt error:(NSError **)error;
```




##4.AFNetworking初步 - GET请求
 


```objectivec 
// 1. 请求的url 
 NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://rss.sina.com.cn/sina_all_opml.xml"]];
// 2. 先获取一个网络请求对象(单例)
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
// 3. 不同接口响应的数据格式可能不同,因此我们一般都将响应数据格式设置为二进制形式。
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
// 4. 第一个参数,是请求的网络接口,字符串;第二个参数,是请求的参数;第三个参数,是请求成功后,执行的block;第四个参数,是请求失败后,执行的block。
[manager GET:url success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"%@", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"error : %@", error);
    }];
```


##5.AFNetworking初步 - 图片异步下载


```objectivec
// AF可以异步加载图片,需要导入 UIKit+AF头文件
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 50, 250, 150)];
[self.view addSubview:imageView];
// 异步加载网络图片
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://img4.duitang.com/uploads/item/201401/29/20140129132055_m32sc.thumb.600_0.jpeg"]];
[imageView setImageWithURL:url placeholderImage:[UIImage imageNamed:@"image.png"]];


```
0 0
原创粉丝点击