Что делают параметры JSONSerialization и как они меняют jsonResult?

Я использую JSONSerialization довольно часто в моем проекте. Вот пример моего кода JSONSerialization:

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

Примечание. Параметры отсутствуют для цели, и я обычно их использую в своем проекте.

Моя проблема в том, что я не совсем уверен, что делают эти options: []?

Что я нашел о настройках:

NSJSONReadingMutableContainers:

Указывает, что массивы и словари создаются как изменяемые объекты.

NSJSONReadingMutableLeaves:

Указывает, что строковые строки в графе объектов JSON создаются как экземпляры NSMutableString.

NSJSONReadingAllowFragments:

Указывает, что анализатор должен разрешать объекты верхнего уровня, которые не являются экземпляр NSArray или NSDictionary.

Примечание2. Я нашел эти определения: https://developer.apple.com/reference/foundation/nsjsonreadingoptions

Мой вопрос: Может кто-то, пожалуйста, объясните мне различия между этими параметрами, для чего я должен их использовать, и если бы вы могли показать мне пример кода этих вариантов, это было бы прекрасно:).

Любая помощь была оценена.

Спасибо.

Ответ 1

Короткий ответ для первых двух вариантов:

Игнорировать их в Swift!

В Swift вы можете создавать объекты, изменяемые с помощью ключевого слова var.

В Objective-C, с другой стороны, вам нужны параметры для создания типов коллекций NSArray/NSDictionary mutable → NSMutableArray/NSMutableDictionary с опцией NSJSONReadingMutableContainers или строками значений → NSMutableString с NSJSONReadingMutableLeaves.

В Objective-C и Swift, если вы только читаете JSON, вам совсем не нужна изменчивость.

NSJSONReadingAllowFragments важен, если корневой объект полученного JSON не массив или словарь. Если это есть массив или словарь, вы также можете опустить этот параметр.

Пара пустых скобок [] представляет No options (options может быть опущена в Swift 3).

Ответ 2

Вам лучше знать, как значения JSON импортируются в мир iOS:

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

(Вам лучше также проверить RFC JSON. RFC-4627, RFC-7159)

Затем снова проверьте все параметры:

mutableContainers (NSJSONReadingMutableContainers):

Гарантирует, что NSArray или NSDictionary, содержащиеся в результате, должны быть NSMutableArray или NSMutableDictionary s. Кто-то говорит, что в более старых iOS JSONSerialization (NSJSONSerialization) возвращаемые изменяемые объекты не указаны mutableContainers, но в зависимости от этого не рекомендуется, и на самом деле вы можете найти, что кто-то сообщает, что такой код не работает в iOS 10.

В Swift изменчивость представлена ​​ var и let, поэтому вам не нужно использовать эту опцию в кодах Swifty. Необходимо только, когда вы произвели некоторые части десериализованного результата на NSMutableArray или NSMutableDictionary. Я настоятельно рекомендую переписать такие коды более осторожно.

mutableLeaves (NSJSONReadingMutableLeaves):

Гарантирует, что NSString, содержащийся в результате, должен быть NSMutableString s. Редко используется даже в старых Objective-C кодах, игнорируйте его.

allowFragments (NSJSONReadingAllowFragments):

В старой RFC (RFC-4627) только массив и объект были действительными как самый внешний компонент JSON. Если вы ожидаете от сервера массив или объект (NSDictionary), НЕ указывая этот параметр, это поможет вам найти неверное возвращаемое значение с сервера немного раньше.

Видя разницу в кодах:

Предположим, что data1 является допустимым представлением UTF-8 следующего JSON:

[{"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)
}

Ответ 3

Options: [] - пустой массив, ничего не возвращает.

В то время как Options: [] также может быть изменен с помощью:

  • NSJSONWritingOptions: для записи данных JSON, например.

    • NSJSONWritingOptions.NSJSONWritingPrettyPrinted: Указывает, что данные JSON должны быть сгенерированы с помощью пробелов, предназначенных для того, чтобы сделать вывод более читаемым. Если этот параметр не установлен, генерируется максимально компактное представление JSON.
  • NSJSONReadingOptions: используется при создании объектов Foundation из данных JSON.

    • NSJSONReadingOptions.MutableContainers: Указывает, что массивы и словари создаются как изменяемые объекты.
    • .mutableLeaves: Указывает, что строковые строки в графе объектов JSON создаются как экземпляры NSMutableString.
    • .allowFragments: Указывает, что анализатор должен разрешать объекты верхнего уровня, которые не являются экземпляром NSArray или NSDictionary.