DataStore في Kotlin: دليل شامل مع أمثلة تطبيقية
1. ما هي DataStore ولماذا تحتاجها؟
DataStore هي مكتبة من Google لتخزين كميات صغيرة من البيانات في تطبيقات Kotlin (وأندرويد). جاءت لتحل محل SharedPreferences القديمة وتقدم طريقة أكثر أمانًا وتزامنًا وأمانًا من حيث الأنواع للتعامل مع البيانات. تستخدم DataStore مكتبتي Kotlin Coroutines و Flow، مما يجعلها الخيار الأمثل للتطبيقات الحديثة التي تعتمد على البرمجة التفاعلية.
لماذا تحتاج DataStore؟ المشكلة الرئيسية في SharedPreferences هي القراءة المتزامنة من القرص، والتي قد تمنع واجهة المستخدم، بالإضافة إلى عدم دعم أنواع البيانات (يتم تخزين كل شيء كـ Set<String>). تحل DataStore هذه المشاكل: جميع عمليات القراءة والكتابة غير متزامنة، ويتم تخزين البيانات في كائنات محددة الأنواع (عبر Protocol Buffers أو Preferences). علاوة على ذلك، تتعامل DataStore تلقائيًا مع أخطاء التسلسل وتوفر واجهة برمجة نظيفة للتعامل مع البيانات.
تتوفر المكتبة بنوعين: Preferences DataStore (لتخزين أزواج بسيطة من "مفتاح-قيمة"، مثل SharedPreferences) و Proto DataStore (لتخزين كائنات محددة الأنواع عبر Protocol Buffers). في هذه المقالة، سنركز على Preferences DataStore باعتبارها الخيار الأبسط والأكثر استخدامًا.
2. التثبيت
يتم توزيع DataStore عبر Maven Central. لإضافتها إلى مشروع Kotlin/Android، أضف التبعية في ملف build.gradle.kts (وحدة التطبيق):
dependencies {
// Preferences DataStore
implementation("androidx.datastore:datastore-preferences:1.1.1")
// إذا كنت تستخدم Proto DataStore
// implementation("androidx.datastore:datastore-core:1.1.1")
// لدعم Coroutines (عادةً ما تكون موجودة بالفعل في المشروع)
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0")
}
إذا كنت تستخدم Gradle مع Groovy (build.gradle)، فسيكون السطر كالتالي:
implementation 'androidx.datastore:datastore-preferences:1.1.1'
بعد مزامنة Gradle، تصبح المكتبة جاهزة للاستخدام.
3. بداية سريعة — مثال عملي بسيط
لننشئ DataStore بسيطًا لتخزين اسم المستخدم وعداد.
import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
// إضافة خاصية DataStore للـ Context
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "user_settings")
// مفاتيح البيانات
val USER_NAME_KEY = stringPreferencesKey("user_name")
val COUNTER_KEY = intPreferencesKey("counter")
class UserPreferences(private val context: Context) {
// قراءة اسم المستخدم كـ Flow
val userName: Flow<String?> = context.dataStore.data.map { preferences ->
preferences[USER_NAME_KEY]
}
// قراءة العداد كـ Flow
val counter: Flow<Int> = context.dataStore.data.map { preferences ->
preferences[COUNTER_KEY] ?: 0
}
// حفظ اسم المستخدم
suspend fun saveUserName(name: String) {
context.dataStore.edit { preferences ->
preferences[USER_NAME_KEY] = name
}
}
// زيادة العداد
suspend fun incrementCounter() {
context.dataStore.edit { preferences ->
val currentCounter = preferences[COUNTER_KEY] ?: 0
preferences[COUNTER_KEY] = currentCounter + 1
}
}