对不起,我的英语不好 :(
我想用 KMM 创建应用程序,并最大化共享代码。只有我想写两次的是 UI 和导航。所以我在共享代码中创建 ViewModel。
open class ViewModel<T>(initialState: T) where T : ViewState {
private val _state = MutableStateFlow(initialState)
val currentState: T
get() = stateFlow.value
val stateFlow: StateFlow<T> = _state
fun updateState(
context: CoroutineContext = EmptyCoroutineContext,
mapping: (currentState: T) -> T
) { GlobalScope.launch(context) { _state.emit(mapping(_state.value)) } }
}
ViewState 就在哪里
interface ViewState
用于在密封类中实现,描述当前视图状态。当它发生变化时,用户界面会收到变化和更新。状态看起来像(我发现的第一个免费公共 API 返回随机狗图像):
sealed class DogImageViewState : ViewState {
object Loading : DogImageViewState()
data class Content(val image: String) : DogImageViewState()
}
好的
所以我创建了具体的 ViewModel 来在 iOS 和 android 之间共享逻辑
class DogImageViewModel(initialState: DogImageViewState) : ViewModel<DogImageViewState>(initialState) {
private val interactor : GetDogImageUrlInteractor by dogDi.instance()
init {
getImage()
}
fun reload() {
updateState { DogImageViewState.Loading }
getImage()
}
private fun getImage() {
GlobalScope.launch(ioDispatcher) {
val image = interactor.getImageUrl()
updateState { (it as? Content)?.copy(image = image) ?: Content(image = image) }
}
}
}
简单,尼特?Viewmodel 使用 Loading 进行初始化,并立即开始图像加载。图像加载后进入新状态。在刷新操作上完全相同
在Android中使用很简单,jetpack compose 可以collectAsState
StateFlow,没有什么可做的,只用state来描述一个ui
问题出在 iOS
我们必须为 iOS“桥接”可观察模型。iOS 有ObservableObject
机制,我已经扩展了它
class ObservableViewModel<T : ViewState>: ObservableObject {
@Published var state : T
init(viewModel: ViewModel<T>) {
self.state = viewModel.currentState
viewModel.onChange { newState in
self.state = newState as! T
}
}
}
看起来不错。ViewState 的通用类...现在我可以将它与 SwiftUI 一起使用!不好了...
当我尝试ObservableViewModel
在代码中使用时,我收到一个错误
@StateObject var vm = ObservableViewModel<DogImageViewState>(viewModel: DogImageViewModel(initialState: DogImageViewState.Loading()))
类型“DogImageViewState”不符合协议“ViewState”
但它完全符合!
当我跳到定义时,DogImageViewState
我会看到下一个
__attribute__((swift_name("DogImageViewState")))
@interface DogDogImageViewState : DogBase <DogSharedViewState>
@end;
看起来完全不符合。什么是Base<ViewState>
(DogBase 因为 Dog 功能构建在单独的框架中dog
,而 DogSharedViewState 因为 ViewState 中声明shared
)?为什么不只是ViewState
?
如何解释 swift 和 DogSharedViewState 完全一样?