JSONSerialization — Foundation freymvorkundan iOS-un daxili sinfi, JSON-u Foundation obyektlərinə və əksinə çevirmək üçün nəzərdə tutulub. Bu API, Apple platformalarında JSON ilə işləmək üçün əsas mexanizmdir, üçüncü tərəf kitabxanalarını qoşmadan lüğətlərin, massivlərin və primitiv tiplərin pars edilməsini dəstəkləyir. Apple Developer, 2024-ə görə, JSONSerialization Data, axınlar və JSON məlumatlarının çevik emalı üçün oxu seçimləri ilə işi dəstəkləyir.
Əsas məqamlar
JSONSerialization — iOS, macOS, tvOS və watchOS-da mövcud olan Foundation freymvorkundan bir sinifdir. O, JSON Data-nı Foundation obyektlərinə (NSDictionary, NSArray, NSString, NSNumber) və əksinə çevirmək üçün metodlar təqdim edir. Sinif iOS 5-də ortaya çıxdı və Codable-ın (Swift 4) tətbiqinə qədər Apple platformalarında JSON ilə işləməyin əsas yolu olaraq qaldı. Yaşına baxmayaraq, JSONSerialization Objective-C-də legacy layihələrində və sabit model sxemi olmadan dinamik JSON emalı tələb edən ssenarilərdə tələb olunmağa davam edir.
Codable-ın meydana gəlməsinə baxmayaraq, JSONSerialization bir neçə ssenaridə aktual olaraq qalır. Dinamik JSON strukturu — cavab formatı dəyişdikdə və ya əvvəlcədən məlum olmadıqda — açarlar vasitəsilə lüğətlərə müraciət tələb edir, bunu JSONSerialization vasitəsilə etmək daha asandır. Sinif həmçinin Codable-ın mövcud olmadığı Objective-C layihələrində və böyük JSON fayllarının mərhələli pars edilməsi üçün axınlarla işləyərkən tətbiq olunur. Testlərdə və maketlərdə isValidJSONObject və data(withJSONObject:options:) üçüncü tərəf kitabxanalarını qoşmadan sürətlə JSON fiksturları yaratmağa imkan verir ki, bu da inkişaf və prototipləşdirməni sürətləndirir.
import Foundation
// JSONSerialization istifadəsinin əsas strukturu
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 pars xətası: \(error)")
}
JSONSerialization JSON ilə işləmək üçün dörd əsas metod təqdim edir. Əsas metod — jsonObject(with:options:), Data-nı Foundation obyektlərinə çevirir. data(withJSONObject:options:) metodu əks serializasiyanı yerinə yetirir. isValidJSONObject(_:) obyektin serializasiya oluna biləcəyini yoxlayır. writeJSONObject(_:to:options:error:) JSON-u birbaşa axına yazır. InputStream-dən JSON oxumaq üçün Data əvəzinə axın qəbul edən jsonObject(with:options:) metodu mövcuddur ki, bu da axın məlumatlarını qaytaran şəbəkə sorğuları ilə inteqrasiya zamanı rahatdır.
jsonObject metodu Data qəbul edir və Any qaytarır — adətən NSDictionary və ya NSArray. Təhlükəsiz iş üçün nəticə şərti çevirmə vasitəsilə gözlənilən tipə salınır. data metodu Foundation obyektini qəbul edir və JSON təsviri ilə Data qaytarır. .prettyPrinted seçimi oxunaqlılıq üçün abzaslarla formatlaşdırma əlavə edir.
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("Məhsul: \(name)")
}
}
}
// Əks serializasiya: obyekt -> JSON
let outputDict: [String: Any] = ["status": "ok", "count": 42]
if let outputData = try? JSONSerialization
.data(withJSONObject: outputDict,
options: .prettyPrinted) {
String(data: outputData, encoding: .utf8)
}
Əsas pars etmə primitiv tiplərlə lüğətin — JSONSerialization ilə ən çox yayılmış əməliyyatdır. URLSession vasitəsilə Data aldıqdan sonra tərtibatçı jsonObject-i çağırır və nəticəni gözlənilən tipə salır. Obyekt massivləri üçün [[String: Any]]-ə çevirmə istifadə olunur, bundan sonra hər bir element dövrədə emal edilir. Bu yanaşma çevikdir, lakin əl ilə tip idarəçiliyi tələb edir.
Real API-lər massivlər, tarixlər və isteğe bağlı sahələrlə mürəkkəb iç-içə JSON obyektləri qaytarır. JSONSerialization istənilən yuvalanma dərinliyini düzgün idarə edir, lakin tərtibatçı hər səviyyəni tələb olunan tipə müstəqil şəkildə salmalıdır. Bu tapşırığı sadələşdirmək üçün Apple tipləşdirilmiş məlumatlar üçün Codable, dinamik strukturlar üçün isə yalnız JSONSerialization istifadəsini tövsiyə edir.
// API cavabının pars edilməsi
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("İstifadəçi: \(name) (ID: \(userId))")
} catch let error as ParsingError {
print("Pars uğursuz oldu: \(error)")
} catch {
print("Gözlənilməz xəta: \(error)")
}
}
enum ParsingError: Error {
case missingField
case invalidType
}
JSONSerialization etibarsız JSON, tip uyğunsuzluğu və ya yuvalanma dərinliyinin aşılması zamanı xətalar atır. Xətalar CocoaError tipinə aiddir və problemin təsviri ilə kod ehtiva edir. Tərtibatçı onları do-catch konstruksiyası vasitəsilə idarə etməlidir, əks halda proqram qəzaya uğrayacaq. Ən çox yayılmış xətalar: NSPropertyListReadCorruptError (yanlış JSON) və NSPropertyListReadUnknownError. Hər bir xəta növü öz idarəetmə strategiyasını tələb edir: yanlış formatda məlumatların təkrar göndərilməsini tələb etmək, struktur uyğunsuzluğunda isə pars modelini yeniləmək lazımdır.
Yanlış JSON — uğursuzluqların ən ümumi səbəbi: buraxılmış vergül, artıq simvol və ya düzgün qaçırılmamış dırnaq işarəsi bütün parsı pozur. İkinci növ xətalar — gözlənilən strukturla uyğunsuzluq: məsələn, server lüğət əvəzinə massiv qaytardı. JSONSerialization.fragmentsAllowed kökü lüğət və ya massiv deyil, primitiv dəyər olan JSON-u oxumağa imkan verir. Tərtibatçı həmçinin JSON çox çox yuvalanma səviyyəsi ehtiva etdikdə dərinliyin aşılması xətası ilə qarşılaşa bilər.
JSONSerialization parsı konfiqurasiya etmək üçün bir neçə seçim təqdim edir. .mutableContainers dəyişməz versiyalar əvəzinə NSMutableDictionary və NSMutableArray qaytarır ki, bu da parsdan sonra məlumatların dəyişdirilməsi zamanı faydalıdır. .mutableLeaves mətn dəyərlərini dəyişdirilə bilən edir. .fragmentsAllowed kökü obyekt və ya massiv deyil, mətn və ya rəqəm olan JSON-a icazə verir — bu sadə API cavabları üçün rahatdır. .withoutEscapingSlashes və .sortedKeys seçimləri data(withJSONObject:options:) metodu üçün mövcuddur, serializasiya olunmuş JSON-un formatlaşdırılmasını idarə edir. Seçimlər bit maskası ilə ötürülür ki, bu da parsın çevik konfiqurasiyası üçün operator | vasitəsilə bir neçə dəyəri birləşdirməyə imkan verir.
// Müxtəlif xəta növlərinin idarə edilməsi
func safeParse(jsonData: Data) {
do {
let object = try JSONSerialization
.jsonObject(with: jsonData,
options: .fragmentsAllowed)
if let dictionary = object as? [String: Any] {
print("Lüğət \(dictionary.count) açarla")
} else if let array = object as? [Any] {
print("Massiv \(array.count) elementlə")
}
} catch CocoaError.propertyListReadCorrupt {
print("Korlanmış JSON məlumatı")
} catch let error as CocoaError {
print("Cocoa xətası: \(error)")
} catch {
print("Naməlum xəta: \(error)")
}
}
// Serializasiyadan əvvəl obyektin düzgünlüyünün yoxlanılması
let testObject: [String: Any] = ["key": "value", "nested": ["a": 1]]
if JSONSerialization.isValidJSONObject(testObject) {
print("Düzgün JSON obyekti")
}
JSONSerialization performansına məlumatların ölçüsü və çağırışların tezliyi təsir edir. Kiçik server cavabının birdəfəlik pars edilməsində fərq nəzərə çarpmır, lakin onlarla meqabayt JSON-un emalı və ya dövrələrdə tez-tez çağırışlar zamanı tip çevirmə xərclərini nəzərə almaq lazımdır. JSONSerialization sinxron işləyir cari axında, buna görə də böyük sənədlər üçün DispatchQueue.global() vasitəsilə parsı fon növbəsinə çıxarmaq tövsiyə olunur. Alternativ olaraq, bütün faylı yaddaşa yükləmədən axın emalı üçün InputStream istifadə edilə bilər ki, bu da məhdud resurslu proqramlar üçün kritikdir. JSON-u fayla və ya şəbəkə axınına yazmaq üçün writeJSONObject(_:to:options:error:) metodu aralıq Data obyekti yaratmadan serializasiya olunmuş məlumatları birbaşa OutputStream-a yönləndirməyə imkan verir ki, bu da böyük sənədlərlə işləyərkən yaddaş istehlakını azaldır.
Tez-tez verilən suallar
JSONSerialization — JSON Data-nı Foundation obyektlərinə (NSDictionary, NSArray) və əksinə çevirmək üçün Foundation sinfidir. O, əlavə kitabxanalar qoşmadan iOS, macOS, tvOS və watchOS-da işləyir.
Codable — tipli təhlükəsiz koda kompilyasiya olunan avtomatik tipləşdirilmiş serializasiya üçün Swift protokoludur. JSONSerialization dinamik Any tipləri ilə işləyir və əl ilə çevirmə tələb edir. Codable yeni layihələr üçün, JSONSerialization isə Objective-C və dinamik məlumatlar üçün daha uyğundur.
jsonObject-u çağırarkən do-catch konstruksiyasından istifadə edin. JSONSerialization xətaları CocoaError-a aiddir. Debug üçün JSON məlumatlarının yanlış formatını göstərən NSPropertyListReadCorruptError-u yoxlayın.
Bəli, JSONSerialization lüğətlərin və massivlərin istənilən yuvalanma dərinliyini dəstəkləyir. Bütün iç-içə obyektlər orijinal JSON strukturunu qoruyaraq müvafiq Foundation tiplərinə (NSDictionary, NSArray, NSString, NSNumber) çevrilir.
JSONSerialization dinamik JSON strukturunda, Objective-C layihələrində, axınlarla işləyərkən və isValidJSONObject vasitəsilə JSON-un düzgünlüyünü yoxlamaq üçün uyğundur. Məlum sxemli tipləşdirilmiş strukturlar üçün Codable daha yaxşı seçimdir.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun