عميل HTTP لـ Swift (iOS/macOS): أفضل المكتبات لطلبات الشبكة
العمل مع الشبكة هو جزء لا يتجزأ من تطوير تطبيقات iOS و macOS. سواء كان تحميل البيانات من REST API، أو إرسال الملفات، أو العمل مع WebSocket، فإن اختيار عميل HTTP المناسب يؤثر بشكل مباشر على الأداء، وقابلية قراءة الكود، ووقت التطوير. في هذه المقالة، سنستعرض أفضل 4 مكتبات لـ Swift ستساعدك على العمل بكفاءة مع HTTP.
1. URLSession — المعيار المدمج من Apple
URLSession هو إطار عمل أساسي من Apple للعمل مع طلبات الشبكة. إنه مدمج في كل تطبيق على iOS/macOS ولا يتطلب تثبيت تبعيات إضافية. يدعم HTTP/2، والتحميل في الخلفية، والمصادقة، والتخزين المؤقت.
المزايا:
- لا يتطلب تبعيات خارجية
- تكامل كامل مع GCD و Combine (async/await)
- أداء عالي بفضل التنفيذ الأصلي
- دعم الجلسات الخلفية لتحميل الملفات
العيوب:
- الكثير من الكود التكراري (boilerplate) للسيناريوهات المعقدة
- عدم وجود واجهة برمجة تطبيقات مريحة للتسلسل/إلغاء التسلسل
مثال استخدام (Swift 5.5+ مع async/await):
import Foundation
struct User: Codable { let id: Int let name: String let email: String}
func fetchUser(id: Int) async throws -> User { let url = URL(string: "https://jsonplaceholder.typicode.com/users/\\(id)")! 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)}
// الاستخدامTask { do { let user = try await fetchUser(id: 1) print("User: \\(user.name), email: \\(user.email)") } catch { print("Error: \\(error.localizedDescription)") }}2. Alamofire — عميل HTTP الأكثر شعبية لـ Swift
Alamofire هو غلاف أنيق فوق URLSession، يبسط بشكل كبير طلبات الشبكة. توفر المكتبة واجهة برمجة تطبيقات متسلسلة، وتسلسل تلقائي لـ JSON، ومعالجة الأخطاء، وتحميل/رفع الملفات، ودعم Combine.
المزايا:
- الحد الأدنى من الكود التكراري (boilerplate)
- معالجة مدمجة للأخطاء وإعادة المحاولة
- دعم Codable و Combine و async/await
- تكوين مرن للرؤوس والمعاملات والمهلات
العيوب:
- تبعية إضافية (~1-2 ميجابايت)
- قد يكون مبالغًا فيه للمشاريع البسيطة
مثال استخدام:
import Alamofire
struct Post: Codable { let userId: Int let id: Int let title: String let body: String}
// طلب GET مع async/awaitfunc fetchPosts() async throws -> [Post] { let response = await AF.request("https://jsonplaceholder.typicode.com/posts") .serializingDecodable([Post].self) .response switch response.result { case .success(let posts): return posts case .failure(let error): throw error }}
// طلب POST مع المعاملاتfunc createPost(title: String, body: String) async throws -> Post { let parameters: Parameters = [ "userId": 1, "title": title, "body": body ] let response = await AF.request("https://jsonplaceholder.typicode.com/posts", method: .post, parameters: parameters, encoding: JSONEncoding.default) .serializingDecodable(Post.self) .response switch response.result { case .s