JSON数据的解析

2017-03-09  本文已影响88人  小胖子2号

什么是JSON

  1. JSON是一种轻量级的数据格式,一般用于数据交互

  2. 服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外)

  3. JSON的格式很像OC中的字典和数组

    {"name" : "jack", "age" : 10}
    {"names" : ["jack", "rose", "jim"]}
    ** 标准JSON格式的注意点:key必须用双引号 **

  4. 要想从JSON中挖掘出具体数据,得对JSON进行解析

  5. JSON – OC 转换对照表

    1.png
  6. JSON – OC 转换练习


    2.png

JSON解析方案

在iOS中,JSON的常见解析方案有4种

解析来自服务器的JSON

3.png

json数据-> OC对象

-(void)JSONtoOC
{    //1.确定请求路径  
  NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=23&pwd=2344&type=JSON"];   
     //2.创建请求对象    
  NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];      
    //3.使用 NSURLSession 发送一个异步请求    
  [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
       //4.当接收到服务器的响应数据后解析数据(json数据————>OC数据)

       //将文字读取到字符串中
         NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);    
          
       /**把JSON转换为OC对象                     
           第一个参数:要解析的json数据,是NSDate类型也就是二进制数据
           第二个参数:可选配置参数   
                     NSJSONReadingMutableContainers:生成的是可变的字典或数组         
                     NSJSONReadingMutableLeaves:内部元素的字符串也是可变的,iOS7以后有问题         
                     NSJSONReadingAllowFragments:如果最外层不是字典或数组那么就必须用这个        
                     kNilOptions:默认         
       */        
         NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];  
         NSLog(@"%@",dict);  
        }];
}

OC对象-> son数据

-(void)OCtoJSON
{
  //    NSDictionary *dict =@{
  //                          @"name":@"xiaomage"
  //                          };       

  NSString *str = @"xiaomage";   
 /*
     - Top level object is an NSArray or NSDictionary     
     - All objects are NSString, NSNumber, NSArray, NSDictionary, or NSNull     
     - All dictionary keys are NSStrings    
     - NSNumbers are not NaN or infinity    
     1.最外层是字典或数组    
     2.元素必须是 NSString, NSNumber, NSArray, NSDictionary, NSNull    
     3.所有字典的所有的KEY都必须是NSString   
     4.NSNumber不能是NAN 或者是无穷大
     */

   /* 注意:可以通过`+ (BOOL)isValidJSONObject:(id)obj;`方法判断当前OC对象能否转换为JSON数据     
       具体限制:       
              1.obj 是NSArray 或 NSDictionay 以及他们派生出来的子类   
              2.obj 包含的所有对象是NSString,NSNumber,NSArray,NSDictionary 或NSNull        
              3.字典中所有的key必须是NSString类型的         
              4.NSNumber的对象不能是NaN或无穷大    
 */ 

   BOOL isValid = [NSJSONSerialization isValidJSONObject:str]; 
   NSLog(@"%d",isValid);      
   NSData *data = [NSJSONSerialization dataWithJSONObject:str options:kNilOptions error:nil];      
   NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
}

