مقدمة: لماذا يحتاج مطور Swift إلى قواعد البيانات؟
عند تطوير التطبيقات الأصلية لنظامي iOS و macOS، غالباً ما تنشأ الحاجة لتخزين البيانات ليس فقط محلياً (Core Data, UserDefaults)، ولكن أيضاً على خادم بعيد. يمكن أن يكون ذلك لتحليلات الخادم، التسجيل، المزامنة بين الأجهزة، أو خلفية كاملة للتطبيق. أكثر نوعين شائعين من قواعد البيانات هما العلائقية (PostgreSQL) والموجهة للوثائق (MongoDB).
في هذه المقالة، سنشرح كيفية الاتصال بـ PostgreSQL و MongoDB من تطبيق Swift باستخدام المكتبات والمشغلات الشائعة. سنركز بشكل خاص على الجانب العملي: تثبيت التبعيات، كتابة الاستعلامات، ومعالجة الأخطاء.
1. العمل مع PostgreSQL من Swift
PostgreSQL هو نظام إدارة قواعد بيانات علائقية قوي، مثالي للمشاريع التي تكون فيها سلامة البيانات والاستعلامات SQL المعقدة مهمة. في Swift، يمكننا العمل مع PostgreSQL بطريقتين رئيسيتين:
- عبر ORM Fluent (جزء من إطار العمل Vapor) — نهج عالي المستوى، مناسب لتطبيقات الويب.
- مباشرة عبر المشغل (مثل
PostgresNIO) — تحكم منخفض المستوى، مناسب لتطبيقات iOS/macOS.
سننظر في الخيار الثاني، لأنه لا يتطلب Vapor ومناسب للتطبيقات العادية.
1.1. الاتصال بـ PostgreSQL عبر PostgresNIO
أضف التبعية في Package.swift:
dependencies: [ .package(url: "https://github.com/vapor/postgres-nio.git", from: "1.18.0")]مثال على الاتصال وتنفيذ استعلام:
import PostgresNIOimport NIOCoreimport NIOPosix
func queryPostgres() async throws { let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1) defer { try? eventLoopGroup.syncShutdownGracefully() }
let config = PostgresConnection.Configuration( host: "localhost", port: 5432, username: "swift_user", password: "secret", database: "test_db", tls: .disable )
let connection = try await PostgresConnection.connect( on: eventLoopGroup.next(), configuration: config ) defer { try? connection.close() }
let rows = try await connection.query("SELECT id, name FROM users LIMIT 5;", logger: nil) for try await row in rows { let id = try row.decode(Int.self, column: "id") let name = try row.decode(String.self, column: "name") print("ID: \\(id), Name: \\(name)") }}يقوم هذا الكود بإنشاء اتصال بخادم PostgreSQL محلي، وتنفيذ SELECT وعرض النتائج. هام: لا تقم أبداً بتخزين كلمات المرور في الكود — استخدم متغيرات البيئة أو Keychain.
1.2. إدراج البيانات مع المعاملات
للحماية من حقن SQL، استخدم الاستعلامات ذات المعاملات:
let name = "Alice"let age = 30try await connection.query( "INSERT INTO users (name, age) VALUES ($1, $2);", params: [.string(name), .int(age)], logger: nil)2. العمل مع MongoDB من Swift
MongoDB هي قاعدة بيانات NoSQL، تخزن البيانات في شكل وثائق تشبه JSON (BSON). يوجد مشغل ممتاز لـ Swift يسمى MongoSwift.
2.1. تثبيت MongoSwift
أضف في Package.swift:
dependencies: [ .package(url: "https://github.com/mongodb/mongo-swift-driver.git", from: "1.3.0")]2.2. الاتصال وعمليات CRUD
مثال على الاتصال بـ MongoDB محلياً وإدراج وثيقة:
import MongoSwift
func mongoExample() async throws { let client = try MongoClient("mongodb://localhost:27017") defer { try? client.syncClose() }
let db = client.db("test_database") let collection = db.collection("users")
// إدراج وثيقة let document: Document = ["name": "Bob", "age": 25, "city": "Mosc