Android

Preference Datastore

chattymin 2024. 4. 25. 03:59
728x90
반응형

언제 쓸까?

로그인 세부 정보 저장, 다크모드 설정, 글꼴 크기 등 작고 간단한 데이터 세트에 적합

대용량 or 복잡한 데이터 → Room을 쓰자.

 

 

Jetpack DataStore 라이브러리 → 데이터 저장을 위한 간단하고 안전한 비동기

  • Preference DataStore : key-value로 저장
  • Proto DataStore : 프로토콜 버퍼를 사용하여 스키마 정의 → Strong Type 데이터 유지 가능

Proto DataStore는 type safety, 효율적이지만 구성과 설정이 필요함

Preference DataStore는 쉽게 설정 가능

 

 

필수 추가 종속성

implementation("androidx.datastore:datastore-preferences:1.0.0")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.3.1")

 

 

Preference Datastore 설정 방법

@ActivityRetainedScoped
class LocalUserDataStore @Inject constructor(
    private val localDataStore: DataStore<Preferences>,
) {
    private object Keys {
        val id = stringPreferencesKey(ID_KEY)
        val password = stringPreferencesKey(PASSWORD_KEY)
        val nickname = stringPreferencesKey(NICKNAME_KEY)
    }

    val userInfo: Flow<UserInfo> = localDataStore.data
        .catch {
            if (it is IOException) {
                emit(emptyPreferences())
            } else {
                throw it
            }
        }
        .map { preferences ->
            UserInfo(
                id = preferences[Keys.id].orEmpty(),
                password = preferences[Keys.password].orEmpty(),
                nickname = preferences[Keys.nickname].orEmpty(),
            )
        }
        .distinctUntilChanged()

    suspend fun setUserInfo(userInfo: UserInfo) {
        localDataStore.edit { preferences ->
            preferences[Keys.id] = userInfo.id
            preferences[Keys.password] = userInfo.password
            preferences[Keys.nickname] = userInfo.nickname
        }
    }

    companion object {
        const val ID_KEY = "id_key"
        const val PASSWORD_KEY = "pw_key"
        const val NICKNAME_KEY = "nickname_key"
    }
}

DataStore 객체 밖에서 선언하여 싱글톤으로 관리

나는 SSA설계를 위해 ActivityRetainedScoped를 사용했지만, 싱글톤을 적용해주는게 일반적인 상황에선 더 좋을 것 같다

 

@ActivityRetainedScoped를 사용하여 액티비티의 생명주기를 따라가도록 설정

  • @ActivityRetainedScoped : Activity의 onCreate()와 onDestory()를 그대로 따라감
  • @ActivityScoped : Configuration Change에 영향을 받지 않음 ex) 화면 회전…

 

 

Preference Datastore에 값을 저장하는 방법

suspend fun setUserInfo(userInfo: UserInfo) {
    context.localDataStore.edit { preferences ->
        preferences[Keys.id] = userInfo.id
        preferences[Keys.password] = userInfo.password
        preferences[Keys.nickname] = userInfo.nickname
    }
}

 

 

Preference Datastore에서 값을 가져오는 방법

val userInfo: Flow<UserInfo> = context.localDataStore.data
        .catch {
            if (it is IOException) {
                emit(emptyPreferences())
            } else {
                throw it
            }
        }
        .map { preferences ->
            UserInfo(
                id = preferences[Keys.id].orEmpty(),
                password = preferences[Keys.password].orEmpty(),
                nickname = preferences[Keys.nickname].orEmpty(),
            )
        }
        .distinctUntilChanged()

 

728x90
반응형