Что делают параметры 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.