Closed tgyuuAn closed 7 months ago
-> ์ฌ์ฉ๋ฒ ๋งค์ฐ ๊ฐ๋จ -> ๋ฐ์ดํฐ์ ๊ธฐ๋ณธ ๊ฐ์ ์ค์ ํด์ค ์ ์์. -> null๊ฐ์ ๋ฐ์ดํฐ๊ฐ ์ฌ ๊ฒฝ์ฐ ์๋น์ค ์ฐ์ฐ์ ?: ์ ์ด์ฉํด์ ๊ธฐ๋ณธ ๊ฐ์ ์ค ์ ์๊ธด ํ์ง๋ง ๋ณด์ผ๋ฌ ํ๋ ์ดํธ ๋ฐ์.
?:
-> ๊ธฐ๋ณธ๊ฐ์ ํ ๋นํด์ค ์ ์์.
key=value&key=value
java.lang.IllegalArgumentException: Unable to create @Body converter for class com.tgyuu.network.model.consulting.AiChatRequest (parameter #1) for method OpenAiApi.postChatMessage
@Body
Response๋ Request DTO ์์ @Serilizaion ์ด๋ ธํ ์ด์ ์์ @Suppress("PLUGIN_IS_NOT_ENABLED") ์๋ฌ๊ฐ ๋๋๊ฒ ์์ํ์.
@Serilizaion
@Suppress("PLUGIN_IS_NOT_ENABLED")
์ฐพ์๋ณด๋ kotlin serialization์ ์ฌ์ฉํ๊ธฐ ์ํด์๋,
kotlin serialization
์ฌ์ฉํ๋ ค๋ ๋ชจ๋์ plugin{} ์ kotlin("plugin.serialization") version "1.9.23" ์ ์ถ๊ฐํ์ด์ผ ํ์.
plugin{}
kotlin("plugin.serialization") version "1.9.23"
์ฌ๊ธฐ์ ๊ทธ๋ผ, plugin์ importํ ๋ ๋ค์ ํญ์ ๋ถ๋ apply false๋ฅผ ๋ถ์ด์ง ์๋ ์ด์ ๊ฐ ๊ถ๊ธํ์.
์... ๊ทธ๋ ๋ค๊ณ ํ๋ค...! ํํ...
MutableLIst<T> ์ ๊ฐ์ด mutableํ ๊ฐ์ฒด๋ฅผ ์ด์ฉํ์ฌ ๊ฐ์ add ์ํค๋ฉด compose๋ ์ด์ ๊ฐ ๋ณํ๋ฅผ ์ธ์งํ์ง ๋ชปํ๊ณ Recomposition์ ์ ๋ฐํ์ง ์๋๋ค.
MutableLIst<T>
ํ์ฌ OpenAi Api๋ฅผ ํธ์ถํจ์ผ๋ก์จ ์๋ต๋๋ AI์๋ต ๋ต๋ณ์ ๊ณ์ํด์ mutableList<T>์ ์ ์ฅํด์ผํ๊ณ ,
mutableList<T>
์ด๋ฅผ ๊ณ์ LazyColumn ์ด ๋ฐ์๋จน์ผ๋ฉด์ ์๋์ผ๋ก ๊ทธ๋ ค์ง๋ ์ด์์ ์ธ ๋ชจ์ต์ ์ํ๋ค.
LazyColumn
ํ์ง๋ง, ViewModel์์ StateFlow<MutableList<T>>๋ฅผ ์ฌ์ฉํ ๋์๋, ๋ฐ์ดํฐ๋ ์ ๋ ๋ค์ด๊ฐ์ง๋ง
StateFlow<MutableList<T>>
๋ณ๋๋ก ๋ฆฌ์ปดํฌ์ง์ ์ ์ผ์ผํค๋ ํ์๋ฅผ ์ถ๊ฐ์ ์ผ๋ก ํด์ผ์ง๋ง ๋งํ์ ์ด ์ ๋ฐ์ดํธ๊ฐ ๋์๋ค.
mutableํ ๊ฐ์ฒด๋ฅผ immutableํ๊ฒ ๋ง๋ค๋ฉด ๋๋ค.
์๋ฅผ ๋ค์ด,
// BAD @Composable fun NamesList() { val names by remember { mutableStateOf(mutableListOf<String>()) } LazyColumn { item { Button(onClick = { names.add("Hans") }) { Text(text = "Add name") } } items(names) { name -> Text(name) } } }
์ด๋ผ๋ ์ฝ๋๋
// GOOD @Composable fun NamesList() { var names by remember { mutableStateOf(listOf<String>()) } LazyColumn { item { Button(onClick = { names = names + "Hans" }) { Text(text = "Add name") } } items(names) { name -> Text(name) } } }
๋ก MutableList + add() ์์ List ์ผ๋ก ์นํํด์ ์ฌ์ฉํ ์ ์๋ค.
MutableList
add()
List
ํ์ง๋ง ๋ ์ข์ ๋ฐฉ์์ด ์๋๋ฐ,
๊ทธ๊ฒ์ ๊ณต์๋ฌธ์ ์ฝ๋๋ฉ์์ ์๊ฐํ๋ mutableStateList๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
mutableStateList
mutableStateList๋ ๊ด์ฐฐ๊ฐ๋ฅํ MutableList์ ์ญํ ์ ํด์ฃผ๋ ๋์ด์ฐํ ์์ด์ด๋ค.
1 ์ด์ ์ฑํ ์ ํ ์คํธ ์ฌ์ด์ฆ๋ฅผ ์ ์ฅํด๋
2. ์๋ก์ด ์ฑํ ์ด ๋ค์ด์์ ๋, ํ์ฌ ์ฌ์ด์ฆ์ ๋ค๋ฅผ๊ฒฝ์ฐ, ๋ง์ง๋ง ์์ดํ ์ ์ธ๋ฑ์ค๋ก ์คํฌ๋กค ํจ.
val listState = rememberLazyListState() var previousChatSize by remember { mutableStateOf(1) } val coroutineScope = rememberCoroutineScope()
LaunchedEffect(chatLog) { if (previousChatSize != chatLog.size) { coroutineScope.launch { listState.animateScrollToItem(chatLog.size - 1) } previousChatSize = chatLog.size } }
LazyColumn( state = listState, verticalArrangement = Arrangement.spacedBy(20.dp), contentPadding = PaddingValues(horizontal = 25.dp), modifier = Modifier .fillMaxSize() .padding(top = topBarHeight, bottom = textFieldHeight), ) {
1. ๐ ๊ด๋ จ๋ ์ด์ ๋ฐ ์๊ฐ
2. ๐ฅ๋ณ๊ฒฝ๋ ์
3. ๐ธ ์คํฌ๋ฆฐ์ท(์ ํ)
4. ๐ก์๊ฒ๋ ํน์ ๊ถ๊ธํ ์ฌํญ๋ค
1. Retrofit2๋ฅผ ์ฌ์ฉํ ๋, GsonConverter vs kotlin Serealization ์ฐจ์ด
GsonConverter
-> ์ฌ์ฉ๋ฒ ๋งค์ฐ ๊ฐ๋จ -> ๋ฐ์ดํฐ์ ๊ธฐ๋ณธ ๊ฐ์ ์ค์ ํด์ค ์ ์์. -> null๊ฐ์ ๋ฐ์ดํฐ๊ฐ ์ฌ ๊ฒฝ์ฐ ์๋น์ค ์ฐ์ฐ์
?:
์ ์ด์ฉํด์ ๊ธฐ๋ณธ ๊ฐ์ ์ค ์ ์๊ธด ํ์ง๋ง ๋ณด์ผ๋ฌ ํ๋ ์ดํธ ๋ฐ์.Kotlinx.Sereilization
-> ๊ธฐ๋ณธ๊ฐ์ ํ ๋นํด์ค ์ ์์.
2. Retrofit2๋ฅผ ์ฌ์ฉํ ๋, @FIELD, @BODY ์ฐจ์ด
@Field
key=value&key=value
์ ๊ฐ์ ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํจ.@Body
3. Retrofit2 Converter๊ฐ ๋์ํ์ง ์๋ ์๋ฌ ๋ฐ์
java.lang.IllegalArgumentException: Unable to create @Body converter for class com.tgyuu.network.model.consulting.AiChatRequest (parameter #1) for method OpenAiApi.postChatMessage
@Body
๋ถ๋ถ์ด ์ง๋ ฌํ๊ฐ ์๋๊ณ ์๋ ๊ฒ ๊ฐ์.๋๋ฒ๊น
Response๋ Request DTO ์์
@Serilizaion
์ด๋ ธํ ์ด์ ์์@Suppress("PLUGIN_IS_NOT_ENABLED")
์๋ฌ๊ฐ ๋๋๊ฒ ์์ํ์.์ฐพ์๋ณด๋
kotlin serialization
์ ์ฌ์ฉํ๊ธฐ ์ํด์๋,์ฌ์ฉํ๋ ค๋ ๋ชจ๋์
plugin{}
์kotlin("plugin.serialization") version "1.9.23"
์ ์ถ๊ฐํ์ด์ผ ํ์.์ฌ๊ธฐ์ ๊ทธ๋ผ, plugin์ importํ ๋ ๋ค์ ํญ์ ๋ถ๋ apply false๋ฅผ ๋ถ์ด์ง ์๋ ์ด์ ๊ฐ ๊ถ๊ธํ์.
์... ๊ทธ๋ ๋ค๊ณ ํ๋ค...! ํํ...
4. StateFlow<MutableList>๋ฅผ ์ฌ์ฉํ๋ฉด Compose๊ฐ ๋ณํ๋ฅผ ์ธ์งํ์ง ๋ชปํด์.
MutableLIst<T>
์ ๊ฐ์ด mutableํ ๊ฐ์ฒด๋ฅผ ์ด์ฉํ์ฌ ๊ฐ์ add ์ํค๋ฉด compose๋ ์ด์ ๊ฐ ๋ณํ๋ฅผ ์ธ์งํ์ง ๋ชปํ๊ณ Recomposition์ ์ ๋ฐํ์ง ์๋๋ค.ํ์ฌ OpenAi Api๋ฅผ ํธ์ถํจ์ผ๋ก์จ ์๋ต๋๋ AI์๋ต ๋ต๋ณ์ ๊ณ์ํด์
mutableList<T>
์ ์ ์ฅํด์ผํ๊ณ ,์ด๋ฅผ ๊ณ์
LazyColumn
์ด ๋ฐ์๋จน์ผ๋ฉด์ ์๋์ผ๋ก ๊ทธ๋ ค์ง๋ ์ด์์ ์ธ ๋ชจ์ต์ ์ํ๋ค.ํ์ง๋ง, ViewModel์์
StateFlow<MutableList<T>>
๋ฅผ ์ฌ์ฉํ ๋์๋, ๋ฐ์ดํฐ๋ ์ ๋ ๋ค์ด๊ฐ์ง๋ง๋ณ๋๋ก ๋ฆฌ์ปดํฌ์ง์ ์ ์ผ์ผํค๋ ํ์๋ฅผ ์ถ๊ฐ์ ์ผ๋ก ํด์ผ์ง๋ง ๋งํ์ ์ด ์ ๋ฐ์ดํธ๊ฐ ๋์๋ค.
๋๋ฒ๊น
mutableํ ๊ฐ์ฒด๋ฅผ immutableํ๊ฒ ๋ง๋ค๋ฉด ๋๋ค.
์๋ฅผ ๋ค์ด,
์ด๋ผ๋ ์ฝ๋๋
๋ก
MutableList
+add()
์์List
์ผ๋ก ์นํํด์ ์ฌ์ฉํ ์ ์๋ค.ํ์ง๋ง ๋ ์ข์ ๋ฐฉ์์ด ์๋๋ฐ,
๊ทธ๊ฒ์ ๊ณต์๋ฌธ์ ์ฝ๋๋ฉ์์ ์๊ฐํ๋
mutableStateList
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.mutableStateList
๋ ๊ด์ฐฐ๊ฐ๋ฅํ MutableList์ ์ญํ ์ ํด์ฃผ๋ ๋์ด์ฐํ ์์ด์ด๋ค.5. LazyColumn ๋ง์ง๋ง item์ผ๋ก ์คํฌ๋กค ํ๋ ๋ฐฉ๋ฒ
1 ์ด์ ์ฑํ ์ ํ ์คํธ ์ฌ์ด์ฆ๋ฅผ ์ ์ฅํด๋
2. ์๋ก์ด ์ฑํ ์ด ๋ค์ด์์ ๋, ํ์ฌ ์ฌ์ด์ฆ์ ๋ค๋ฅผ๊ฒฝ์ฐ, ๋ง์ง๋ง ์์ดํ ์ ์ธ๋ฑ์ค๋ก ์คํฌ๋กค ํจ.