العمل مع JSON في Swift: التحليل والتسلسل
JSON (JavaScript Object Notation) هو تنسيق خفيف لتبادل البيانات، يُستخدم على نطاق واسع في خدمات الويب وتطبيقات الهاتف المحمول. في نظام Apple البيئي (iOS، macOS، watchOS، tvOS)، يُعد العمل مع JSON جزءًا لا يتجزأ من التطوير: من تحميل البيانات من الخادم إلى حفظ إعدادات التطبيق. في هذه المقالة، سنستعرض بالتفصيل كيفية إجراء التحليل (فك الترميز) والتسلسل (الترميز) لـ JSON في Swift باستخدام البروتوكولات المدمجة Codable وJSONDecoder وJSONEncoder.
1. أساسيات Codable: نموذج البيانات
يعتمد النهج الحديث للعمل مع JSON في Swift على البروتوكول Codable، الذي يجمع بين بروتوكولين: Encodable (للتسلسل) وDecodable (للتحليل). لجعل هيكلك أو صنفك قابلاً للتحويل إلى JSON والعكس، يكفي تعريفهما كـ Codable.
لنأخذ مثالاً على نموذج مستخدم:
struct User: Codable { let id: Int let name: String let email: String let isActive: Bool}إذا كانت المفاتيح في JSON تختلف عن أسماء الخصائص في Swift (على سبيل المثال، استخدام snake_case بدلاً من camelCase)، يمكنك استخدام التعداد CodingKeys:
struct User: Codable { let id: Int let fullName: String let email: String let isActive: Bool
enum CodingKeys: String, CodingKey { case id case fullName = "full_name" case email case isActive = "is_active" }}2. تحليل JSON باستخدام JSONDecoder
لتحويل سلسلة JSON أو بياناتها إلى كائنات Swift، يُستخدم JSONDecoder. الطريقة الرئيسية هي decode(_:from:)، التي تأخذ نوع البيانات (المتوافق مع Decodable) وكائن Data.
مثال على تحليل سلسلة JSON تم الحصول عليها من API:
let jsonString = """{ "id": 1, "name": "إيفان بيتروف", "email": "ivan@example.com", "is_active": true}"""
let jsonData = Data(jsonString.utf8)
do { let decoder = JSONDecoder() let user = try decoder.decode(User.self, from: jsonData) print("المستخدم: \\(user.name)، البريد الإلكتروني: \\(user.email)")} catch { print("خطأ في فك الترميز: \\(error.localizedDescription)")}غالبًا ما يأتي JSON كمصفوفة من الكائنات. في هذه الحالة، حدد ببساطة النوع [User].self:
let jsonArrayString = """[ {"id": 1, "name": "إيفان", "email": "ivan@test.com", "is_active": true}, {"id": 2, "name": "ماريا", "email": "maria@test.com", "is_active": false}]"""
let jsonArrayData = Data(jsonArrayString.utf8)
do { let users = try JSONDecoder().decode([User].self, from: jsonArrayData) users.forEach { print($0.name) }} catch { print("خطأ: \\(error)")}3. تسلسل الكائنات إلى JSON باستخدام JSONEncoder
العملية العكسية — تحويل كائن Swift إلى JSON — تتم باستخدام JSONEncoder. الطريقة encode(_:) تُرجع كائن Data، والذي يمكن تحويله بعد ذلك إلى سلسلة نصية أو إرساله إلى الخادم.
let user = User(id: 3, fullName: "أليكسي سميرنوف", email: "alex@example.com", isActive: true)
do { let encoder = JSONEncoder() encoder.outputFormatting = .prettyPrinted // لتنسيق قابل للقراءة let jsonData = try encoder.encode(user) if let jsonString = String(data: jsonData, encoding: .utf8) { print(jsonString) }} catch { print("خطأ في الترميز: \\(error)")}سيكون الإخراج كالتالي:
{ "id" : 3, "full_name" : "أليكسي سميرنوف", "email" : "alex@example.com", "is_active" : true}لاحظ أن JSO