@composable 调用只能在 @composable 函数的上下文中发生,同时解决缺乏对 moko:biometry-compose 的桌面支持的问题

问题描述 投票:0回答:1

我正在尝试解决 dev.icerock.moko:biometry-compose 缺乏桌面支持的问题,我无法编译桌面版本,而该库是 commonMain 的一部分。这个想法是将库下推到 Android 和 Native (ios)。我尝试了期望/实际和界面选项。但我在这两种情况下都遇到了这个问题。 “@composable 调用只能在 @composable 函数的上下文中发生”。有什么想法吗?

interface BiometryAuthenticator {
    suspend fun checkBiometryAuthentication(
        requestTitle: String,
        requestReason: String,
        failureButtonText: String,
        allowDeviceCredentials: Boolean
    ): Boolean
}

expect class BiometryAuthenticatorFactory() {
    @Composable
    fun createBiometryAuthenticator(): BiometryAuthenticator
}

// AndroidBiometryAuthenticatorFactory.kt (androidMain)
package domain

import androidx.compose.runtime.Composable
import dev.icerock.moko.biometry.compose.rememberBiometryAuthenticatorFactory
import dev.icerock.moko.resources.desc.Raw
import dev.icerock.moko.resources.desc.StringDesc
import dev.icerock.moko.biometry.BiometryAuthenticator as MokoBiometryAuthenticator

actual class BiometryAuthenticatorFactory {

    @Composable
    actual fun createBiometryAuthenticator(): BiometryAuthenticator {
        val factory = rememberBiometryAuthenticatorFactory()
        return MokoBiometryAuthenticatorWrapper(factory.createBiometryAuthenticator())
    }

    private class MokoBiometryAuthenticatorWrapper(
        private val authenticator: MokoBiometryAuthenticator
    ) : BiometryAuthenticator {
        override suspend fun checkBiometryAuthentication(
            requestTitle: String,
            requestReason: String,
            failureButtonText: String,
            allowDeviceCredentials: Boolean
        ): Boolean {
            return authenticator.checkBiometryAuthentication(
                requestTitle = StringDesc.Raw(requestTitle),
                requestReason = StringDesc.Raw(requestReason),
                failureButtonText = StringDesc.Raw(failureButtonText),
                allowDeviceCredentials = allowDeviceCredentials
            )
        }
    }
}

  @Composable
  fun LoginScreen() {
    val viewModel = getViewModel(
            key = "biometry-screen",
            factory = viewModelFactory {
                AuthViewModel(                  
                    biometryAuthenticatorFactory.createBiometryAuthenticator() <-- It breaks here 
                )
            }
        ) {
    Column() {
            BindBiometryAuthenticatorEffect(viewModel.biometryAuthenticator) <-- and here....
    }
kotlin android-jetpack-compose kotlin-multiplatform jetbrains-compose
1个回答
0
投票

您可以将

createBiometryAuthenticator
移动到
viewModelFactory
之外:

val biometryAuthenticator = biometryAuthenticatorFactory.createBiometryAuthenticator()

val viewModel = getViewModel(
    key = "biometry-screen",
    factory = viewModelFactory {
        AuthViewModel(                  
            biometryAuthenticator
        )
    }
) {

为了使其更像组合,我建议您将该方法重命名为

rememberBiometryAuthenticator
,并实际记住该值 - 否则将在每次重新组合时创建该对象,并且这并不是什么期望,因为工厂不会使用新价值。

@Composable
actual fun rememberBiometryAuthenticator(): BiometryAuthenticator {
    val factory = rememberBiometryAuthenticatorFactory()
    return remember { MokoBiometryAuthenticatorWrapper(factory.createBiometryAuthenticator()) }
}
© www.soinside.com 2019 - 2024. All rights reserved.