1. 程式人生 > >iOS開發,json解析

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 

@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 

#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