-(void)jsonWithOC
{   
   //模拟JOSN字符串
   //   NSString *test = @"{\"error\":\"用户名不存在\"}";
   //    NSString *test = @"[\"a\",\"b\"]";
   //    NSString *test = @"\"wending\"";
   //    NSString *test = @"false";
   //    NSString *test = @"null";   
 NSString *test = @"10.0";  
    
 //把JSON转换成Oc 
   id obj = [NSJSONSerialization JSONObjectWithData:[test dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil];  
   NSLog(@"%@",[obj class]);
    ```
  > 
  JSON数据格式和OC对象的一一对应关系    
        {} -> 字典     
[] -> 数组     
"" -> 字符串    
 10/10.1 -> NSNumber     
true/false -> NSNumber    
 null -> NSNull 

/*
json oc
{} @{}
[] @[]
u "" @""
true|false NSNumber
null NSNull == nil
*/
}

----------------------------------------------------------

#(4)如何查看复杂的JSON数据

方法一: 在线格式化http://tool.oschina.net/codeformat/json

方法二: 把解析后的数据写plist文件,通过plist文件可以直观的查看JSON的层次结构。

`[dictM writeToFile:@"/Users/文顶顶/Desktop/videos.plist" atomically:YES];`

@interface ViewController ()

/TableView的数据源/
@property (nonatomic, strong) NSArray *videos;
@end

@implementation ViewController

//1.确定请求路径
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=JSON"];
//2.创建请求对象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.发送异步请求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//4.解析数据
NSDictionary *dictM = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
// NSLog(@"%@",dictM);

     //  将字典写成plist文件,方便查看             
     [dictM writeToFile:@"/Users/xiaomage/Desktop/video.plist" atomically:YES];             
      NSArray *arrayM = dictM[@"videos"];
        
    //字典转模型
    //  NSMutableArray *arr = [NSMutableArray arrayWithCapacity:arrayM.count];      
    //   for (NSDictionary *dict in arrayM) {
    //  [arr addObject:[XMGVideo videoWithDict:dict]];
    //  }              

     //字典数组       
    self.videos = [XMGVideo objectArrayWithKeyValuesArray:arrayM];             
    NSLog(@"----%@",self.videos);   
 
     //5.刷新TableView        
    [self.tableView reloadData];          
     }];

}

pragma mark TableViewDataSource

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.videos.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *ID = @"video";
//1.创建cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];

//拿到该行cell对应的数据
// NSDictionary *videoDict = self.videos[indexPath.row];

XMGVideo *video = self.videos[indexPath.row];

//2.设置cell的数据
/*
cell.textLabel.text = videoDict[@"name"];
NSString *detailStr = [NSString stringWithFormat:@"%@",videoDict[@"length"]];
cell.detailTextLabel.text = detailStr;
NSString *baseUrl = @"http://120.25.226.186:32812/";
NSURL *imageUrl =[NSURL URLWithString:[baseUrl stringByAppendingPathComponent:videoDict[@"image"]]];
[cell.imageView sd_setImageWithURL:imageUrl placeholderImage:[UIImage imageNamed:@"123"]];
*/

cell.textLabel.text = video.name;
NSString *detailStr = [NSString stringWithFormat:@"%zd",video.length];
cell.detailTextLabel.text = detailStr;
// 拼接图片URL地址
NSString *baseUrl = @"http://120.25.226.186:32812/";
NSURL *imageUrl =[NSURL URLWithString:[baseUrl stringByAppendingPathComponent:video.image]];
[cell.imageView sd_setImageWithURL:imageUrl placeholderImage:[UIImage imageNamed:@"123"]];

NSLog(@"ID---%@",video.ID);

//3.返回cell
return cell;
}

pragma mark---TableViewDelegate

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//1.拿到数据
// NSDictionary *videoDict = self.videos[indexPath.row];
XMGVideo *video = self.videos[indexPath.row];
NSString *baseUrl = @"http://120.25.226.186:32812/";
NSURL *mpUrl = [NSURL URLWithString:[baseUrl stringByAppendingPathComponent:video.url]];

// MPMoviePlayerController
MPMoviePlayerViewController *vc = [[MPMoviePlayerViewController alloc]initWithContentURL:mpUrl];
[self presentViewController:vc animated:YES completion:nil];
}


#补充:视频的简单播放

1. 需要导入系统框架 #import <MediaPlayer/MediaPlayer.h>

//1.拿到该cell对应的数据字典
XMGVideo *video = self.videos[indexPath.row];

NSString *videoStr = [@"http://120.25.226.186:32812" stringByAppendingPathComponent:video.url];

//2.创建一个视频播放器
MPMoviePlayerViewController *vc = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:videoStr]];

//3.present播放控制器
[self presentViewController:vc animated:YES completion:nil];


# 字典转模型框架

(1)相关框架

     a.Mantle 需要继承自MTModel
     b.JSONModel 需要继承自JSONModel
     c.MJExtension 不需要继承,无代码侵入性

(2)自己设计和选择框架时需要注意的问题

    a.侵入性
    b.易用性,是否容易上手
    c.扩展性,很容易给这个框架增加新的功能

(3)MJExtension框架的简单使用

//1.把字典数组转换为模型数组

//使用MJExtension框架进行字典转模型
self.videos = [XMGVideo objectArrayWithKeyValuesArray:videoArray];

//2.重命名模型属性的名称

//第一种重命名属性名称的方法,有一定的代码侵入性

//设置字典中的id被模型中的ID替换
+(NSDictionary *)replacedKeyFromPropertyName
{
return @{
@"ID":@"id"
};
}

//第二种重命名属性名称的方法,代码侵入性为零
[XMGVideo setupReplacedKeyFromPropertyName:^NSDictionary *{
return @{
@"ID":@"id"
};
}];

//3.MJExtension框架内部实现原理-运行时

上一篇下一篇

猜你喜欢

热点阅读