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

0nd*_*re_ 22 json ios swift swift3

JSONSerialization经常在我的项目中使用.这是我的JSONSerialization代码示例:

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

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

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

我发现的选项:

NSJSONReadingMutableContainers:

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

NSJSONReadingMutableLeaves:

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

NSJSONReadingAllowFragments:

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

注2:我在以下网址找到了这些定义:https://developer.apple.com/reference/foundation/nsjsonreadingoptions

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

任何帮助赞赏.

谢谢.

vad*_*ian 35

前两个选项的简短回答:

在Swift中忽略它们!

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

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

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

在Objective-C和Swift中,如果您只是阅读 JSON,则根本不需要可变性.

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

这对空括号[]表示No options(optionsSwift 3+中的参数可以省略).

  • 谢谢.Apple应该在他们的文档的第一行写下这个: - / (5认同)

OOP*_*Per 19

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

 JSON array ->  NSArray
 JSON object -> NSDictionary
 JSON number -> NSNumber
 JSON string -> NSString
 JSON true   -> NSNumber
 JSON false  -> NSNumber
 JSON null   -> NSNull
Run Code Online (Sandbox Code Playgroud)

(您最好还查看JSON 的RFC.RFC-4627,RFC-7159)

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

mutableContainers(NSJSONReadingMutableContainers):

保证结果中包含的NSArrays或NSDictionarys必须是NSMutableArrays或NSMutableDictionarys.有人说在较旧的iOSs JSONSerialization(NSJSONSerialization)中没有指定就返回了可变对象mutableContainers,但是不建议依赖它,实际上你可以找到报告这些代码的人在iOS 10中不起作用.

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

mutableLeaves(NSJSONReadingMutableLeaves):

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

allowFragments(NSJSONReadingAllowFragments):

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

看到代码的差异:

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

[{"name": "aaa", "value": 123}, {"name": "bbb", "value": 456}]
Run Code Online (Sandbox Code Playgroud)

和代码:

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)
}
Run Code Online (Sandbox Code Playgroud)

而且data2:

-1
Run Code Online (Sandbox Code Playgroud)

和它的比较:

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)
}
Run Code Online (Sandbox Code Playgroud)


vai*_*hav 5

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

Options: []也可以修改为:

  • NSJSONWritingOptions:用于写入JSON数据之类的。

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

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