مقدمة: لماذا لا يزال مطورو Swift يبحثون عن طلبات HTTP على Google؟
إذا كنت قد كتبت يومًا تطبيقًا بلغة Swift يتواصل مع خادم، فمن المؤكد أنك واجهت هذا السؤال. قد يبدو الأمر بسيطًا؟ أرسل طلبًا، واحصل على رد. لكن في الواقع، كل مطور ثانٍ (حتى ذو الخبرة) يفتح Stack Overflow ويبحث عن: "How to make HTTP request in Swift?". وهذا أمر طبيعي.
لماذا؟ لأن نظام Swift البيئي يتغير. بالأمس فقط، كان الجميع يكتبون closures و delegates. اليوم — async/await. وغدًا، ربما يظهر شيء آخر. في عام 2025، استقرت أساليب طلبات الشبكة، لكن الشيطان، كما هو الحال دائمًا، في التفاصيل: إدارة التدفقات، معالجة الأخطاء، إلغاء الطلبات، الاختبار.
في هذه المقالة، سنستعرض أفضل الممارسات الحقيقية لتنفيذ طلبات HTTP في Swift — من URLSession الأساسي إلى التقنيات المتقدمة مع async/await والمكتبات. ستتعلم كيفية كتابة كود شبكي نظيف وآمن وفعال. هيا بنا!
1. URLSession: الأساس الذي يجب أن يعرفه الجميع
لنبدأ بالأساسي. في مكتبة Swift القياسية (Foundation) يوجد كل ما تحتاجه للعمل مع HTTP — وهو الفئة URLSession. تذكر: في 90% من المهام، لا تحتاج إلى مكتبات خارجية. URLSession هي أداة قوية ومرنة وأصلية.
1.1. طلب GET بسيط (الطريقة القديمة)
دعنا نتذكر كيف كان يتم ذلك سابقًا. قد لا يزال هذا الكود موجودًا في المشاريع القديمة:
let url = URL(string: "https://api.pythonlib.ru/users")!let task = URLSession.shared.dataTask(with: url) { data, response, error in if let error = error { print("خطأ: \\(error.localizedDescription)") return } guard let data = data else { print("لا توجد بيانات") return } // العمل مع data print("تم استلام بايت: \\(data.count)")}task.resume()هذا الكود يعمل. لكن له عيوب:
- Callback hell — إذا كنت بحاجة إلى سلسلة من الطلبات، يصبح الكود غير قابل للقراءة.
- تسرب الذاكرة — من السهل نسيان
weak selfفي closure. - صعوبة الإلغاء — تحتاج إلى الاحتفاظ بمرجع لـ
task.
في عام 2025، نكتب بشكل مختلف.
1.2. طلب GET حديث مع async/await
بدءًا من Swift 5.5 (iOS 15، macOS 12)، لدينا structured concurrency. هذا يغير كل شيء:
func fetchUsers() async throws -> [User] { let url = URL(string: "https://api.pythonlib.ru/users")! let (data, response) = try await URLSession.shared.data(from: url) guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else { throw URLError(.badServerResponse) } return try JSONDecoder().decode([User].self, from: data)}جميل، أليس كذلك؟ لا closures، ولا resume(). الكود يُقرأ كما لو كان متزامنًا، لكنه يُنفذ بشكل غير متزامن. هذا هو المعيار الفعلي في عام 2025.
2. طلب POST: إرسال البيانات إلى الخادم
الآن دعنا نرسل البيانات. لنفترض أننا بحاجة إلى إنشاء مستخدم جديد.
2.1. POST مع نص JSON
func createUser(name: String, email: String) async throws -> User { let url = URL(string: "https://api.pythonlib.ru/users")! var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") let body = ["name": name, "email": email] request.httpBody = try JSONSerialization.data(withJSONObject: body) let (data, response) = try await URLSession.shared.data(for: request) // معالجة الرد... return try JSONDecoder().decode(User.self, from: data)}
المدونات
توصيات الكتب
اقرأ أيضًا