Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 513 Vote(s) - 3.49 Average
  • 1
  • 2
  • 3
  • 4
  • 5
What do JSONSerialization options do and how do they change jsonResult?

#1
I am using `JSONSerialization` quite often in my project.
Here is an example of my `JSONSerialization` code:

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

**Note**: Options are missing for purpose and I normally have them in my project.

My problem is that I am not pretty sure what do these `options: []` do?

**What I have found about options:**

**NSJSONReadingMutableContainers:**

> Specifies that arrays and dictionaries are created as mutable objects.

**NSJSONReadingMutableLeaves:**

> Specifies that leaf strings in the JSON object graph are created as
> instances of NSMutableString.

**NSJSONReadingAllowFragments:**

> Specifies that the parser should allow top-level objects that are not
> an instance of NSArray or NSDictionary.

**Note2**: I found those definitions on :

[To see links please register here]


**My question is**:
Can someone please explain me differences between those options , what should I use them for and if you could show me some code example of those options it would be perfect :).

Any help appreciated.

Thanks.
Reply

#2
Short answer for the first two options:

**Ignore them in Swift!**

In Swift you can make objects mutable just with the `var` keyword.

In Objective-C on the other hand you need

- `NSJSONReadingMutableContainers` to make the nested collection types mutable `NSArray` → `NSMutableArray` and `NSDictionary` → `NSMutableDictionary`.
- `NSJSONReadingMutableLeaves` to make the value strings mutable → `NSMutableString`.

In both Objective-C and Swift if you are only ***reading*** the JSON you don't need mutability at all.

The third option `NSJSONReadingAllowFragments` is important if the root object of the received JSON is **not** an array and **not** a dictionary.
If it **is** an array or dictionary you can omit that option, too.

The pair of empty brackets `[]` represents `No options` (the `options` parameter can be omitted in Swift 3+).
Reply

#3
You'd better know how JSON values are imported into iOS world:

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

(You'd better also check the RFCs of JSON. [RFC-4627][1], [RFC-7159][2])

Then re-check the all options again:

**`mutableContainers` (`NSJSONReadingMutableContainers`)**:

Guarantees the `NSArray`s or `NSDictionary`s contained in the result must be `NSMutableArray`s or `NSMutableDictionary`s. Someone says in older iOSs `JSONSerialization` (`NSJSONSerialization`) returned mutable objects without specifying `mutableContainers`, but depending on it is not recommended, and actually you can find someones reporting such code does not work in iOS 10.

In Swift, mutability is represented by `var` and `let`, so you have no need to use this option in Swifty codes. Only needed when you cast some parts of the deserialized result to `NSMutableArray` or `NSMutableDictionary`. I strongly recommend to rewrite such codes in a more Swifty manner.

**`mutableLeaves` (`NSJSONReadingMutableLeaves`)**:

Guarantees the `NSString`s contained in the result must be `NSMutableString`s. Rarely used even in old Objective-C codes, ignore it.

**`allowFragments` (`NSJSONReadingAllowFragments`)**:

In old RFC (RFC-4627), only array and object were valid as the outermost component of JSON. If you expect array or object (`NSDictionary`) from the server, NOT specifying this option would help you to find the invalid returned value from the server a little bit sooner.

Seeing the difference in codes:
---

Assume `data1` is a valid UTF-8 representation of the following JSON:

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

And the code:

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)
}

And `data2`:

-1

And the comparison for it:

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)
}

[1]:

[To see links please register here]

[2]:

[To see links please register here]


Reply

#4
`Options: []` is an empty array returns nothing.

Whereas `Options: []` can also be amend with:

- **NSJSONWritingOptions:** for writing JSON data like.
+ `NSJSONWritingOptions.NSJSONWritingPrettyPrinted:` Specifies that the JSON data should be generated with whitespace designed to make the output more readable. If this option is not set, the most compact possible JSON representation is generated.


- **NSJSONReadingOptions:** used when creating Foundation objects from JSON data.
+ `NSJSONReadingOptions.MutableContainers:` Specifies that arrays and dictionaries are created as mutable objects.
+ `.mutableLeaves:` Specifies that leaf strings in the JSON object graph are created as instances of NSMutableString.
+ `.allowFragments:` Specifies that the parser should allow top-level objects that are not an instance of NSArray or NSDictionary.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through