1、JSON認(rèn)識(shí)
- 什么是json
- JSON是一種輕量級(jí)的數(shù)據(jù)格式,一般用于數(shù)據(jù)交互
- 服務(wù)器返回給客戶(hù)端的數(shù)據(jù),一般都是JSON格式或者XML格式(文件下載除外)
- 1.2 注意點(diǎn)
- 標(biāo)準(zhǔn)JSON格式的注意點(diǎn):
key必須用雙引號(hào)
JSON解析方案
- 在iOS中,JSON的常見(jiàn)解析方案有
4種
- 第三方框架:JSONKit、SBJson、TouchJSON(性能從左到右,越差)
- 蘋(píng)果原生(自帶):NSJSONSerialization(
性能最好
)- NSJSONSerialization的常見(jiàn)方法
// JSON數(shù)據(jù) -> OC對(duì)象
+ (id)JSONObjectWithData:(NSData*)data options:(NSJSONReadingOptions)opt error:(NSError**)error;
// OC對(duì)象 -> JSON數(shù)據(jù)
+ (NSData*)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError**)error;
2、JSON — OC相互轉(zhuǎn)換
- JSON和OC對(duì)象轉(zhuǎn)換后對(duì)應(yīng)數(shù)據(jù)類(lèi)型
JSON和OC對(duì)象轉(zhuǎn)換.png
{} -> NSDictionary @{}
[] -> NSArray @[]
"jack" -> NSString @"jack"
10 -> NSNumber @10
10.5 -> NSNumber @10.5
true -> NSNumber @1
false -> NSNumber @0
null -> NSNull
// 利用NSJSONSerialization類(lèi)
+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;
// 例如將json轉(zhuǎn)換成OC字典
/*
第一個(gè)參數(shù): 需要轉(zhuǎn)換的json數(shù)據(jù)
第二個(gè)參數(shù): 告訴系統(tǒng)如何轉(zhuǎn)換json數(shù)據(jù)(轉(zhuǎn)換出來(lái)的對(duì)象是否可變/子對(duì)象是否課變/是否是標(biāo)準(zhǔn)json)
NSJSONReadingMutableContainers = 轉(zhuǎn)換出來(lái)的對(duì)象是可變數(shù)組或者可變字典
NSJSONReadingMutableLeaves = 轉(zhuǎn)換出來(lái)的OC對(duì)象中的字符串是可變的 \ 注意: iOS7之后無(wú)效 bug
NSJSONReadingAllowFragments = 如果服務(wù)器返回的JSON數(shù)據(jù), 不是標(biāo)準(zhǔn)的JSON, 那么就必須使用這個(gè)值, 否則無(wú)法解析,允許解析出來(lái)的對(duì)象不是字典或者數(shù)組,比如直接是字符串或者NSNumber,比如直接是字符串或者NSNumber :{15}, {"abc"}
第三個(gè)參數(shù): 錯(cuò)誤信息
*/
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
4、OC對(duì)象 -> JSON數(shù)據(jù)(NSData)
// 利用NSJSONSerialization類(lèi)
+ (NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;
5、格式化服務(wù)器返回的JSON數(shù)據(jù)
- 在線格式化:http://tool.oschina.net/codeformat/json
- 將服務(wù)器返回的字典或者數(shù)組寫(xiě)成plist文件
6、JSON解析小案例
- 解析來(lái)自服務(wù)器的JSON
解析JSON.png
#import "ViewController.h"
#import <SDWebImage/UIImageView+WebCache.h>
#import <MediaPlayer/MPMoviePlayerViewController.h>
#import "JPVideo.h"
#import <MJExtension/MJExtension.h>
@interface ViewController ()
@property (nonatomic, strong) NSArray *videos; /**< 視屏信息 */
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 只需要在字典轉(zhuǎn)模型之前, 告訴框架要將模型中的哪個(gè)屬性和字典中的哪個(gè)KEY對(duì)應(yīng)
[JPVideo setupReplacedKeyFromPropertyName:^NSDictionary *{
return @{@"ID":@"id"};
}];
self.tableView.rowHeight = 150;
// Do any additional setup after loading the view, typically from a nib.
NSURL *url = [NSURL URLWithString:@"/video?type=JSON"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// 解析來(lái)自服務(wù)器的data的josn數(shù)據(jù) - > OC字典
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
// self.videos = dict[@"videos"];
// 字典轉(zhuǎn)模型
/*
NSMutableArray *models = [NSMutableArray array];
for (NSDictionary *videoDict in dict[@"videos"]) {
JPVideo *video = [JPVideo videoWithDict:videoDict];
[models addObject:video];
}
self.videos = [models copy];
*/
/* 使用MJExtension的優(yōu)點(diǎn):
1.沒(méi)有任何依賴(lài)關(guān)系
2.模型中的屬性, 不用和字典中的key一一對(duì)應(yīng)
*/
self.videos = [JPVideo objectArrayWithKeyValuesArray:dict[@"videos"]];
// 注意: 拿到數(shù)據(jù)之后一定要刷新表格
[self.tableView reloadData];
}];
}
#pragma mark - datasource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.videos.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1.創(chuàng)建cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
// 2.取出對(duì)應(yīng)行的字典
JPVideo *video = self.videos[indexPath.row];
// 2.1設(shè)置數(shù)據(jù)
cell.textLabel.text = video.name;
cell.detailTextLabel.text = [NSString stringWithFormat:@"時(shí)長(zhǎng):%@", video.length];
NSString *urlStr = [NSString stringWithFormat:@"http://120.25.226.186:32812/%@", video.image];
urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:urlStr] placeholderImage:nil];
// 3.返回cell
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1.取出選中行對(duì)應(yīng)的字典
JPVideo *video = self.videos[indexPath.row];
// 2.根據(jù)字典中的URL屬性拼接視屏的地址
NSString *urlStr = [NSString stringWithFormat:@"/%@", video.url];
urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlStr];
// 3.播放視屏
MPMoviePlayerViewController *vc = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
// 4.顯示控制器
[self presentViewController:vc animated:YES completion:nil];
}
@end