JSON
- Javascript Object Notation( Javascript的对象表示法)
- JSON是Javascript中的对象,在 Javascript中解析JSON对象很方便
- JSON具有自我描述性,更易理解
- 通常在网络传输数据的时候会使用JSON或XML,JSON比XML更轻量级使用更加广泛
- JSON独立于语言,其它语言中一般都有解析JSON的库
JSON语法规则
- 数据在名称/值对中
- 数据由逗号分隔
- 花括号保存对象
- 方括号保存数组
JSON的格式
{}对象{"key":" value","k1":"v1"}
[]数组[{},{}]
JSON的值可以是:数字(整数或浮点数)、字符串(在双引号中)、逻辑值(true或 false)数组(在方括号中)、对象(在花括号中)、null
JSON示例
描述一个学生
{"name": "张三", "age": 18, "gender": 1, "friends":["Is","ww"])
描述一些学生
[{"name":"zs","age": 18),{"name":"zs","age": 18}]
描述一个班级
{"classname":"一班", "students":[{"name":"zs","age": 18},{"name":"zs","age":18}]}
JSON的解析(反序列化)
request
返回的response
的data
是json形式的字符串
- JSON序列化:把对象转化成JSON形式的字符串
- JSON的反序列化:把JSON形式的字符串转换成OC中的对象
NSJSONSerialization
NSError *error;
//解析的JSON字符串,返回的OC对象可能是数组[]或字典{}
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if(error){NSLog(@"解析JSON出错 %@",error);}
else{
NSLog(@"%@",json);
NSLog(@"%@",[json class]);//输出json的类型
}
options:
0 不可变容器NSCFDictionary
NSJSONReadingMutableContainers = (1UL<<0) 可变容器NSCFDictionaryM
NSJSONReadingMutableLeaves = (1UL<<1) 叶子可变,ios7以后不起作用
NSJSONReadingAllowFragments = (1UL<<2) 允许不是JSON形式的字符串
解决数组输出汉字的问题
建立分类,重写descriptionWithLocale
方法
-(NSString *)descriptionWithLocale:(id)locale{
NSMutableString *mStr = [NSMutableString string];
[mStr appendString:@"(\r\n"];
[self enumerateObjectsUsingBlock:^(id _Nonnull obj,NSUInteger idx,BOOL * _Nonnull stop){
[mStr appendFormat:@"\t%@,\r\t",obj];
}];
[mStr appendString:@")"];
return mStr.copy;
}
description
NSLog
直接输出对象,其实是调用了description
方法
-(NSSTring *)description{
return[NSString stringWithFormat:@"{name:%@,age:%@}",self.name,self.age];
}
JSON数据转模型(字典转模型)
+(instancetype)PersonWithJSON:(NSDictionary *)dic{
Person *per = [self new];
[per setValuesForKeysWithDictionary:dic];//自动遍历按照字典和模型的键值对进行赋值
return per;
}
-(void)setValue:(id)value forUndefinedKey:(NSString *)key{
setValuesForKeysWithDictionary方法,当字典大于模型,会报错,重新该方法就不会了
}
setValuesForKeysWithDictionary
方法
int
类型建议定义为NSNumber
类型 ,输出用self.NSNumber数据.intValue
,就能让nil
数据输出为0
JSON解析的第三方框架
第三方框架
JSONkit、SBJSON、TouchJSON
JSONkit
2012年停止更新,iOS5以前用的多
JSONkit的演示
JSONkit
是MRC
的- 导入
JSONkit
,并设置编译方式为MRC
NSDictionary *dic =[[JSONDecoder decoder] objectWithData: data];
解析plist和JSON的相似
NSJSONSerialization
NSPropertyListSerializationl
//解析的JSON字符串,返回的OC对象可能是数组[]或字典{}
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
id plist = [NSPropertyListSerializationl propertyListWithData:data options:0 error:NULL];
plist
文件是iOS特有的,一般很少用,多用JSON
JSON序列化
//方法一:自己拼
NSString *jsonStr = @"{\"name\":\"zhangsan\",\"age\":18}";
//编码
[jsonStr dataUsingEncodeing:NSUTF8StringEncoding];
//方法二:字典
NSDictionary *dic = @{@"name":@"zhangsan",@"age":@(18)};
//JSON序列化
NSData *data = [NSJSONSerialization dataWithJSONObject:dic options:0 error:NULL];
//方法三:数组
NSArray *array = @[@{@"name":@"zhangsan",@"age":@(18)},
@{@"name":@"lisi",@"age":@(19)}];
//JSON序列化
NSData *data = [NSJSONSerialization dataWithJSONObject:array options:0 error:NULL];
- 自定义对象序列化
需要把对象转为字典KVC
,内部成员变量同样可以赋值
NSDictionary *dic = [video1 dictionaryWithValuesForKeys:@[@"videoName",@"size",@"author"]]
- 对象集进行序列化
NSArray *array = @[video1,video2];
//数组存放字典
NSMutableArray *marray = [NSMuableArray arrayWithCapacity:2];
for(HMVideo *video in array){
NSDictionary *dic = [video dictionaryWithValuesForKeys:@[@"videoName",@"size",@"author"]];
[mArray addObject:dic];
}
NSData *data = [NSJSONSerialization dataWithJSONObject:mArray options:0 error:NULL];
JSON保存到文件
NSData *data = [NSJSONSerialization dataWithJSONObject:mArray options:0 error:NULL];
//写入
[data writeToFile:@"/Users/Apple/Desktop/111.json" atomically:YES];
//读取
NSData *data = [NSData dataWithContentsOfFile:@"/Users/Apple/Desktop/111.json"];