JSONSerialization — kelas iOS bawaan dari framework Foundation, yang dirancang untuk mengonversi JSON menjadi objek Foundation dan sebaliknya. API ini adalah mekanisme dasar bekerja dengan JSON di platform Apple tanpa menghubungkan pustaka pihak ketiga, mendukung parsing kamus, array, dan tipe primitif. Menurut Apple Developer, 2024, JSONSerialization mendukung bekerja dengan Data, aliran, dan opsi pembacaan untuk pemrosesan data JSON yang fleksibel.
Poin utama
JSONSerialization — adalah kelas dari framework Foundation, tersedia di iOS, macOS, tvOS, dan watchOS. Kelas ini menyediakan metode untuk mengonversi Data JSON menjadi objek Foundation (NSDictionary, NSArray, NSString, NSNumber) dan sebaliknya. Kelas ini muncul di iOS 5 dan hingga pengenalan Codable (Swift 4) tetap menjadi cara utama bekerja dengan JSON di platform Apple. Meskipun usianya sudah tua, JSONSerialization tetap diminati di proyek legacy pada Objective-C dan dalam skenario yang memerlukan pemrosesan JSON dinamis tanpa skema model tetap.
Meskipun munculnya Codable, JSONSerialization tetap relevan dalam beberapa skenario. Struktur JSON dinamis — ketika format respons berubah atau tidak diketahui sebelumnya — memerlukan akses ke kamus melalui kunci, yang lebih mudah dilakukan melalui JSONSerialization. Kelas ini juga digunakan dalam proyek Objective-C di mana Codable tidak tersedia, dan saat bekerja dengan aliran untuk parsing bertahap file JSON besar. Dalam pengujian dan maket, isValidJSONObject dan data(withJSONObject:options:) memungkinkan pembuatan fixture JSON dengan cepat tanpa menghubungkan pustaka pihak ketiga, yang mempercepat pengembangan dan pembuatan prototipe.
import Foundation
// Struktur dasar penggunaan 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("Kesalahan parsing JSON: \(error)")
}
JSONSerialization menyediakan empat metode utama untuk bekerja dengan JSON. Metode utama — jsonObject(with:options:), yang mengonversi Data menjadi objek Foundation. Metode data(withJSONObject:options:) melakukan serialisasi terbalik. isValidJSONObject(_:) memeriksa apakah objek dapat diserialisasi. writeJSONObject(_:to:options:error:) menulis JSON langsung ke aliran. Untuk membaca JSON dari InputStream terdapat metode jsonObject(with:options:), yang menerima aliran alih-alih Data, yang nyaman saat integrasi dengan permintaan jaringan yang mengembalikan data aliran.
Metode jsonObject menerima Data dan mengembalikan Any — biasanya NSDictionary atau NSArray. Untuk bekerja dengan aman, hasilnya dikonversi ke tipe yang diharapkan melalui konversi bersyarat. Metode data menerima objek Foundation dan mengembalikan Data dengan representasi JSON. Opsi .prettyPrinted menambahkan pemformatan dengan indentasi untuk keterbacaan.
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("Produk: \(name)")
}
}
}
// Serialisasi terbalik: objek -> JSON
let outputDict: [String: Any] = ["status": "ok", "count": 42]
if let outputData = try? JSONSerialization
.data(withJSONObject: outputDict,
options: .prettyPrinted) {
String(data: outputData, encoding: .utf8)
}
Parsing dasar kamus dengan tipe primitif — operasi paling umum dengan JSONSerialization. Setelah menerima Data melalui URLSession, pengembang memanggil jsonObject dan mengonversi hasilnya ke tipe yang diharapkan. Untuk array objek, digunakan konversi ke [[String: Any]], setelah itu setiap elemen diproses dalam satu lingkaran. Pendekatan ini fleksibel tetapi memerlukan manajemen tipe secara manual.
API nyata mengembalikan objek JSON bersarang yang kompleks dengan array, tanggal, dan bidang opsional. JSONSerialization memproses kedalaman bersarang apa pun dengan benar, tetapi pengembang harus secara mandiri mengonversi setiap level ke tipe yang diperlukan. Untuk menyederhanakan tugas ini, Apple merekomendasikan penggunaan Codable untuk data bertipe, dan JSONSerialization hanya untuk struktur dinamis.
// Parsing respons dari 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("Pengguna: \(name) (ID: \(userId))")
} catch let error as ParsingError {
print("Parsing gagal: \(error)")
} catch {
print("Kesalahan tak terduga: \(error)")
}
}
enum ParsingError: Error {
case missingField
case invalidType
}
JSONSerialization melempar kesalahan pada JSON tidak valid, ketidakcocokan tipe, atau melebihi kedalaman bersarang. Kesalahan termasuk dalam tipe CocoaError dan berisi kode dengan deskripsi masalah. Pengembang wajib menanganinya melalui konstruksi do-catch, jika tidak aplikasi akan berakhir secara mendadak. Kesalahan paling umum: NSPropertyListReadCorruptError (JSON salah) dan NSPropertyListReadUnknownError. Setiap jenis kesalahan memerlukan strategi penanganannya sendiri: pada format tidak valid, perlu meminta pengiriman ulang data, dan pada ketidakcocokan struktur — memperbarui model parsing.
JSON tidak valid — penyebab kegagalan paling umum: koma hilang, karakter berlebih, atau tanda kutip yang tidak di-escape merusak seluruh parsing. Jenis kesalahan kedua — ketidakcocokan dengan struktur yang diharapkan: misalnya, server mengembalikan array alih-alih kamus. JSONSerialization.fragmentsAllowed memungkinkan membaca JSON yang akarnya bukan kamus atau array, melainkan nilai primitif. Pengembang juga dapat mengalami kesalahan melebihi kedalaman bersarang ketika JSON mengandung terlalu banyak level hierarki.
JSONSerialization menyediakan beberapa opsi untuk mengonfigurasi parsing. .mutableContainers mengembalikan NSMutableDictionary dan NSMutableArray alih-alih versi yang tidak dapat diubah, yang berguna saat memodifikasi data setelah parsing. .mutableLeaves membuat nilai teks dapat diubah. .fragmentsAllowed mengizinkan JSON yang akarnya bukan objek atau array, melainkan string atau angka — nyaman untuk respons API sederhana. Opsi .withoutEscapingSlashes dan .sortedKeys tersedia untuk metode data(withJSONObject:options:), mengontrol pemformatan JSON yang diserialisasi. Opsi dikirimkan melalui mask bit, yang memungkinkan menggabungkan beberapa nilai melalui operator | untuk konfigurasi parsing yang fleksibel.
// Penanganan berbagai jenis kesalahan
func safeParse(jsonData: Data) {
do {
let object = try JSONSerialization
.jsonObject(with: jsonData,
options: .fragmentsAllowed)
if let dictionary = object as? [String: Any] {
print("Kamus dengan \(dictionary.count) kunci")
} else if let array = object as? [Any] {
print("Array dengan \(array.count) item")
}
} catch CocoaError.propertyListReadCorrupt {
print("Data JSON rusak")
} catch let error as CocoaError {
print("Kesalahan Cocoa: \(error)")
} catch {
print("Kesalahan tidak dikenal: \(error)")
}
}
// Pemeriksaan validitas objek sebelum serialisasi
let testObject: [String: Any] = ["key": "value", "nested": ["a": 1]]
if JSONSerialization.isValidJSONObject(testObject) {
print("Objek JSON valid")
}
Kinerja JSONSerialization dipengaruhi oleh ukuran data dan frekuensi panggilan. Pada parsing satu kali dari respons server kecil, perbedaannya tidak terlihat, tetapi saat memproses puluhan megabyte JSON atau panggilan sering dalam loop, perlu mempertimbangkan overhead konversi tipe. JSONSerialization bekerja secara sinkron di thread saat ini, oleh karena itu untuk dokumen besar disarankan untuk memindahkan parsing ke antrian latar belakang melalui DispatchQueue.global(). Alternatifnya, InputStream dapat digunakan untuk pemrosesan aliran tanpa memuat seluruh file ke memori, yang sangat penting untuk aplikasi dengan sumber daya terbatas. Untuk menulis JSON ke file atau aliran jaringan, metode writeJSONObject(_:to:options:error:) memungkinkan pengarahan data yang diserialisasi langsung ke OutputStream tanpa membuat objek Data perantara, yang mengurangi konsumsi memori saat bekerja dengan dokumen besar.
Pertanyaan yang sering diajukan
JSONSerialization — adalah kelas Foundation untuk mengonversi Data JSON menjadi objek Foundation (NSDictionary, NSArray) dan sebaliknya. Ini bekerja di iOS, macOS, tvOS, dan watchOS tanpa menghubungkan pustaka tambahan.
Codable — adalah protokol Swift untuk serialisasi bertipe otomatis yang dikompilasi menjadi kode yang aman tipe. JSONSerialization bekerja dengan tipe dinamis Any dan memerlukan konversi manual. Codable lebih disukai untuk proyek baru, JSONSerialization — untuk Objective-C dan data dinamis.
Gunakan konstruksi do-catch saat memanggil jsonObject. Kesalahan JSONSerialization termasuk dalam CocoaError. Untuk debugging, periksa NSPropertyListReadCorruptError yang menunjukkan format data JSON tidak valid.
Ya, JSONSerialization mendukung kedalaman bersarang kamus dan array apa pun. Semua objek bersarang dikonversi ke tipe Foundation yang sesuai (NSDictionary, NSArray, NSString, NSNumber), mempertahankan struktur JSON asli.
JSONSerialization cocok untuk struktur JSON dinamis, di proyek Objective-C, saat bekerja dengan aliran, dan untuk memvalidasi JSON melalui isValidJSONObject. Untuk struktur bertipe dengan skema yang diketahui, Codable lebih disukai.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga