It appears that data class is not fully compatible...
# multiplatform
j
It appears that data class is not fully compatible with iOS SwiftUI/Combine ObservableObject. Using this template app: https://github.com/joreilly/PeopleInSpace which lists people in space. On iOS its using SwiftUI and MVVM with viewmodel class (inherit from ObservableObject) that has a list/array of People object which is Kotlin data class in commonMain. The iOS basically calls the Repository class in commonMain to retrieve a list of People objects and display in list view. ObservableObject in SwiftUI/Combine is setup to update the SwiftUI list view whenever there is any changes in viewmodel class. Everything works fine if youre not changing the content of People object, like the sample template app. But when you try to change the attribute of the People object, the update is not reflected in the SwiftUI list view. So I changed the viewmodel class to have a list of PeopleIOS object, which is a struct I define in iOS. When retrieving the list of People object from commonMain, I convert them to a list of PeopleIOS, and use this structure in SwiftUI list view. And the changes is reflected in SwiftUI list view. I’m only few days picking up KMP so not so sure if I did anything wrong. Trying to look for a sample app that has KMP/SwiftUI/Combine that edit the commonMain data class model, if there is any would like to take a look. And I find the KaMPKit too much for KMP beginner. It might do more damage than getting people to adopt KMP.
👍 1
💡 2
a
I caught myself that MVI-ish approach works better for KMP. I allows you to share more code as well as simplify integration points. You can expose only view interface that accepts view models (immutable data classes) and emits view events. And also expose a Binder class that has lifecycle callbacks: onStart, onViewCreated(view), onViewDestroyed, onStop, onDestroy. So clients just do nothing but implement the interface, create binder and call it's callbacks. No wirings on their side. Also you create AbstractView impl in commonMain so clients also won't need to dial with Channels/Relays etc for view events. With such an approach clients don't directly depend on an Rx/Coroutines library.
👍 1
I think I will write an article about MVI in KMP
👍 9
j
Thanks
d
@Arkadii Ivanov Yes, I also find this is a natural fit approach. I favoured similar idea with 'MVP passive view' pattern to create https://git.chrishatton.org/chris/multi-mvp
o
@Arkadii Ivanov did you write your article?
a
Not yet, slowly in progress. I have some samples open sourced, can share if there is interest.
o
Sure!
a
Here is the sample KMP module with MVI-ish approach: https://github.com/badoo/Reaktive/tree/master/sample-mpp-module You can also find Android, iOS, macOS, Linux and JS sample apps using this shared module there. Also I just published the first KMP version of the MVIKotlin framework: https://github.com/arkivanov/MVIKotlin You can also find some samples there.
j
@Jaxon Du just saw this....haven't had a chance to dig any deeper but just wondering if you think this was issue with Kotlin Multiplatform in general (when used on iOS) or related to use of Combine (or both!)?
j
@John O'Reilly if my understanding is correct, it’s due to Combine and it’s Observable, ObservableObject do not support ObjectiveC object, only Swift. Multiplatform generates Objective-C codes. So the solution seems to be hoping Apple will add Objective-C support to Combine or Multiplatform generates Swift codes.
👍 1
a
You can check my sample apps here: https://github.com/arkivanov/MVIKotlin/tree/master/sample But this is MVI, not MVVM. So it is a simple todo list. You can go to the todo details screen, edit an item there and then go back to the list screen, changes are reflected.
175 Views