Multiplatform Settings
Ознакомьтесь с multiplatform-settings - библиотекой, позволяющей сохранять key-value данные в параметры устройства из общего кода, используя SharedPreferences
для Android и NSUserDefaults
для iOS
Разберем варианты ее подключения к проекту.
Подключение, используя expect/actual
Создайте expect/actual функцию, для получения settings
на платформах
получение
settings
для Android
androidMain:
var appContext: Context? = null
actual fun getSettings(): Settings {
val delegate = appContext!!.getSharedPreferences("app", Context.MODE_PRIVATE)
val settings: Settings = SharedPreferencesSettings(delegate)
return settings
}Перед тем, как обращаться к функции
getSettings
, проинициализируйте переменнуюappContext
.получение
settings
для iOS
iosMain:
actual fun getSettings(): Settings {
val delegate = NSUserDefaults.standardUserDefaults
val settings: Settings = NSUserDefaultsSettings(delegate)
return settings
}
Подключение no-arg библиотеки
Если вся работа с multiplatform-settings будет происходить в общем коде, вы можете использовать no-arg-module.
Используя его, вам не придется инициализировать Settings
на платформе, для Android
, в качестве делегата будет использоваться PreferenceManager.getDefaultSharedPreferences()
, а для iOS - NSUserDefaults.standardUserDefaults
.
- подключите
no-arg
библиотеку к commonMain модулю:implementation("com.russhwolf:multiplatform-settings-no-arg:1.3.0")
- создайте
settings
, сохраните значение, а затем прочитайте - протестируйте на обеих платформах
Подключение напрямую к платформе
Нам необходимо подключить библиотеку как api
, чтобы ее классы были доступны за пределами общего модуля. Подробнее о разнице между api
и implementation
можете почитать здесь.
Добавьте подключение библиотеки к общему модулю:
commonMain {
dependencies {
// ...
api("com.russhwolf:multiplatform-settings:1.3.0")
}
}
Убедитесь, что класс SharedPreferencesSettings
стал доступен в Android-проекте.
Однако, этого не достаточно, чтобы библиотека стала доступна и на iOS. Чтобы это сделать, необходимо добавить классы библиотеки в header iOS фреймворка, чтобы они стали видны из swift.
По умолчанию, для api
-зависимостей этого не происходит, потому что тогда бы бинарник фреймворка был бы огромный (кому интересно, почитайте об этом тут).
Но, при желании, добавить классы в хидер можно, для этого добавьте следующие строчки в раздел cocoapods/framework
в shared/build.gradle
файле:
export("com.russhwolf:multiplatform-settings:1.3.0")
Как должно получиться:
cocoapods {
summary = "Some description for the Shared Module"
homepage = "Link to the Shared Module homepage"
ios.deploymentTarget = "14.1"
podfile = project.file("../iosApp/Podfile")
framework {
baseName = "shared"
export("com.russhwolf:multiplatform-settings:1.3.0")
}
}
Более подробно о настройке фреймворка вы можете прочитать тут.
Наконец, выполните команду pod install
и классы библиотеки mutliplatform-settings станут доступны на iOS, попробуйте создать NSUserDefaultsSettings
.
KeyValueStorage
В работе мы делегируем работу с хранилищем устройства классу KeyValueStorage
.
Это позволяет нам:
- Не создавать константу-ключ для каждой переменной в хранилище
- Не беспокоиться о том, что в переменной окажется что-то не то, потому что мы задали тип
class KeyValueStorage(settings: Settings) {
var platformName: String? by settings.nullableString("platform_name_key")
var language: String? by settings.nullableString("language_key")
}
Практическое задание
- Откройте проект, который вы изменяли в разделе expect/actual или создайте новый по инструкции
- Подключите multiplatform-settings, используя no-arg модуль библиотеки, убедитесь, что все работает
- Подключите multiplatform-settings напрямую к платформам, убедитесь, что все работает
- Подключите multiplatform-settings, используя expect/actual, убедитесь, что все работает
- Сохраните название платформы в хранилище устройства в общем коде
- Для iOS и Android выведите на экран значение, которое сохранили в общем коде используя библиотеку