iOS开发 - JSON解析

JSON解析

什么是JSON
JSON是一种轻量级的数据格式,一般用于数据交互
服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外)

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

{"name" : "jack", "age" : 10}
{"names" : ["jack", "rose", "jim"]}

标准JSON格式的注意点:key必须用双引号

要想从JSON中挖掘出具体数据,得对JSON进行解析
JSON 转换为 OC数据类型

JSON – OC 转换对照表

JSON OC
大括号 { } NSDictionary
中括号 [ ] NSArray
双引号 ” “ NSString
数字 10、10.8 NSNumber

JSON解析方案

在iOS中,JSON的常见解析方案有4种
第三方框架:JSONKit、SBJson、TouchJSON(性能从左到右,越差)
苹果原生(自带):NSJSONSerialization(性能最好)

NSJSONSerialization的常见方法
//JSON数据 到 OC对象
+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;

//OC对象 到 JSON数据 
+ (NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;

解析来自服务器的JSON

技术分享

JSON解析实例

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextField *username;
@property (weak, nonatomic) IBOutlet UITextField *pwd;
- (IBAction)login;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.view endEditing:YES];
}

- (IBAction)login {
    // 1.用户名
    NSString *usernameText = self.username.text;
    if (usernameText.length == 0) {
        [MBProgressHUD showError:@"请输入用户名"];
        return;
    }

    // 2.密码
    NSString *pwdText = self.pwd.text;
    if (pwdText.length == 0) {
        [MBProgressHUD showError:@"请输入密码"];
        return;
    }

    // 3.发送用户名和密码给服务器(走HTTP协议)
    // 创建一个URL : 请求路径
    NSString *urlStr = [NSString stringWithFormat:@"http://localhost:8080/Server/login?username=%@&pwd=%@",usernameText, pwdText];
    NSURL *url = [NSURL URLWithString:urlStr];

    // 创建一个请求
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
//    NSLog(@"begin---");

    // 发送一个同步请求(在主线程发送请求)
    // queue :存放completionHandler这个任务
    NSOperationQueue *queue = [NSOperationQueue mainQueue];
    [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:
     ^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        // 这个block会在请求完毕的时候自动调用
        if (connectionError || data == nil) {
            [MBProgressHUD showError:@"请求失败"];
            return;
        }

        // 解析服务器返回的JSON数据
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
        NSString *error = dict[@"error"];
        if (error) {
            // {"error":"用户名不存在"}
            // {"error":"密码不正确"}
            [MBProgressHUD showError:error];
        } else {
            // {"success":"登录成功"}
            NSString *success = dict[@"success"];
            [MBProgressHUD showSuccess:success];
        }
     }];

//    NSLog(@"end---");
}
@end

视屏JSON数据解析实例

模型类

#import <Foundation/Foundation.h>

@interface Video : NSObject
/**
 *  ID
 */
@property (nonatomic, assign) int id;
/**
 *  时长
 */
@property (nonatomic, assign) int length;

/**
 *  图片(视频截图)
 */
@property (nonatomic, copy) NSString *image;

/**
 *  视频名字
 */
@property (nonatomic, copy) NSString *name;

/**
 *  视频的播放路径
 */
@property (nonatomic, copy) NSString *url;

+ (instancetype)videoWithDict:(NSDictionary *)dict;
@end
#import "Video.h"

@implementation Video
+ (instancetype)videoWithDict:(NSDictionary *)dict
{
    Video *video = [[self alloc] init];
    [video setValuesForKeysWithDictionary:dict];
    return video;
}
@end
#import <MediaPlayer/MediaPlayer.h>

#define Url(path) [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:8080/Server/%@", path]]

@interface VideosViewController ()
@property (nonatomic, strong) NSMutableArray *videos;
@end

@implementation VideosViewController

- (NSMutableArray *)videos
{
    if (!_videos) {
        self.videos = [[NSMutableArray alloc] init];
    }
    return _videos;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    /**
     加载服务器最新的视频信息
     */

    // 1.创建URL
    NSURL *url = Url(@"video");

    // 2.创建请求
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    // 3.发送请求
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        if (connectionError || data == nil) {
            [MBProgressHUD showError:@"网络繁忙,请稍后再试!"];
            return;
        }

        // 解析JSON数据
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
        NSArray *videoArray = dict[@"videos"];
        for (NSDictionary *videoDict in videoArray) {
            HMVideo *video = [HMVideo videoWithDict:videoDict];
            [self.videos addObject:video];
        }

        // 刷新表格
        [self.tableView reloadData];
    }];
}

#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.videos.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"video";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
    }

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

    cell.textLabel.text = video.name;
    cell.detailTextLabel.text = [NSString stringWithFormat:@"时长 : %d 分钟", video.length];

    // 显示视频截图
    NSURL *url = HMUrl(video.image);
    [cell.imageView sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"placehoder"]];

    return cell;
}

#pragma mark - 代理方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 1.取出对应的视频模型
    HMVideo *video = self.videos[indexPath.row];

    // 2.创建系统自带的视频播放控制器
    NSURL *url = Url(video.url);
    MPMoviePlayerViewController *playerVc = [[MPMoviePlayerViewController alloc] initWithContentURL:url];

    // 3.显示播放器
    [self presentViewController:playerVc animated:YES completion:nil];
}
@end

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。