JSONSerialization — JSON'u Foundation nesnelerine dönüştürmek ve geri almak için tasarlanmış, Foundation çerçevesinin yerleşik bir iOS sınıfıdır. Bu API, üçüncü taraf kütüphaneler olmadan Apple platformlarında JSON ile çalışmanın temel mekanizmasıdır ve sözlüklerin, dizilerin ve ilkel türlerin ayrıştırılmasını destekler. Apple Developer, 2024'e göre, JSONSerialization esnek JSON veri işleme için Data, akışlar ve okuma seçenekleriyle çalışmayı destekler.
Önemli Noktalar
JSONSerialization iOS, macOS, tvOS ve watchOS'ta kullanılabilen Foundation çerçevesinin bir sınıfıdır. JSON Data'yı Foundation nesnelerine (NSDictionary, NSArray, NSString, NSNumber) dönüştürmek ve geri almak için yöntemler sağlar. Sınıf iOS 5'te ortaya çıktı ve Codable (Swift 4) tanıtılana kadar Apple platformlarında JSON ile çalışmanın birincil yolu olarak kaldı. Yaşına rağmen JSONSerialization, eski Objective-C projelerinde ve sabit bir model şablonu olmadan dinamik JSON işleme gerektiren senaryolarda geçerliliğini korumaktadır.
Codable'ın gelişine rağmen JSONSerialization birkaç senaryoda geçerliliğini korur. Dinamik JSON yapısı — yanıt biçimi değiştiğinde veya önceden bilinmediğinde — sözlüklere anahtarlarla erişmeyi gerektirir, bu da JSONSerialization aracılığıyla yapılması daha kolaydır. Sınıf ayrıca Codable'ın kullanılamadığı Objective-C projelerinde ve büyük JSON dosyalarının aşamalı ayrıştırılması için akışlarla çalışırken kullanılır. Testlerde ve maketlerde isValidJSONObject ve data(withJSONObject:options:), üçüncü taraf kütüphaneler olmadan hızlı bir şekilde JSON fikstürleri oluşturmayı sağlayarak geliştirme ve prototip oluşturmayı hızlandırır.
import Foundation
// JSONSerialization kullanımının temel yapısı
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 ayrıştırma hatası: \(error)")
}
JSONSerialization JSON ile çalışmak için dört ana yöntem sağlar. Ana yöntem jsonObject(with:options:)'dır ve Data'yı Foundation nesnelerine dönüştürür. data(withJSONObject:options:) yöntemi ters serileştirme yapar. isValidJSONObject(_:) bir nesnenin serileştirilip serileştirilemeyeceğini kontrol eder. writeJSONObject(_:to:options:error:) JSON'u doğrudan bir akışa yazar. InputStream'tan JSON okumak için, Data yerine akış kabul eden jsonObject(with:options:) yöntemi bulunur ve bu, akış verisi döndüren ağ istekleriyle entegre olurken kullanışlıdır.
jsonObject yöntemi Data kabul eder ve Any — genellikle NSDictionary veya NSArray — döndürür. Güvenli kullanım için sonuç, koşullu dönüştürme yoluyla beklenen türe dönüştürülür. data yöntemi bir Foundation nesnesi kabul eder ve JSON temsiliyle Data döndürür. .prettyPrinted seçeneği, okunabilirlik için girintili biçimlendirme ekler.
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("Ürün: \(name)")
}
}
}
// Ters serileştirme: nesne -> JSON
let outputDict: [String: Any] = ["status": "ok", "count": 42]
if let outputData = try? JSONSerialization
.data(withJSONObject: outputDict,
options: .prettyPrinted) {
String(data: outputData, encoding: .utf8)
}
Temel ayrıştırma ilkel türlerle bir sözlüğün, JSONSerialization ile en yaygın işlemdir. URLSession aracılığıyla Data alındıktan sonra geliştirici jsonObject'i çağırır ve sonucu beklenen türe dönüştürür. Nesne dizileri için [[String: Any]]'e dönüştürme kullanılır ve ardından her öğe bir döngüde işlenir. Bu yaklaşım esnektir ancak manuel tür yönetimi gerektirir.
Gerçek API'ler, diziler, tarihler ve isteğe bağlı alanlarla karmaşık iç içe JSON nesneleri döndürür. JSONSerialization herhangi bir iç içe derinliğini doğru şekilde işler, ancak geliştiricinin her seviyeyi bağımsız olarak gerekli türe dönüştürmesi gerekir. Bu görevi basitleştirmek için Apple, tür belirtilmiş veriler için Codable kullanılmasını ve JSONSerialization'ın yalnızca dinamik yapılar için kullanılmasını önerir.
// API yanıtını ayrıştırma
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("Kullanıcı: \(name) (ID: \(userId))")
} catch let error as ParsingError {
print("Ayrıştırma başarısız: \(error)")
} catch {
print("Beklenmeyen hata: \(error)")
}
}
enum ParsingError: Error {
case missingField
case invalidType
}
JSONSerialization geçersiz JSON, tür uyuşmazlığı veya iç içe derinliğinin aşılması durumunda hata fırlatır. Hatalar CocoaError türüne aittir ve sorunu tanımlayan bir kod içerir. Geliştirici bunları do-catch yapısıyla ele almalıdır, aksi takdirde uygulama çökecektir. En yaygın hatalar şunlardır: NSPropertyListReadCorruptError (geçersiz JSON) ve NSPropertyListReadUnknownError. Her hata türü kendi ele alma stratejisini gerektirir: geçersiz biçim için verilerin yeniden gönderilmesini talep edin ve yapı uyuşmazlığı için ayrıştırma modelini güncelleyin.
Geçersiz JSON — başarısızlığın en yaygın nedeni: eksik virgül, fazladan karakter veya kaçış dizisi eklenmemiş tırnak işaretinin tüm ayrıştırmayı bozmasıdır. İkinci hata türü, beklenen yapıyla uyuşmazlıktır: örneğin, sunucunun sözlük yerine bir dizi döndürmesi. JSONSerialization.fragmentsAllowed, kökü sözlük veya dizi değil de ilkel bir değer olan JSON'u okumaya izin verir. Geliştirici ayrıca JSON çok fazla hiyerarşi düzeyi içerdiğinde iç içe derinlik aşımı hatasıyla karşılaşabilir.
JSONSerialization, ayrıştırmayı yapılandırmak için çeşitli seçenekler sunar. .mutableContainers değişmez sürümler yerine NSMutableDictionary ve NSMutableArray döndürür; bu, ayrıştırmadan sonra verileri değiştirirken kullanışlıdır. .mutableLeaves dize değerlerini değiştirilebilir yapar. .fragmentsAllowed, kökü bir nesne veya dizi değil de bir dize veya sayı olan JSON'a izin verir — basit API yanıtları için kullanışlıdır. .withoutEscapingSlashes ve .sortedKeys seçenekleri data(withJSONObject:options:) yöntemi için kullanılabilir ve serileştirilmiş JSON'ın biçimlendirmesini kontrol eder. Seçenekler, esnek ayrıştırma yapılandırması için | operatörü aracılığıyla birden çok değerin birleştirilmesine izin veren bir bit maskesi olarak iletilir.
// Çeşitli hata türlerini ele alma
func safeParse(jsonData: Data) {
do {
let object = try JSONSerialization
.jsonObject(with: jsonData,
options: .fragmentsAllowed)
if let dictionary = object as? [String: Any] {
print("\(dictionary.count) anahtarlı sözlük")
} else if let array = object as? [Any] {
print("\(array.count) öğeli dizi")
}
} catch CocoaError.propertyListReadCorrupt {
print("Bozuk JSON verisi")
} catch let error as CocoaError {
print("Cocoa hatası: \(error)")
} catch {
print("Bilinmeyen hata: \(error)")
}
}
// Serileştirmeden önce nesne geçerliliğini kontrol etme
let testObject: [String: Any] = ["key": "value", "nested": ["a": 1]]
if JSONSerialization.isValidJSONObject(testObject) {
print("Geçerli JSON nesnesi")
}
JSONSerialization'ın performansı veri boyutuna ve çağrı sıklığına bağlıdır. Küçük bir sunucu yanıtının tek bir ayrıştırılmasında fark önemsizdir, ancak onlarca megabayt JSON veya döngülerde sık çağrılar işlenirken tür dönüştürmenin ek yükü dikkate alınmalıdır. JSONSerialization geçerli iş parçacığında eşzamanlı olarak çalışır, bu nedenle büyük belgeler için ayrıştırmanın DispatchQueue.global() aracılığıyla bir arka plan kuyruğuna taşınması önerilir. Alternatif olarak, dosyanın tamamını belleğe yüklemeden akış işleme için InputStream kullanabilirsiniz; bu, kaynakları kısıtlı uygulamalar için kritiktir. JSON'u bir dosyaya veya ağ akışına yazmak için writeJSONObject(_:to:options:error:) yöntemi, bir ara Data nesnesi oluşturmadan serileştirilmiş verileri doğrudan OutputStream'e göndermeye izin verir ve büyük belgelerle çalışırken bellek tüketimini azaltır.
Sıkça Sorulan Sorular
JSONSerialization JSON Data'yı Foundation nesnelerine (NSDictionary, NSArray) dönüştürmek ve geri almak için bir Foundation sınıfıdır. Ek kütüphaneler olmadan iOS, macOS, tvOS ve watchOS'ta çalışır.
Codable tür güvenli koda derlenen otomatik tür belirtilmiş serileştirme için bir Swift protokolüdür. JSONSerialization dinamik Any türleriyle çalışır ve manuel dönüştürme gerektirir. Codable yeni projeler için, JSONSerialization Objective-C ve dinamik veriler için tercih edilir.
jsonObject çağrılırken do-catch yapısını kullanın. JSONSerialization hataları CocoaError'e aittir. Hata ayıklama için, geçersiz JSON veri biçimini gösteren NSPropertyListReadCorruptError'ı kontrol edin.
Evet, JSONSerialization sözlüklerin ve dizilerin herhangi bir iç içe derinliğini destekler. Tüm iç içe nesneler, orijinal JSON yapısını koruyarak karşılık gelen Foundation türlerine (NSDictionary, NSArray, NSString, NSNumber) dönüştürülür.
JSONSerialization dinamik JSON yapıları için, Objective-C projelerinde, akışlarla çalışırken ve isValidJSONObject aracılığıyla JSON doğrulama için uygundur. Bilinen şablonu olan tür belirtilmiş yapılar için Codable tercih edilir.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun