Objective-C的JSON

4,580 阅读5分钟

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种数据类型

    1. String:字符串,必须要用双引号引起来。例如 :
"[{\"y\":2019,\"m\":10,\"d\":2},{\"y\":2019,\"m\":10,\"d\":4}]"
    1. Number:数值,与JavaScript的number一致,整数(不使用小数点或指数计数法)最多为 15 位,小数的最大位数是 17。例如:
{ "age":30 }
    1. Object:JavaScript的对象形式,{ key:value }表示方式,可嵌套。例如:
{
   "name":"runoob",
   "alexa":10000,
   "sites": {
       "site1":"www.runoob.com",
       "site2":"m.runoob.com",
       "site3":"c.runoob.com"
   }
    1. 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" ]
    1. true/false:布尔类型,JavaScript的boolean类型。例如:
{ "flag":true }
    1. 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字符串方法\color{red}{例如 : 字典转json字符串方法}

// 字典转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));

例如:JSON字符串转化为字典\color{red}{例如 : JSON字符串转化为字典}

- (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;
}