JSONSerialization选项有什么作用以及它们如何更改jsonResult?

时间:2016-10-15 10:24:18

标签: ios json swift swift3

我在项目中经常使用JSONSerialization。 以下是我的JSONSerialization代码示例:

let json = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any] 

注意:目的缺少选项,我通常在项目中使用它们。

我的问题是我不确定这些options: []做了什么?

我发现了有关选项的内容:

NSJSONReadingMutableContainers:

  

指定将数组和字典创建为可变对象。

NSJSONReadingMutableLeaves:

  

指定将JSON对象图中的叶字符串创建为   NSMutableString的实例。

NSJSONReadingAllowFragments:

  

指定解析器应该允许不是的顶级对象   NSArray或NSDictionary的一个实例。

Note2 :我在https://developer.apple.com/reference/foundation/nsjsonreadingoptions

上找到了这些定义

我的问题是: 有人可以解释我这些选项之间的差异,我应该使用它们,如果你能告诉我这些选项的一些代码示例,它将是完美的:)。

任何帮助表示感谢。

感谢。

3 个答案:

答案 0 :(得分:31)

前两个选项的简短回答:

在Swift中忽略它们

在Swift中,您可以使用var关键字使对象变为可变。

另一方面,在Objective-C中你需要

  • NSJSONReadingMutableContainers使嵌套集合类型可变NSArrayNSMutableArrayNSDictionaryNSMutableDictionary
  • NSJSONReadingMutableLeaves使值字符串变为可变→NSMutableString

如果您只是 正在阅读 ,那么在Objective-C和Swift中,您根本不需要可变性。

如果收到的JSON的根对象数组且字典,则第三个选项NSJSONReadingAllowFragments很重要。
如果数组或字典,您也可以省略该选项。

这对空括号[]代表No options(Swift 3 +中可省略options参数。)

答案 1 :(得分:18)

您最好知道如何将JSON值导入iOS世界:

 JSON array ->  NSArray
 JSON object -> NSDictionary
 JSON number -> NSNumber
 JSON string -> NSString
 JSON true   -> NSNumber
 JSON false  -> NSNumber
 JSON null   -> NSNull

(您最好还查看JSON的RFC。RFC-4627RFC-7159

然后再次重新检查所有选项:

mutableContainersNSJSONReadingMutableContainers

保证结果中包含的NSArrayNSDictionary必须为NSMutableArrayNSMutableDictionary s。有人说在较旧的iOS JSONSerializationNSJSONSerialization)中没有指定mutableContainers就返回了可变对象,但是根据它不建议,实际上你可以找到报告此类代码的人在iOS中不起作用10。

在Swift中,可变性由varlet表示,因此您无需在Swifty代码中使用此选项。只有在将反序列化结果的某些部分转换为NSMutableArrayNSMutableDictionary时才需要。我强烈建议以更加Swifty的方式重写这些代码。

mutableLeavesNSJSONReadingMutableLeaves

保证结果中包含的NSString必须为NSMutableString s。即使在旧的Objective-C代码中也很少使用,请忽略它。

allowFragmentsNSJSONReadingAllowFragments

在旧的RFC(RFC-4627)中,只有数组和对象作为JSON的最外层组件才有效。如果您希望来自服务器的数组或对象(NSDictionary),则不指定此选项将帮助您更快地从服务器中找到无效的返回值。

看到代码的差异:

假设data1是以下JSON的有效UTF-8表示形式:

[{"name": "aaa", "value": 123}, {"name": "bbb", "value": 456}]

代码:

do {
    let result = try JSONSerialization.jsonObject(with: data1)
    let resultArray = result as! NSMutableArray //->This may cause your app crash
    //->Could not cast value of type '__NSArrayI' (0x105e79c08) to 'NSMutableArray' (0x105e79cd0).
    print(resultArray)
} catch {
    print(error)
}

do {
    let result = try JSONSerialization.jsonObject(with: data1, options: [.mutableContainers])
    let resultArray = result as! NSMutableArray //->This should always work
    print(resultArray) //->shows output...
} catch {
    print(error)
}

data2

-1

和它的比较:

do {
    let result = try JSONSerialization.jsonObject(with: data2)
    print(result)
} catch {
    print(error) //->Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
}

do {
    let result = try JSONSerialization.jsonObject(with: data2, options: [.allowFragments])
    print(result) //-> -1
} catch {
    print(error)
}

答案 2 :(得分:4)

Options: []是一个空数组,不返回任何内容。

Options: []也可以修改:

  • NSJSONWritingOptions:用于编写JSON数据,如。

    • NSJSONWritingOptions.NSJSONWritingPrettyPrinted:指定应使用设计的空格生成JSON数据,以使输出更具可读性。如果未设置此选项,则会生成最紧凑的可能JSON表示。
  • NSJSONReadingOptions:在从JSON数据创建Foundation对象时使用。

    • NSJSONReadingOptions.MutableContainers:指定将数组和字典创建为可变对象。
    • .mutableLeaves:指定将JSON对象图中的叶字符串创建为NSMutableString的实例。
    • .allowFragments:指定解析器应允许不是NSArray或NSDictionary实例的顶级对象。