JSONSerialization — уграђена iOS класа из оквира Foundation, намењена за претварање JSON-а у Foundation објекте и обрнуто. Овај API је основни механизам рада са JSON-ом на Apple платформама без повезивања спољних библиотека, подржавајући парсирање речника, низова и примитивних типова. Према Apple Developer, 2024, JSONSerialization подржава рад са Data, токовима и опцијама читања за флексибилну обраду JSON података.
Главне тачке
JSONSerialization — је класа из оквира Foundation, доступна на iOS, macOS, tvOS и watchOS. Она пружа методе за претварање JSON Data у Foundation објекте (NSDictionary, NSArray, NSString, NSNumber) и обрнуто. Класа се појавила у iOS 5 и до увођења Codable (Swift 4) остала главни начин рада са JSON-ом на Apple платформама. Упркос старости, JSONSerialization остаје тражен у legacy пројектима на Objective-C и у сценаријима где је потребна динамичка обрада JSON-а без фиксне шеме модела.
Упркос појави Codable-а, JSONSerialization остаје актуелан у неколико сценарија. Динамичка структура JSON-а — када се формат одговора мења или је унапред непознат — захтева приступ речницима преко кључева, што је једноставније урадити преко JSONSerialization-а. Класа се такође примењује у Objective-C пројектима где Codable није доступан, и при раду са токовима за етапно парсирање великих JSON датотека. У тестовима и макетама, isValidJSONObject и data(withJSONObject:options:) омогућавају брзо генерисање JSON фикстура без повезивања спољних библиотека, што убрзава развој и прототиповање.
import Foundation
// Основна структура коришћења JSONSerialization-а
let jsonString = """
{
"id": 1,
"name": "John Doe",
"email": "john@example.com"
}
"""
guard let jsonData = jsonString.data(using: .utf8) else {
return
}
do {
let json = try JSONSerialization
.jsonObject(with: jsonData,
options: .mutableContainers)
print(json)
} catch {
print("Грешка парсирања JSON-а: \(error)")
}
JSONSerialization пружа четири главне методе за рад са JSON-ом. Главна метода — jsonObject(with:options:), која претвара Data у Foundation објекте. Метода data(withJSONObject:options:) врши обрнуту серијализацију. isValidJSONObject(_:) проверава да ли објекат може бити серијализован. writeJSONObject(_:to:options:error:) уписује JSON директно у ток. За читање JSON-а из InputStream-а постоји метода jsonObject(with:options:), која прима ток уместо Data, што је згодно при интеграцији са мрежним захтевима који враћају податке у току.
Метода jsonObject прима Data и враћа Any — обично NSDictionary или NSArray. За безбедан рад резултат се претвара у очекивани тип кроз условно превођење. Метода data прима Foundation објекат и враћа Data са JSON приказом. Опција .prettyPrinted додаје форматирање са увлакама за читљивост.
let jsonString = """
{
"products": [
{"id": 1, "name": "iPhone", "price": 999},
{"id": 2, "name": "iPad", "price": 799}
]
}
"""
let data = Data(jsonString.utf8)
if let json = try? JSONSerialization
.jsonObject(with: data) as? [String: Any],
let products = json["products"] as? [[String: Any]] {
for product in products {
if let name = product["name"] as? String {
print("Производ: \(name)")
}
}
}
// Обрнута серијализација: објекат -> JSON
let outputDict: [String: Any] = ["status": "ok", "count": 42]
if let outputData = try? JSONSerialization
.data(withJSONObject: outputDict,
options: .prettyPrinted) {
String(data: outputData, encoding: .utf8)
}
Основно парсирање речника са примитивним типовима — најчешћа операција са JSONSerialization-ом. Након пријема Data путем URLSession-а, програмер позива jsonObject и претвара резултат у очекивани тип. За низове објеката користи се претварање у [[String: Any]], након чега се сваки елемент обрађује у петљи. Овај приступ је флексибилан, али захтева ручно управљање типовима.
Прави API-ји враћају сложене угњеждене JSON објекте са низовима, датумима и опционим пољима. JSONSerialization исправно обрађује било коју дубину угњеждености, али програмер мора самостално да претвара сваки ниво у потребан тип. Да би поједноставио овај задатак, Apple препоручује коришћење Codable-а за типизиране податке, а JSONSerialization — само за динамичке структуре.
// Парсирање одговора са API-ја
func parseUserResponse(data: Data) {
do {
guard let json = try JSONSerialization
.jsonObject(with: data) as? [String: Any]
else { return }
guard let userId = json["id"] as? Int,
let name = json["name"] as? String
else {
throw ParsingError.missingField
}
print("Корисник: \(name) (ID: \(userId))")
} catch let error as ParsingError {
print("Парсирање није успело: \(error)")
} catch {
print("Неочекивана грешка: \(error)")
}
}
enum ParsingError: Error {
case missingField
case invalidType
}
JSONSerialization баца грешке при неважећем JSON-у, неусклађености типова или прекорачењу дубине угњеждености. Грешке припадају типу CocoaError и садрже код са описом проблема. Програмер је дужан да их обрађује кроз конструкцију do-catch, иначе ће се апликација нагло завршити. Најчешће грешке: NSPropertyListReadCorruptError (неисправан JSON) и NSPropertyListReadUnknownError. Сваки тип грешке захтева сопствену стратегију обраде: при неисправном формату треба затражити поновно слање података, а при неусклађености структуре — ажурирати модел парсирања.
Неисправан JSON — најчешћи узрок отказа: пропуштени зарез, вишак карактера или неекранизовани наводници ломе цело парсирање. Други тип грешака — неусклађеност са очекиваном структуром: на пример, сервер је вратио низ уместо речника. JSONSerialization.fragmentsAllowed омогућава читање JSON-а чији корен није речник или низ, већ примитивна вредност. Програмер се такође може сусрести са грешком прекорачења дубине угњеждености када JSON садржи превише нивоа хијерархије.
JSONSerialization пружа неколико опција за конфигурисање парсирања. .mutableContainers враћа NSMutableDictionary и NSMutableArray уместо непроменљивих верзија, што је корисно при модификацији података након парсирања. .mutableLeaves чини променљивим текстуалне вредности. .fragmentsAllowed дозвољава JSON чији корен није објекат или низ, већ текст или број — згодно за једноставне API одговоре. Опције .withoutEscapingSlashes и .sortedKeys доступне су за метод data(withJSONObject:options:), управљајући форматирањем серијализованог JSON-а. Опције се прослеђују битском маском, што омогућава комбиновање више вредности кроз оператор | за флексибилну конфигурацију парсирања.
// Обрада различитих типова грешака
func safeParse(jsonData: Data) {
do {
let object = try JSONSerialization
.jsonObject(with: jsonData,
options: .fragmentsAllowed)
if let dictionary = object as? [String: Any] {
print("Речник са \(dictionary.count) кључева")
} else if let array = object as? [Any] {
print("Низ са \(array.count) ставки")
}
} catch CocoaError.propertyListReadCorrupt {
print("Оштећени JSON подаци")
} catch let error as CocoaError {
print("Cocoa грешка: \(error)")
} catch {
print("Непозната грешка: \(error)")
}
}
// Провера исправности објекта пре серијализације
let testObject: [String: Any] = ["key": "value", "nested": ["a": 1]]
if JSONSerialization.isValidJSONObject(testObject) {
print("Исправан JSON објекат")
}
На перформансе JSONSerialization-а утиче величина података и учесталост позива. При једнократном парсирању малог серверског одговора разлика је неприметна, али при обради десетина мегабајта JSON-а или честим позивима у петљама треба узети у обзир трошкове превођења типова. JSONSerialization ради синхроно у тренутној нити, због чега се за велике документе препоручује избацивање парсирања у позадински ред кроз DispatchQueue.global(). Алтернативно се може користити InputStream за токовну обраду без учитавања целе датотеке у меморију, што је критично за апликације са ограниченим ресурсима. За упис JSON-а у датотеку или мрежни ток, метода writeJSONObject(_:to:options:error:) омогућава директно усмеравање серијализованих података у OutputStream без стварања посредног Data објекта, што смањује потрошњу меморије при раду са великим документима.
Често постављана питања
JSONSerialization — је Foundation класа за претварање JSON Data у Foundation објекте (NSDictionary, NSArray) и обрнуто. Ради на iOS, macOS, tvOS и watchOS без повезивања додатних библиотека.
Codable — је Swift протокол за аутоматску типизирану серијализацију који се компајлира у типно безбедан код. JSONSerialization ради са динамичким типовима Any и захтева ручно превођење. Codable је пожељнији за нове пројекте, JSONSerialization — за Objective-C и динамичке податке.
Користите конструкцију do-catch при позиву jsonObject-а. Грешке JSONSerialization-а припадају CocoaError-у. За дебаговање проверите NSPropertyListReadCorruptError који указује на неисправан формат JSON података.
Да, JSONSerialization подржава било коју дубину угњеждености речника и низова. Сви угњеждени објекти се претварају у одговарајуће Foundation типове (NSDictionary, NSArray, NSString, NSNumber), чувајући оригиналну JSON структуру.
JSONSerialization је прикладан при динамичкој структури JSON-а, у Objective-C пројектима, при раду са токовима и за проверу исправности JSON-а кроз isValidJSONObject. За типизиране структуре са познатом шемом пожељнији је Codable.
Резиме
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође