我正在尝试解决 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....
}
您可以将
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()) }
}