JSON
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
JSON简史
JSON的诞生原因是因为XML整合到HTML中各个浏览器实现的细节不尽相同,所以道格拉斯·克罗克福特(Douglas Crockford) 和 奇普·莫宁斯达(Chip Morningstar)一起从JS的数据类型中提取了一个子集,作为新的数据交换格式,因为主流的浏览器使用了通用的JavaScript引擎组件,所以在解析这种新数据格式时就不存在兼容性问题,于是他们将这种数据格式命名为 “JavaScript Object Notation”,缩写为 JSON,由此JSON便诞生了!
JOSN的6种数据类型
-
- String:字符串,必须要用双引号引起来。例如 :
"[{\"y\":2019,\"m\":10,\"d\":2},{\"y\":2019,\"m\":10,\"d\":4}]"
-
- Number:数值,与JavaScript的number一致,整数(不使用小数点或指数计数法)最多为 15 位,小数的最大位数是 17。例如:
{ "age":30 }
-
- Object:JavaScript的对象形式,{ key:value }表示方式,可嵌套。例如:
{
"name":"runoob",
"alexa":10000,
"sites": {
"site1":"www.runoob.com",
"site2":"m.runoob.com",
"site3":"c.runoob.com"
}
-
- Array:数组,JavaScript的Array表示方式[ value ],可嵌套。例如:
数组可包含多个对象:
{
"sites": [{ "name":"菜鸟教程" , "url":"www.runoob.com" }, { "name":"google" , "url":"www.google.com" }, { "name":"微博" , "url":"www.weibo.com" }]
}
//单独的json数组
[ "Google", "Runoob", "Taobao" ]
-
- true/false:布尔类型,JavaScript的boolean类型。例如:
{ "flag":true }
-
- null:空值,JavaScript的null。例如:
{"myCount": null}
NSJSONSerialization - 用于SON与Foundation对象转换的对象
一个用于在JSON与等效的Foundation对象之间转换的对象。可以使用NSJSONSerialization类将JSON转换为Foundation对象,或将Foundation对象转换为JSON。
一个可以被转换成JSON的Foundation对象必须具有以下属性:
- 如果未设置NSJSONWritingFragmentsAllowed,那么顶层对象则需要是一个NSArray或NSDictionary。
- 所有对象都是NSString、NSNumber、NSArray、NSDictionary或NSNull的实例。
- 所有字典Key都是NSString的实例。
- 数字不是NaN或无穷大。
如果要适用其他规则,需要调用isValidJSONObject:方法确定给定对象是否可以转换为JSON数据后进行最终的尝试转换。
NSJSONSerialization常用函数
+ (BOOL)isValidJSONObject:(id)obj;
函数描述 :返回一个布尔值,该值指示是否可以将给定对象转换为JSON数据。
参数 :
obj : 要测试的对象。
返回值 : 如果obj可以转换成JSON数据,则为YES,否则为NO。
+ (nullable NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;
函数描述 :从Foundation对象返回JSON数据。如果obj不能生成有效的JSON,则抛出异常,此异常在分析之前引发,表示编程错误,而不是内部错误。在调用此方法之前使用isValidJSONObject:方法检查输入是否会生成有效的JSON。
参数 :
obj : 用来生成JSON数据的对象,必须非nil。
opt : 用于创建JSON数据的选项。
error :如果发生内部错误,则在返回时包含一个NSError对象,其中包含描述问题的代码NSPropertyListWriteInvalidError。
返回值 : obj的JSON数据,如果发生内部错误则为nil。结果数据用UTF-8编码。
- NSJSONWritingOptions枚举的用于创建JSON数据的选项如下:
typedef NS_OPTIONS(NSUInteger, NSJSONWritingOptions) {
//使用空格和缩进使输出更可读的写入选项。
//如果未设置此选项,则生成尽可能紧凑的JSON表示。
NSJSONWritingPrettyPrinted = (1UL << 0),
//按字典顺序排列键的写入选项。
NSJSONWritingSortedKeys API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)) = (1UL << 1),
//返回允许JSON字符串最外层既不是NSArray也不是NSDictionary,
//但必须是有效的JSON片段
NSJSONWritingFragmentsAllowed = (1UL << 2),
//不转义斜杠的JSON写入
NSJSONWritingWithoutEscapingSlashes API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) = (1UL << 3),
} API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
// 字典转json字符串方法
-(NSString *)convertToJsonData:(NSDictionary *)dict{
NSError *error;
//从基础对象返回JSON数据
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString;
if (!jsonData) {
NSLog(@"%@",error);
}else{
jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
}
NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
NSRange range = {0,jsonString.length};
//去掉字符串中的空格
[mutStr replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:range];
NSRange range2 = {0,mutStr.length};
//去掉字符串中的换行符
[mutStr replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:range2];
return mutStr;
}
+ (nullable id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;
函数描述 :从给定的JSON数据返回一个Foundation对象。数据必须是JSON规范中列出的5种受支持的编码之一:UTF-8、UTF-16LE、UTF-16BE、UTF-32LE、UTF-32BE。数据可能有也可能没有BOM。用于解析的最有效编码是UTF-8,因此,如果可以选择对传递给该方法的数据进行编码,请使用UTF-8。
参数 :
data : 一个包含JSON数据的数据对象。
opt : 用于读取JSON数据和创建基础对象的选项。
error : 如果发生错误,则在返回时包含一个NSError对象,该对象的代码为NSPropertyListReadCorruptError,用于描述问题。
返回值 : 数据中JSON数据转换的基础对象,如果发生错误,则为nil。
- NSJSONReadingOptions枚举的用于读取JSON数据和创建基础对象的选项如下:
typedef NS_OPTIONS(NSUInteger, NSJSONReadingOptions) {
//指定将数组和词典创建为可变对象。
NSJSONReadingMutableContainers = (1UL << 0),
//返回的JSON对象中字符串的值为NSMutableString。
NSJSONReadingMutableLeaves = (1UL << 1),
//解析时允许不是数组或字典作为顶级对象。
NSJSONReadingFragmentsAllowed = (1UL << 2),
//返回允许JSON字符串最外层既不是NSArray也不是NSDictionary,
//但必须是有效的JSON 片段.
NSJSONReadingAllowFragments API_DEPRECATED_WITH_REPLACEMENT("NSJSONReadingFragmentsAllowed", macos(10.7, API_TO_BE_DEPRECATED), ios(5.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED)) = NSJSONReadingFragmentsAllowed,
} API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
- (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString{
if (jsonString == nil) {
return nil;
}
//返回一个NSData对象,该对象包含使用给定编码编码的接收器的表示形式
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *err;
//从给定的JSON数据返回一个Foundation对象
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
options:NSJSONReadingMutableContainers
error:&err];
if(err)
{
NSLog(@"json解析失败:%@",err);
return nil;
}
return dic;
}