![](/img/trans.png)
[英]KMM: Unable to generate classes in iOS for the implementation of sealed interfaces inside sub-modules of shared code
[英]KMM - Casting a sealed class/interface in swift not possible
在我的 KMM 庫中,我使用密封的接口/類來表示某些狀態/錯誤。 我決定使用密封接口/類,因為這些狀態必須有不同的關聯對象。
在 Android 代碼中,這也按預期工作,沒有任何問題。
但在 iOS 部分,我無法檢測到具體的 state,因為無法進行轉換。
報錯與是密封接口還是密封class無關,這里舉例:
sealed class SyncState() {
object Loading : SyncState()
data class Active(val syncNumber: String) : SyncState()
data class Error(val throwable: Throwable) : SyncState()
}
在 KMM 庫中的存儲庫中,現在根據 state 返回相應的 SyncState。
fun currentSyncState(): SyncState {
if … {
return SyncState.Error(Throwable("…"))
} else if … {
return SyncState.Active("…")
} else {
return SyncState.Loading
}
}
iOS,我也可以毫無問題的撥打這個function。 唯一的問題是我無法從返回的 object 中分辨出它是哪個 state,因為轉換在任何時候都不起作用。
let state = repo.currentSyncState()
…
(lldb) po state
SyncState.Loading@2fe538
(lldb) po state is SyncState
true
(lldb) po state is SyncState.Loading
false
(lldb) po type(of: state)
SyncStateLoading
(lldb) po state as? SyncState.Loading
nil
let state = repo.currentSyncState()
…
(lldb) po state
Active(syncNumber=syncNumber 123)
(lldb) po state is SyncState
true
(lldb) po state is SyncState.Active
false
(lldb) po type(of: state)
SyncStateActive
(lldb) po state as? SyncState.Active
nil
一個可能的解決方案可能是在 KMM 中為每個 State 添加一個額外的 Type enum case,但這仍然不允許我處理相應 state 的關聯值。
有沒有人遇到過類似的問題並找到了可能的解決方案? 我很感激每一個小建議。
我正在使用 Kotlin 1.6.10 和 Xcode 13.2 和 Swift 5.5.2。
我在https://github.com/icerockdev/moko-kswift使用了一個庫來解決同樣的問題。 它為您提供了自動生成的 swift 枚舉,其構造函數采用從 Kotlin 中的密封 class 生成的 Obj C 類型,並且還映射回 Obj C 類型。
我建議不要使用您從 Swift 生成的密封類。您不會從中得到任何幫助,因為它很尷尬並且沒有詳盡的when
語句。 當你得到密封的 class 時,使用應該執行的回調要容易得多。這里有幾種方法:
sealed class SyncState() {
object Loading : SyncState()
data class Active(val syncNumber: String) : SyncState()
data class Error(val throwable: Throwable) : SyncState()
}
...
class NativeViewModel (
onLoading: () -> Unit,
onActive: (String) -> Unit,
onError: (Throwable) -> Unit
)
在 Swift 中:
let mainViewModel = NativeViewModel(
onLoading: { ... },
onActive: { ... },
onError: { ... }
)
或者,您可以將所有情況包含在具有可為空屬性的data class
的 1 個回調中:
data class SyncState() {
val loading: Boolean?,
val active: String?,
val error: Throwable?
}
...
class NativeViewModel (
onSyncState: (SyncState) -> Unit
)
在 Swift 中:
let mainViewModel = NativeViewModel(
onSyncState: { ... }
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.