Постоянното съхранение на данни осигурява запазването на потребителска информация между сесиите на мобилното приложение. Без тази технология всяко стартиране на програмата би започвало от нулата — настройки, история и изтеглени файлове биха се загубили при затваряне. Според данни на Google Developers, 2024, повече от 90% от мобилните приложения използват поне един механизъм за постоянно съхранение за запазване на потребителски данни и състояние на интерфейса.
Основни точки
Data Persistence — способността на приложението да съхранява данни в енергонезависимата памет на устройството. В мобилното разработване постоянното съхранение обхваща бази данни, файлова система, настройки и кеш. Всеки механизъм има свои характеристики на производителност, сигурност и обем на съхраняваната информация.
Временните данни съществуват само в RAM паметта и се губят при завършване на процеса. Към тях спадат състояние на екрана, временни изчисления и кеш на изображения. Постоянните данни се записват във файловата система или базата данни и остават достъпни след рестартиране на приложението. Към тях спадат потребителски настройки, токени за оторизация, история на операциите и изтеглено съдържание.
При избора на метод за съхранение разработчикът оценява няколко фактора. Типът данни определя структурата на съхранение: прости настройки — SharedPreferences или DataStore, структурирани записи — SQLite или Room, файлове — File Storage. Обемът на данните влияе на производителността: базите данни са оптимизирани за хиляди записи, а файловете — за големи двоични обекти. Сигурността изисква криптиране на чувствителна информация чрез EncryptedSharedPreferences или SQLCipher.
data class StorageOption(
name: String,
dataType: StorageType,
capacity: Long,
secure: Boolean
)
enum class StorageType {
KEY_VALUE,
RELATIONAL,
FILE
}
SharedPreferences — класическият начин за съхранение на двойки ключ-стойност на Android. Този API съществува от първите версии на платформата и поддържа примитивни типове: низове, числа, булеви стойности. Данните се съхраняват в XML файл в частната директория на приложението и са достъпни само за неговия процес.
Jetpack DataStore — модерният заместител на SharedPreferences, изграден върху Kotlin Coroutines и Flow. DataStore предлага два варианта: Preferences DataStore за прости стойности и Proto DataStore за типизирани обекти. За разлика от SharedPreferences, DataStore гарантира консистентност на данните при конкурентен достъп и поддържа асинхронни операции без блокиране на основната нишка.
// SharedPreferences — традиционен начин
val prefs = context
.getSharedPreferences("settings", Context.MODE_PRIVATE)
with (prefs.edit()) {
putString("username", "john_doe")
putInt("score", 1500)
apply()
}
// DataStore — асинхронен подход
val settingsDataStore = context
.createDataStore("settings.pb")
val usernameFlow: Flow<String> = settingsDataStore
.data
.map { it[USERNAME_KEY] ?: "" }
На iOS еквивалентът на SharedPreferences е UserDefaults — система за съхранение на прости стойности във формат Property List. UserDefaults използва синхронен достъп и е подходящ за малки обеми конфигурационни данни, но не се препоръчва за съхранение на чувствителна информация.
SQLite — вградена релационна база данни, която работи вътре в процеса на приложението без отделен сървър. Това е най-разпространената DBMS в мобилното разработване: използва се по подразбиране на двете платформи. Android включва SQLite в SDK, а iOS — в библиотеката libsqlite3. SQLite поддържа стандартен SQL, транзакции, индекси и тригери.
Работата с SQLite започва със създаване на схема на базата данни. Разработчикът дефинира таблици, техните полета и типове, след което изпълнява операции за вмъкване, четене, актуализиране и изтриване. SQLiteOpenHelper на Android управлява създаването и миграциите на базата данни, а на iOS се използва C интерфейс или FMDB обвивка.
// SQLiteOpenHelper на Android
class DBHelper(context: Context) :
SQLiteOpenHelper(context, "app.db", null, 1) {
override fun onCreate(db: SQLiteDatabase) {
db.execSQL("""
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE
)
""")
}
fun insertUser(name: String, email: String) {
val db = writableDatabase
val values = ContentValues().apply {
put("name", name)
put("email", email)
}
db.insert("users", null, values)
}
}
| Тип данни | SharedPreferences | SQLite | Файлова система |
|---|---|---|---|
| Тип | ключ-стойност | релационна БД | двоични файлове |
| Обем | стотици записи | хиляди записи | налично място |
| Производителност | висока | средна | зависи от размера |
| Типично приложение | настройки | структурирани данни | изображения, видео |
Room — библиотека от пакета Jetpack, която предоставя ORM слой над SQLite. Room елиминира рутинната работа по писане на SQL заявки и ContentValues, като ги заменя с анотации и Kotlin функции. Компилаторът на Room генерира имплементация на DAO (Data Access Object) на етапа на компилация, което изключва грешки в SQL синтаксиса.
За свързване на Room е необходимо да се добави зависимост kapt и да се анотира класът на обекта, DAO интерфейсът и класът на базата данни. RoomDatabase служи като входна точка: чрез него се получава DAO и се изпълняват операции с базата данни. Room поддържа Flow за реактивни заявки, миграция на схема и проверка на заявки на етапа на компилация.
@Entity(tableName = "users")
data class User(
@PrimaryKey val id: Int,
@ColumnInfo(name = "full_name") val name: String,
@ColumnInfo val email: String
)
@Dao
interface UserDao {
@Query("SELECT * FROM users")
fun getAll(): Flow<List<User>>
@Insert
suspend fun insert(user: User)
@Delete
suspend fun delete(user: User)
}
@Database(
entities = [User::class],
version = 1
)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
Core Data — рамка на Apple за управление на граф от обекти и тяхното записване на диска. За разлика от Room, Core Data не работи с таблици, а с управлявани обекти (NSManagedObject), които образуват йерархия от връзки. Core Data поддържа мързеливо зареждане, отмяна на промени и сложни заявки чрез NSFetchRequest.
Основата на Core Data е стек от три компонента: управляван контекст (NSManagedObjectContext), постоянно хранилище (NSPersistentStoreCoordinator) и модел на данни (NSManagedObjectModel). NSPersistentContainer обединява всички компоненти в единна входна точка, опростявайки настройката за съвременни приложения на Swift.
import CoreData
class PersistenceController {
static let shared = PersistenceController()
let container: NSPersistentContainer
init() {
container = NSPersistentContainer(name: "AppModel")
container.loadPersistentStores { _, error in
if let error = error {
fatalError("Failed: \(error)")
}
}
}
func saveUser(name: String, email: String) {
let context = container.viewContext
let user = User(context: context)
user.name = name
user.email = email
do {
try context.save()
} catch let error {
print("Грешка при запис: \(error)")
}
}
}
Файловото съхранение (File Storage) се използва за запазване на изображения, видеа и документи. Android предоставя вътрешно хранилище (context.filesDir) — частно за приложението, и външно (Environment.getExternalStorageDirectory) — достъпно за други приложения. На iOS файловете се записват в директориите Documents и Library, като Library/Caches е предназначена за кеш, който не се архивира в iCloud. За работа с файлове и двете платформи предоставят File API и поточни операции за четене и запис. Съвременни библиотеки като Coil и SDWebImage добавят слой за кеширане, комбинирайки файлово съхранение с RAM за оптимална производителност.
На Android алтернатива на Core Data по сложност и функционалност е Realm — обектно-ориентирана база данни, която работи директно с моделите без SQL слой. Realm е по-бърз от SQLite в операциите за четене и поддържа живи обекти, които автоматично актуализират UI при промяна на данните.
Често задавани въпроси
Data Persistence — механизми за съхранение на данни в енергонезависимата памет на устройството, осигуряващи тяхната достъпност след рестартиране на приложението. Към тях спадат бази данни, файлово съхранение и системи за настройки.
Room е ORM обвивка над SQLite, която елиминира ръчното писане на SQL заявки и ContentValues. Room проверява SQL заявките на етапа на компилация, поддържа Kotlin Coroutines и Flow, както и автоматично генерира код за достъп до данни.
SharedPreferences е подходящ за съхранение на малък обем прости данни: настройки на приложението, флагове, идентификатори и потребителски предпочитания. За сложни или структурирани данни е по-добре да използвате Room или DataStore.
Core Data — рамка на Apple за управление на граф от обекти. Тя предоставя работа с управлявани обекти, проследяване на промени, мързеливо зареждане и автоматично записване в постоянно хранилище (SQLite, XML или двоичен формат).
Изборът зависи от сложността на данните: за настройки — DataStore или UserDefaults, за структурирани записи — Room (Android) или Core Data (iOS), за файлове — File Storage. Критериите включват обем на данните, изисквания за производителност и необходимост от криптиране. Комбинирането на няколко механизма в едно приложение е стандартна практика, позволяваща оптимално използване на силните страни на всеки подход.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също