美文网首页
JSON数据的解析

JSON数据的解析

作者: 小胖子2号 | 来源:发表于2017-03-09 17:50 被阅读88次

    什么是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种

    • 第三方框架:JSONKit、SBJson、TouchJSON(性能从左到右,越差)
    • 苹果原生(自带):NSJSONSerialization(性能最好)
      • NSJSONSerialization的常见方法
      • JSON数据转 OC对象
        + (id)JSONObjectWiythData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;
      • OC对象转 JSON数据
        + (NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;

    解析来自服务器的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

    • (void)viewDidLoad {
      [super viewDidLoad];
      [XMGVideo setupReplacedKeyFromPropertyName:^NSDictionary *{
      return @{
      @"ID":@"id"
      };
      }];

    //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框架内部实现原理-运行时

    相关文章

      网友评论

          本文标题:JSON数据的解析

          本文链接:https://www.haomeiwen.com/subject/wdowgttx.html