第 18 课2026.08.03
iOS 端需要为同一个 PreferenceStorage 接口提供实现。共享 LanguageRepository 因此可以保持不变,同时在 iPhone 和 iOS 模拟器上使用系统偏好存储。
第 18 课:实现 iOS 偏好存储
- 日期:2026-08-03
- 课程序号:18
- 知识点:在
iosMain中用NSUserDefaults实现共享接口
用途
iOS 端需要为同一个 PreferenceStorage 接口提供实现。共享 LanguageRepository 因此可以保持不变,同时在 iPhone 和 iOS 模拟器上使用系统偏好存储。
核心概念
- Kotlin/Native 可以在
iosMain直接调用 Foundation API。 NSUserDefaults.standardUserDefaults提供应用的标准偏好存储。stringForKey()在键不存在或不能转换成字符串时返回null。setObject()写入字符串,removeObjectForKey()删除对应值。- iOS 实现仍通过组合根注入共享 Repository,不在 UI 中直接读写键名。
示例代码
iosMain/IosPreferenceStorage.kt:
kotlin
import platform.Foundation.NSUserDefaults
class IosPreferenceStorage(
private val defaults: NSUserDefaults =
NSUserDefaults.standardUserDefaults,
) : PreferenceStorage {
override fun putString(key: String, value: String) {
defaults.setObject(value, forKey = key)
}
override fun getString(key: String): String? {
return defaults.stringForKey(key)
}
override fun remove(key: String) {
defaults.removeObjectForKey(key)
}
}在 iOS 侧的共享组合入口中组装:
kotlin
fun createIosLanguageRepository(): LanguageRepository {
return LanguageRepository(
storage = IosPreferenceStorage(),
)
}使用方式与 Android 相同:
kotlin
val repository = createIosLanguageRepository()
repository.saveLanguage("zh-CN")
println(repository.loadLanguage()) // zh-CN5 分钟练习
调用上一课实现的 clearLanguage(),再读取语言偏好,并写出预期结果。
参考答案
kotlin
val repository = createIosLanguageRepository()
repository.saveLanguage("zh-CN")
repository.clearLanguage()
val language = repository.loadLanguage()
println(language) // null删除后 NSUserDefaults.stringForKey() 返回 null,与 PreferenceStorage 的共享契约一致。
与上一课的联系
上一课使用 Android SharedPreferences 实现接口;本课使用 iOS NSUserDefaults 实现同一接口。至此,共享业务、测试 Fake、Android 和 iOS 四个调用方都遵守同一份存储契约。