iOS開發 – JSON解析 – iPhone手機開發 iPhone軟體開發教學課程

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:@"https://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];
    ;
    return video;
}
@end
#import 

#define Url(path) [NSURL URLWithString:[NSString stringWithFormat:@"https://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

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *