icerockdev / moko-mvvm

Model-View-ViewModel architecture components for mobile (android & ios) Kotlin Multiplatform development
https://moko.icerock.dev/
Apache License 2.0
1k stars 95 forks source link

SwiftUI support #36

Closed Xerosigma closed 2 years ago

Xerosigma commented 4 years ago

If supported - Could you provide an example of how binding would work using SwiftUI?

Alex009 commented 4 years ago

Hi! in one of our forks already tried integrate with SwiftUI - https://github.com/icerockdev/moko-mvvm/compare/master...jacobminer:jm/swift-ui-support maybe it work and help you we still not try SwiftUI self, but will try later and update implementation where needed

michaelbrainvu commented 4 years ago

The above integration did not work for me since the BindableObject can not be found so compilation failed. Eventually I had to write a SwiftUI ObservableObject wrapper class which internally creates the actual view model and registers an event dispatcher listener. The model properties are mapped to SwiftUI using @Published properties which are set by actual view model properties observers. Notice that you can not use moko-units for generating list items unless you want to wrap UITableView for SwiftUI which misses the whole point of using SwiftUI. See attached example ExampleViewModelWrapper.swift.zip

jacobminer commented 4 years ago

As far as I can tell, it's not possible for Moko-MVVM to support SwiftUI directly in the shared code right now because Kotlin Multiplatform doesn't support interoperability with pure Swift modules (like SwiftUI and Combine). In order to support SwiftUI, there are two main changes that need to occur, both of which are blocked by the above issue:

If the above were true, I think we would be able to use SwiftUI as follows:

ViewModel

class SwiftUIViewModel: ViewModel() {
    val textLiveData = MutableLiveData("Hello world")
}

SwiftUI

struct SwiftUIView: View {
    @ObservedObject var viewModel: SwiftUIViewModel

    var body: some View {
        Text(viewModel.textLiveData.value)
    }
}
Alex009 commented 4 years ago

thanks for your explanation. we will try to improve support of SwiftUI, maybe with additional swift cocoapod, what will have all required swift interop and objc conversion to use from kotlin-multiplatform side

ln-12 commented 3 years ago

How's the progress in this? Do you plan to support it in the near future? As I want to develop an iOS app using SwiftUI, I need to decide if I could use this library.

Alex009 commented 3 years ago

we not use SwiftUI now, so we not add support in nearby plans. but you can try add support self. if needed some consultations - feel free to ask here

skajake commented 3 years ago

+1 for SwiftUI support

mykola-dev commented 3 years ago

any updates on this? huge blocker for us :(

schrulnz commented 2 years ago

Thanks @michaelbrainvu for your sample code! This works fine for me, I had some problems doing the same with objects instead of Boolean/String variables. I finally succeeded though, in case this helps anyone, here is my code:

class ObservableState: ObservableObject {
    @Published var viewModel = HomeViewModel()
    @Published var data: [User]?

    init() {
        self.viewModel.state.addObserver { (value) in
            self.data = value?.data
        }
    }
}

struct HomeScreen: View {
    @StateObject private var observableState = ObservableState()

    var body: some View {
        NavigationView {
            VStack {
                if let users = observableState.viewModel.state.value?.data {
                    List(users, id: \.id) { user in
                        ListItem(user: user)
                    }
                } else {
                    Text("Loading...")
                }

                // navigating to another screen
                NavigationLink(destination: AddUserScreen(viewModel: self.observableState.viewModel), label: {
                    Text("Add User...")
                })
            }
        }
    }
}
Alex009 commented 2 years ago

sample will be available in 0.13.0 in sample-declarative-ui directory also read 0.13.0 release notes and readme about dependency to SwiftUI swift additions