مقدمة
نادراً ما تخلو تطبيقات iOS وmacOS الحديثة من التفاعل مع الخوادم البعيدة. سواء كان تحميل البيانات من خلاصة الأخبار، أو إرسال نموذج تسجيل، أو مزامنة الملفات - كل هذه العمليات تتطلب تنفيذاً صحيحاً لعميل HTTP. في نظام Swift البيئي، يتوفر للمطور إطار عمل مدمج وقوي URLSession، والذي أصبح أكثر سهولة عاماً بعد عام بفضل إدخال async/await.
في هذه المقالة، سنشرح كيفية إنشاء طلبات HTTP بشكل صحيح بلغة Swift، بدءاً من الهياكل الأساسية وصولاً إلى التقنيات المتقدمة لمعالجة الأخطاء وتسلسل البيانات. ستتعلم كيفية كتابة كود شبكي نظيف وآمن وعالي الأداء لتطبيقاتك.
أساسيات URLSession: أول طلب HTTP
الفئة URLSession هي الأساس لأي عمل شبكي في Swift. فهي تدير التكوين والتخزين المؤقت والجلسات وتنفيذ الطلبات مباشرة. دعنا نلقي نظرة على طلب GET بسيط لجلب البيانات من الخادم.
إنشاء طلب GET بسيط
import Foundation
// 1. إنشاء URLguard let url = URL(string: "https://api.example.com/users") else { print("عنوان URL غير صحيح") return}
// 2. إنشاء الطلب (الافتراضي هو GET)var request = URLRequest(url: url)request.httpMethod = "GET"request.setValue("application/json", forHTTPHeaderField: "Accept")
// 3. إنشاء جلسةlet session = URLSession.shared
// 4. تنفيذ الطلب (الطريقة القديمة مع الإغلاق)let task = session.dataTask(with: request) { data, response, error in if let error = error { print("خطأ في الطلب: \\(error.localizedDescription)") return } guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else { print("الخادم أعاد خطأ") return } if let data = data, let jsonString = String(data: data, encoding: .utf8) { print("البيانات المستلمة: \\(jsonString)") }}task.resume() // مهم! تشغيل المهمةنقاط رئيسية: تحقق دائماً من حالة الاستجابة (200...299)، ولا تنس استدعاء resume()، وتعامل مع الأخطاء المحتملة. في المشاريع الحقيقية، عادةً ما يتم نقل هذا الكود إلى طبقة خدمة منفصلة.
النهج الحديث: async/await
ابتداءً من Swift 5.5، أصبح من الممكن استخدام async/await، مما يجعل الكود أكثر قابلية للقراءة ويخلصك من "هرم الإغلاقات".
func fetchUsers() async throws -> Data { guard let url = URL(string: "https://api.example.com/users") else { throw URLError(.badURL) } var request = URLRequest(url: url) request.httpMethod = "GET" request.setValue("application/json", forHTTPHeaderField: "Accept") let (data, response) = try await URLSession.shared.data(for: request) guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else { throw URLError(.badServerResponse) } return data}يمكن استدعاء هذا الكود من أي دالة أو مهمة غير متزامنة، مما يبسط المنطق بشكل كبير.
العمل مع JSON: Codable ونماذج البيانات
نادراً ما تأتي البيانات بشكل "خام". غالباً ما نتعامل مع JSON. تقدم Swift حلاً أنيقاً - بروتوكول Codable (الذي يجمع بين Encodable و Decodable).
إنشاء النموذج وفك التشفير
// 1. تعريف هيكل البياناتstruct User: Codable { let id: Int let name: String let email: String}
// 2. دالة غير متزامنة لجلب مصفوفة المستخدمينfunc fetchUsers() async throws -> [User] { let data = try await fetchUsersData() // من المثال السابق let decoder = JSONDecoder() return try decoder.decode