Swift Data: إطار عمل ORM الجديد من Apple للغة Swift
1. ما هو Swift Data ولماذا تحتاجه؟
Swift Data هو إطار عمل حديث وخفيف من نوع ORM (تعيين الكائنات العلائقية)، كشفت عنه Apple في مؤتمر WWDC 2023. صُمم للتعامل مع البيانات الدائمة في تطبيقات Swift التي تدعم iOS 17+ وmacOS 14+ وtvOS 17+ وwatchOS 10+. جاء Swift Data ليحل محل Core Data القديم، ويقدم نهجًا أبسط وتصريحيًا وآمنًا من حيث الأنواع لإدارة قاعدة البيانات.
لماذا تحتاج Swift Data؟ في المقام الأول، لتبسيط الكود بشكل كبير. بدلاً من إنشاء NSManagedObject يدويًا، وإعداد السياقات، وكتابة استعلامات معقدة، يصف المطور نموذج البيانات باستخدام فئات Swift العادية والماكرو (@Model، @Attribute، @Relationship). يقوم Swift Data تلقائيًا بتوليد كل المنطق الداخلي اللازم: إنشاء الجداول، إدارة التغييرات، تتبع التبعيات، والمزامنة مع واجهة المستخدم عبر SwiftUI.
الميزة الرئيسية هي التكامل الوثيق مع SwiftUI. التغييرات في البيانات تُحدّث الواجهة تلقائيًا دون الحاجة إلى استدعاء objectWillChange.send() يدويًا أو إعادة تحميل القوائم. هذا يجعل Swift Data الخيار الأمثل للمشاريع الجديدة على SwiftUI التي تتطلب تخزينًا محليًا للبيانات (قوائم المهام، الملاحظات، الإعدادات، التخزين المؤقت).
2. التثبيت
Swift Data هو جزء من المكتبة القياسية لـ Apple، بدءًا من iOS 17 وmacOS 14. لا يتطلب تثبيتًا منفصلاً عبر مديري الحزم (pip, npm, cargo). للاستخدام، يكفي استيراد الإطار في ملف Swift.
هام: يجب أن يكون الحد الأدنى لإصدار النشر (Deployment Target) لمشروعك هو iOS 17.0 أو macOS 14.0.
الأمر لإضافته إلى المشروع (عبر Xcode):
// Swift Data لا يتطلب تثبيتًا. فقط قم باستيراده:
import SwiftData
إذا كنت تستخدم Swift Package Manager (SPM) لإدارة التبعيات، فلا حاجة لإضافة Swift Data كحزمة منفصلة — فهو مدمج في SDK.
3. البداية السريعة — مثال عملي بسيط
لننشئ تطبيقًا بسيطًا لتخزين قائمة المهام (To-Do).
import SwiftUI
import SwiftData
// 1. تعريف نموذج البيانات
@Model
final class TaskItem {
var title: String
var isCompleted: Bool
var createdAt: Date
init(title: String, isCompleted: Bool = false) {
self.title = title
self.isCompleted = isCompleted
self.createdAt = Date()
}
}
// 2. إعداد الحاوية في التطبيق
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
.modelContainer(for: TaskItem.self) // ينشئ الحاوية تلقائيًا
}
}
// 3. استخدام البيانات في الواجهة
struct ContentView: View {
@Environment(\.modelContext) private var context
@Query private var tasks: [TaskItem]
var body: some View {
NavigationStack {
List {
ForEach(tasks) { task in
HStack {
Text(task.title)
Spacer()
if task.isCompleted {
Image(systemName: "checkmark")
}
}
}
.onDelete(perform: deleteTasks)
}
.navigationTitle("المهام")
.toolbar {
ToolbarItem {
Button("إضافة") {
let newTask = TaskItem(title: "مهمة جديدة \(tasks.count + 1)")
context.in