๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿค2024 ์•ˆ๋“œ๋กœ์ด๋“œ/๊ธฐ์ˆ™์‚ฌ ํ”„๋กœ์ ํŠธ ๊ธฐ๋ก

compose์™€ preferences datastore ์ด์šฉํ•˜๊ธฐ

by hyeonha 2024. 1. 18.

๋ชฉ์ฐจ

    ๋„์ž… ๋ฐฐ๊ฒฝ 

    ํ”„๋กœ์ ํŠธ์—์„œ ์„ธํƒ์นด๋“œ์— ์ถฉ์ „ํ•œ ๊ธˆ์•ก์„ ์ž…๋ ฅํ•˜๋ฉด  ์•ž์œผ๋กœ ๋‚จ์€ ์„ธํƒ ํšŸ์ˆ˜์™€ ๋‚จ์€ ์ž”์•ก์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋Š” ํ™”๋ฉด์„ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋‹ค.

    ์ด ๋•Œ ๊ฐ ์‚ฌ์šฉ์ž์˜ ์ž”์•ก์„ ๋กœ์ปฌ db์— ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ์›๋ž˜ ๋กœ์ปฌ db๋กœ์„œ ์ผ๋ฐ˜์ ์œผ๋กœ ์•Œ๊ณ  ์žˆ๋˜ shared prefereces๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ž๋ฃŒ๋ฅผ ์ฐพ์•„๋ณด๋˜ ์ค‘!  preferences datastore์™€ proto datastore์ด๋ผ๋Š” ๋ฐ์ดํ„ฐ ์ €์žฅ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค๋Š” ๊ฒƒ๊ณผ

    ์ด ๋ฐฉ๋ฒ•์ด shared preferences์˜ ๋‹จ์ ์„ ๊ทน๋ณตํ•˜๊ธฐ ์œ„ํ•ด ๋‚˜์™”๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค. 

     

    ๋”ฐ๋ผ์„œ shared preferences๋ฅผ ๋ณด์™„ํ•œ preferences datastore์„ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค.

     

     

    ๊ฐœ๋… ์ดํ•ดํ•˜๊ธฐ

    datastore์€ ๊ฐœ์„ ๋œ ์‹ ๊ทœ ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ ์†”๋ฃจ์…˜์œผ๋กœ ์šฐ๋ฆฌ๊ฐ€ ์•Œ๊ณ  ์žˆ๋Š” shared preferences๋ฅผ ๋Œ€์ฒดํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค!!

    kotlin ์ฝ”๋ฃจํ‹ด๊ณผ Flow๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜์—ฌ ๋‘ ๊ฐ€์ง€ ์ข…๋ฅ˜๊ฐ€ ์กด์žฌํ•˜๋Š”๋ฐ ์ฒซ ๋ฒˆ์งธ๋Š” ํƒ€์ž… ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•˜๋Š” proto datastore์ด๊ณ , ๋‘๋ฒˆ์งธ๋Š” ํ‚ค-๊ฐ’ ์Œ์„ ์ €์žฅํ•˜๋Š” preferences datastore์ด๋‹ค. 

     

    ์‚ฌ์šฉํ•˜๋ ค๋Š” preferences datastore์€ ๋กœ๊ทธ์ธ ์„ธ๋ถ€ ์ •๋ณด ์ €์žฅ์ด๋‚˜ ์–ด๋‘์šด ๋ชจ๋“œ ์„ค์ •, ๊ธ€๊ผด ํฌ๊ธฐ ๋“ฑ ์ž‘๊ณ  ๊ฐ„๋‹จํ•œ ๋ฐ์ดํ„ฐ ์„ธํŠธ์— ์ ํ•ฉํ•˜๋‹ค. Datastore๋Š” ์˜จ๋ผ์ธ ์‹๋ฃŒํ’ˆ์  ์ธ๋ฒคํ† ๋ฆฌ ๋ชฉ๋ก์ด๋‚˜ ํ•™์ƒ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์™€ ๊ฐ™์€ ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ์„ธํŠธ์—๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š๋‹ค. ๋Œ€์šฉ๋Ÿ‰ ๋˜๋Š” ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ์„ธํŠธ๋ฅผ ์ €์žฅํ•ด์•ผํ•œ๋‹ค๋ฉด Datastore ๋Œ€์‹  room ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•˜๊ณ  ์žˆ๋‹ค

     

    ๋‚ด๊ฐ€ ์ €์žฅํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ๋‚จ์€ ๊ธˆ์•ก์œผ๋กœ ๊ฐ„๋‹จํ•œ ๋ฐ์ดํ„ฐ์ด๋‹ค. ๋”ฐ๋ผ์„œ datastore ์ค‘ preference datastore๊ฐ€ ๋” ์ ํ•ฉํ•œ ๋ฐฉ์‹์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

     

    ๋กœ์ง ์ดํ•ดํ•˜๊ธฐ

     

    [ ๋กœ์ง ]

    ์‚ฌ์šฉ์ž๊ฐ€ ์„ธํƒ ์นด๋“œ์— ์ถฉ์ „ํ•œ ๊ธˆ์•ก์„ ๊ธฐ๋กํ•˜๋ฉด ํ™”๋ฉด์— ๋‚จ์€ ๊ธˆ์•ก์— ์ถฉ์ „ํ•œ ๊ธˆ์•ก์ด ํ•ฉํ•ด์ง„ ๊ธˆ์•ก์ด ๋ณด์—ฌ์ง„๋‹ค.

    ์ด ๋•Œ ๋‚จ์€ ๊ธˆ์•ก์€ ์‚ฌ์šฉ์ž์˜ ๋กœ์ปฌ์— ์ €์žฅ๋˜์–ด์„œ ์•ฑ์„ ๋„๊ณ  ๋‹ค์‹œ ์‹คํ–‰ํ•ด๋„ ๋‚จ์•„์žˆ์–ด์•ผํ•œ๋‹ค.

     

    ์„ธํƒ์นด๋“œ์— ๋‚จ์€ ๊ธˆ์•ก์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ๋ทฐ๋ชจ๋ธ๊ณผ preferences datastore์„ ์ด์šฉํ•ด๋ณด์•˜๋‹ค.

     

    [์ˆœ์„œ]

    1. Datastore ๋งŒ๋“ค๊ธฐ

    2. PreferencesKeys ์ •์˜

    3. ์ถฉ์ „ ๊ธˆ์•ก์— ๋Œ€ํ•œ Flow ์ƒ์„ฑ

    4. ์ถฉ์ „ ๊ธˆ์•ก ์ €์žฅ 

    5. ViewModel์—์„œ ์ถฉ์ „ ๊ธˆ์•ก ์—…๋ฐ์ดํŠธ

     

    1.Preferences Datastore ๋งŒ๋“ค๊ธฐ

    // Datestore ๋งŒ๋“ค๊ธฐ
    private const val PREFERENCES_NAME = "user_preferences"
    
    // Create a DataStore instance using the preferencesDataStore delegate, with the Context as
    // receiver.
    
    val Context.dataStore : DataStore<Preferences> by preferencesDataStore(name = PREFERENCES_NAME)

     

    "user_preferences" ๋Š” ์ธ์Šคํ„ด์Šคํ™”ํ•  preferences datastore์˜ ์ด๋ฆ„์ด๋‹ค. 

    preferencesDataStore ์œ„์ž„์„ ์‚ฌ์šฉํ•˜์—ฌ  "user_preferences" ๋ผ๋Š” ์ด๋ฆ„์˜ DataStore ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ ๋‹ค.

    Context๋Š” receiver ์—ญํ• ์ด๋ผ๊ณ  ํ•œ๋‹ค! 

     

    kotlin ํŒŒ์ผ์˜ ์ตœ์ƒ์œ„ ์ˆ˜์ค€์—์„œ DataStore ์ธ์Šคํ„ด์Šค๋ฅผ ํ•œ๋ฒˆ ๋งŒ๋“ค๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์—์„œ ์ด ์†์„ฑ์„ ํ†ตํ•ด ์ธ์Šคํ„ด์Šค์— ์•ก์„ธ์Šคํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค๊ณ  ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด DataStore์„ ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

     

    DataStore ์ธ์Šคํ„ด์Šค๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ ๋งŒ๋“ค์–ด์งˆ ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์‹ฑ๊ธ€ํ†ค์„ ์‚ฌ์šฉํ•œ๋‹ค

     

    2. PreferencesKeys ์ •์˜

    private object PreferencesKeys {
        val CHARGED_MONEY = intPreferencesKey("charged_money")
    }

     

    intPreferencesKey๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ "charged_money" ๋ผ๋Š” ํ‚ค๋ฅผ ์ •์˜ํ•œ๋‹ค. ์ด ํ‚ค๋Š” ๋ฐ์ดํ„ฐ ์Šคํ† ์–ด์—์„œ ์ •์ˆ˜๊ฐ’์„ ์ €์žฅํ•˜๊ณ  ๊ฒ€์ƒ‰ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. 

     

    preferences datastore์€ ์‚ฌ์ „ ์ •์˜๋œ ์Šคํ‚ค๋งˆ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.

    DataStore<Preferences> ์ธ์Šคํ„ด์Šค์— ์ €์žฅํ•ด์•ผํ•˜๋Š” ๊ฐ ๊ฐ’์˜ ํ‚ค๋ฅผ ์ •์˜ํ•˜๋ ค๋ฉด ๊ฑฐ๊ธฐ์— ๋งž๋Š” ํ‚ค ์œ ํ˜• ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค. ๋‚˜๋Š” ๋‚จ์€ ๊ธˆ์•ก์ด๋ผ๋Š” Intํ˜• ๊ฐ’์˜ ํ‚ค๋ฅผ ์ •์˜ํ•˜๊ณ ์ž ํ–ˆ์œผ๋ฏ€๋กœ intPreferenceKey( )๋ฅผ ์‚ฌ์šฉํ•˜์˜€๋‹ค.

     

    ๊ทธ ํ›„ DataStore.data ์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ Flow๋ฅผ ์‚ฌ์šฉํ•œ ์ ์ ˆํ•œ ์ €์žฅ ๊ฐ’์„ ๋…ธ์ถœํ•œ๋‹ค.

     

    3. ์ถฉ์ „ ๊ธˆ์•ก์— ๋Œ€ํ•œ Flow ์ƒ์„ฑ : Preferences Datastore์—์„œ ์ฝ๊ธฐ

    val chargedMoneyFlow: Flow<Int> = dataStore.data
        .catch {
            exception -> if (exception is IOException) {
                emit(emptyPreferences())
        } else{
            throw exception
        }
        }
        .map { preferences ->
            preferences[PreferencesKeys.CHARGED_MONEY] ?: 0 }

     

    dataStore.data ์†์„ฑ์€ datastore์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋น„๋™๊ธฐ์ ์œผ๋กœ ๊ฐ€์ €์˜ค๊ธฐ ์œ„ํ•ด Flow๋ฅผ ์ œ๊ณตํ•ด์ค€๋‹ค.

    ์ด Flow๋ฅผ ํ†ตํ•ด ์•ฑ์˜ ์—ฌ๋Ÿฌ ๋ถ€๋ถ„ ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€์ฐฐํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 

     

    dataStore.data๋Š” datastore์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ Flow์— ๋…ธ์ถœํ•ด์ค€๋‹ค. 

    datasotre ๊ฐ์ฒด๋Š” Preferences DataStore์„ ๋‚˜ํƒ€๋‚ธ๋‹ค.

    .data๋Š” ๋ฐ์ดํ„ฐ์Šคํ† ์–ด์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์†์„ฑ์ด๋‹ค.

     

    * chargedMoneyFlow๋Š” ๋ฐ์ดํ„ฐ ์Šคํ† ์–ด์— ์ €์žฅ๋œ ์ถฉ์ „ ๊ธˆ์•ก ๊ฐ’์„ ๋ฐฉ์ถœํ•˜๋Š” Flow์ด๋‹ค.

    * .catch๋Š” ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ์ž‘์„ฑํ•ด์ฃผ์—ˆ๊ณ , IOException์ด ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ ๋นˆ preference๋ฅผ ๋ฐฉ์ถœํ•œ๋‹ค.

     

    * .map์€

    preferece๋ฅผ ์‹ค์ œ ์ถฉ์ „ ๊ธˆ์•ก ๊ฐ’์œผ๋กœ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค. 

    Flow์˜ ๊ฐ ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. preferences๋Š” Flow์—์„œ ๋ฐ›์•„์˜จ Preferences ๋ฐ์ดํ„ฐ์ด๋‹ค. 

    preferences[PreferencesKeys.CHARGED_MONEY] ?: 0 ์€ CHARGED_MONEY ํ‚ค์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ’์„ ์ฝ์–ด์˜ค๋Š”๋ฐ ์ด ๋•Œ ๊ฐ’์ด null์ด๋ฉด 0์œผ๋กœ ๋Œ€์ฒดํ•ด์ค€๋‹ค. 

     

    ๋”ฐ๋ผ์„œ chargedMoneyFlow๋ฅผ subscribeํ•˜๋ฉด ๋กœ์ปฌ ๋ฐ์ดํ„ฐ ์Šคํ† ์–ด์— ์ €์žฅ๋œ ์ถฉ์ „ ๊ธˆ์•ก์„ ๋น„๋™๊ธฐ์ ์œผ๋กœ ๊ฐ์‹œํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด Flow๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ํ•ด๋‹น ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 

     

    4. ์ถฉ์ „ ๊ธˆ์•ก ์ €์žฅํ•˜๊ธฐ : Prefereces DataStore์— ์“ฐ๊ธฐ

    private suspend fun saveChargedMoney(value: Int) {
        dataStore.edit { preferences ->
            preferences[PreferencesKeys.CHARGED_MONEY] = value
        }
    }

     

    Preferences Datastore์€ Datastore์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํŠธ๋žœ์žญ์…˜ ๋ฐฉ์‹์œผ๋กœ ์—…๋ฐ์ดํŠธํ•˜๋Š” edit ( ) ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

    edit ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ์Šคํ† ์–ด๋ฅผ ์ˆ˜์ •ํ•œ๋‹ค. 

     

    ํŠธ๋žœ์žญ์…˜ ๋ฐฉ์‹?  

    ๋”๋ณด๊ธฐ

    ํŠธ๋žœ์žญ์…˜ ๋ฐฉ์‹์ด๋ž€ 

     

    ์—ฌ๋Ÿฌ ์—ฐ์‚ฐ์„ ๋ฌถ์–ด์„œ ์ผ๊ด„์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ณ  ์ด ๊ณผ์ •์—์„œ ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•˜๋Š” ๋งค์ปค๋‹ˆ์ฆ˜์„ ์˜๋ฏธํ•œ๋‹ค.

     

    DataStore์˜ edit ํ•จ์ˆ˜์˜ ํŠน์ง• 4๊ฐ€์ง€ 

     

    1. ์›์ž์„ฑ(atomicity) : edit ํ•จ์ˆ˜ ๋‚ด์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ๋ชจ๋“  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์›์ž์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋œ๋‹ค. ์ฆ‰ ๋ชจ๋“  ๋ณ€๊ฒฝ์ด ์„ฑ๊ณตํ•˜๊ฑฐ๋‚˜ ์‹คํŒจํ•˜๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•œ๋‹ค.

    ์˜ˆ๋ฅผ ๋“ค์–ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ key-value ์Œ์„ ๋ณ€๊ฒฝํ•˜๋”๋ผ๋„ ๋ชจ๋“  ๋ณ€๊ฒฝ์ด ์„ฑ๊ณตํ•˜๊ฑฐ๋‚˜ ์•„๋ฌด๊ฒƒ๋„ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์ด๋‹ค.

     

    2. ๋ฐ์ดํ„ฐ ๋ถˆ์ผ์น˜ ๋ฐฉ์ง€  : edit ํ•จ์ˆ˜๋Š” datastore์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ˆ˜์ •ํ•˜๋„๋ก ํ•ด์ค€๋‹ค. ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ ๋˜๋Š” ์ฝ”๋ฃจํ‹ด์ด ๋™์‹œ์— datastore์„ ์ˆ˜์ •ํ•˜๋ ค๊ณ ํ•  ๋•Œ ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๋„๋ก ํ•œ๋‹ค.

     

    3. ๋กค๋ฐฑ  : edit ํ•จ์ˆ˜ ๋‚ด์—์„œ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ ์šฉํ•˜๋Š” ๋„์ค‘์— ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ชจ๋“  ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ๋กค๋ฐฑ๋˜์–ด ์ด์ „ ์ƒํƒœ๋กœ ๋Œ์•„๊ฐ„๋‹ค. ์ด๋Š” ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ  ์˜ค๋ฅ˜ ์ƒํƒœ์—์„œ๋„ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•œ ์ƒํƒœ๋กœ ๋ณต๊ตฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

     

     

    Datastor<Preferences>์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝ๋  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” edit ํ•จ์ˆ˜๋Š” ์•„๋ž˜์™€  ๊ฐ™์ด ์ •์˜๋˜์–ด์žˆ๋‹ค.

    public suspend fun DataStore<Preferences>.edit(
        transform: suspend (MutablePreferences) -> Unit
    ): Preferences {
        return this.updateData {
            // It's safe to return MutablePreferences since we freeze it in
            // PreferencesDataStore.updateData()
            it.toMutablePreferences().apply { transform(this) }
        }
    }

     

    ์ฝ”๋“œ ์„ค๋ช… 

    ๋”๋ณด๊ธฐ

    tranform : suspend (MutablePreferences) -> Unit : ์ด ํ•จ์ˆ˜๋Š” MutablePreferences๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์•„๋“ค์ด๋Š” ๋žŒ๋‹คํ•จ์ˆ˜์ด๋‹ค.

    MutablePreferences๋Š” ์ˆ˜์ • ๊ฐ€๋Šฅํ•œ ํ˜•ํƒœ์˜ Prefereces๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. 

    suspend ํ‚ค์›Œ๋“œ๋Š” ์ด ํ•จ์ˆ˜๊ฐ€ ์ฝ”๋ฃจํ‹ด์œผ๋กœ ๋™์ž‘๊ฐ€๋Šฅํ•จ์„ ์˜๋ฏธ!

     

    ์—ฌ๊ธฐ์„œ tranform ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ํ•„์š”์— ๋”ฐ๋ผ ๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ ๋ธ”๋ก์„ ํ—ˆ์šฉํ•œ๋‹ค. ๋ณ€ํ™˜ ๋ธ”๋ก์˜ ๋ชจ๋“  ์ฝ”๋“œ๋Š” ๋‹จ์ผ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์ทจ๊ธ‰๋œ๋‹ค.

     

    this.updateData ๋ถ€๋ถ„์€ DataStore์—์„œ ์ œ๊ณตํ•œ๋Š ๋‹ค๋ฅธ ํ•จ์ˆ˜์ธ updateData๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ์—…๋ฐ์ดํŠธ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

     

    it.toMutablePreference( ).apply { transform(this) }๋Š” updateDataํ•จ์ˆ˜ ๋‚ด์—์„œ ์ƒˆ๋กœ์šด MutablePrefereces๋ฅผ ๋งŒ๋“ค๊ณ  ์ด๋ฅผ ๋žŒ๋‹ค ํ•จ์ˆ˜ transform์— ์ „๋‹ฌํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค.

     

    return this.updateData {...} ๋Š” ์—…๋ฐ์ดํŠธ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ด๋Š” edit ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ ์ชฝ์—์„œ ์—…๋ฐ์ดํŠธ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค.

     

    ์ •๋ฆฌํ•˜๋ฉด

    ์ด edit ํ•จ์ˆ˜๋Š” DataStor์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•œ ๋žŒ๋‹คํ•จ์ˆ˜ transform์„ ์‚ฌ์šฉํ•˜๊ณ  ์ˆ˜์ •๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

    ์šฐ๋ฆฌ ์ฝ”๋“œ ๋‹ค์‹œ ๋ณด๊ธฐ

        private suspend fun saveChargedMoney(value:Int) {
            dataStore.edit { preferences ->
                preferences[PreferencesKeys.CHARGED_MONEY] = value  }
    
        }

     

    ์šฐ๋ฆฌ์˜ ์ฝ”๋“œ์—์„œ๋Š” dataStore.edit ํ•จ์ˆ˜์˜ ๋žŒ๋‹ค ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” preferences์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ด preferences๊ฐ€ tranform ์—ญํ• ์„ ํ•œ๋‹ค.

    preferences๋Š” MutablePrefereces์˜ ์ธ์Šคํ„ด์Šค๋กœ  ์ˆ˜์ •๊ฐ€๋Šฅํ•œ Preferences๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.

    preferences[PreferencesKeys.CHARGED_MONEY] = value ์ฝ”๋“œ๋Š” MutablePreferences๋ฅผ ํ†ตํ•ด CHARGED_MONEY ํ‚ค์— ๋Œ€ํ•œ ๊ฐ’์„ value๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

     

    5. ViewModel์—์„œ ์ถฉ์ „ ๊ธˆ์•ก ์—…๋ฐ์ดํŠธ

    var chargedMoney by mutableIntStateOf(0)
        private set
    
    fun updateChargedMoney(input: Int) {
        viewModelScope.launch {
            chargedMoney += input
            saveChargedMoney(chargedMoney)
        }
    }

     

    updateChargedMoney ํ•จ์ˆ˜๋Š” input ๋งŒํผ chargeMoney์— ํ•ฉํ•ด์ฃผ์–ด ์—…๋ฐ์ดํŠธ๋ฅผ ํ•ด์ค€ ํ›„ ๋ณ€๊ฒฝ๋œ chargeMoney๋ฅผ ๋ฐ์ดํ„ฐ ์Šคํ† ์–ด์— ๋‹ค์‹œ ์ €์žฅํ•ด์ค€๋‹ค.

     

    ๐Ÿšจ ๋ฌธ์ œ ๋ฐœ์ƒ  : ์•ฑ์ด ๊บผ์ง€๊ณ  ๋‹ค์‹œ ์‹คํ–‰๋  ๊ฒฝ์šฐ ๋˜๋Š” ๋„ค๋น„๊ฒŒ์ด์…˜ ํ›„ ๋‹ค์‹œ ์ถฉ์ „ํ•  ๊ฒฝ์šฐ ๊ธฐ์กด์˜ ๊ธˆ์•ก์— ์ฑ„์šด ๊ธˆ์•ก๋งŒํผ ๋”ํ•ด์ง€์ง€ ์•Š๊ณ   0์œผ๋กœ ์ดˆ๊ธฐํ™”๋˜์–ด์„œ ์ฑ„์šด ๊ธˆ์•ก๋งŒํผ์ด ๋”ํ•ด์ง„๋‹ค. 

     

    ๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ๋Š” ๋ทฐ๋ชจ๋ธ๊ณผ ์œ„ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•œ ๊ณผ์ •์„ ๊ธฐ๋กํ•ด๋ณผ์˜ˆ์ •์ด๋‹ค!

     

    728x90