https://kotlinlang.org logo
#ios
Title
# ios
j

Jacob Rhoda

11/01/2023, 6:07 PM
Does anyone have any wisdom to offer regarding using KMP with SwiftUI? Is it better to use Swift types directly in your SwiftUI code, and some glue code that translates between Kotlin and Swift? Or should we use Kotlin types directly in the SwiftUI code? I’m going for a more lightweight MVVM approach than the heavy/complicated MVIKotlin approach.
p

Pablichjenkov

11/01/2023, 6:12 PM
I haven't done it but I like your first solution better. Create a layer in swift itself that consume the kotlin interop. It would allow to make any tweaks in this layer if needed or some data processing before reaching swiftui
m

Michael Langford

11/01/2023, 6:12 PM
There is more than one stable point. It is unquestionable possible to bury Kotlin way down into a data/light calculation only role. I hope to hear others share their stable points, but others have in the past (and used much higher up UI components than I have directly)
(Our decision was based on the iOS app coming first, and the kotlin being a retrofit of a shared data component, not a kotlin app first porting to iOS scenario)
j

Jacob Rhoda

11/01/2023, 6:19 PM
I want Kotlin to be as close to the UI layer as possible, since I want to share as much code as possible between iOS and Android. However, I still want it to be clear to other developers looking at my code what everything is doing. (When I look at MVIKotlin code, my head spins.) I quite like what Point-Free has been doing with their Composable architecture in Swift. They have a UI component that takes a store and a transformation function and shuttles data into the UI type. If I could pull off something like that it would be great. But the question is still there, where exactly do you draw the line between Swift and Kotlin? https://pointfreeco.github.io/swift-composable-architecture/main/documentation/composablearchitecture/withviewstore
m

Michael Langford

11/01/2023, 6:25 PM
At some point, some of the issue is the "how willing are you to ignore iOS UI conventions". Like the interaction and update schemes for jetpack and swiftUI and data around them are different enough that you run into issues at times. For instance, there is a lot more "construct a lot of a hypothetical object across more than one screen then confirm you will store it to your source of truth" on iOS than on Android generally. Beyond the point free guys, there are iOS things like reswift and a few others which are similar ideas and have longstanding communities. iOS definitely supports a "this is the model now" approach natively with swift UI. I haven't brought kotlin up that high into our app yet though to stick it right there though yet 😄
p

Pablichjenkov

11/01/2023, 6:31 PM
I have worked closely with my iOS colleagues implementing semi complex screens and there is no way they would buy into bringing the state directly from kotlin
The reason is, that state is the hottest area in the code. Probably UI state takes around 70% of the time when implementing a solution. Anything that slows these constant state redesign, trial error process, they are not gonna like
m

Michael Langford

11/01/2023, 6:34 PM
For Jacob: Even with native approaches to iOS development, "redux style systems" tend to be vulnerable to "large model object" issues with performance
1
p

Pablichjenkov

11/01/2023, 6:35 PM
They might accept bringing in utility libraries and such but for the UI state, they want to work it out themselves
m

Michael Langford

11/01/2023, 6:36 PM
with redux style systems you can keep UI state out of it (Jacob had pointed at one with the point free stuff which is why I mention it). It isn't such a bottleneck then, but you lose a lot of "shared code" especially test cases.
j

Jacob Rhoda

11/01/2023, 6:39 PM
@Pablichjenkov Yeah, I can see that. However, I’m working on a much smaller team and keen on a type of “mobile full-stack” developer where developers are writing both Kotlin and Swift. That way you can do that sort of code sharing. Perhaps that’s overly ambitious, though.
💯 1
m

Michael Langford

11/01/2023, 6:40 PM
it's not about the developer taste though
d

Darron Schall

11/01/2023, 6:40 PM
FWIW, I have ViewModels in Kotlin that manage UI State, and expose the UI State flow for SwiftUI to consume. The ViewModel is
@Observable
@ObservedObject
and the SwiftUI view pulls the
uiState
from the model and responds accordingly (updating when the flow emits a new state). At that point you're just writing SwiftUI like you normally would.
👀 1
m

Michael Langford

11/01/2023, 6:40 PM
It's about the "that's not how a text box works"
j

Jacob Rhoda

11/01/2023, 6:42 PM
Michael: What do you mean you run into large model object issues? Like, the model gets so gigantic from all the different state that it becomes a performance issue? It was my understanding that the redux-style systems allow you to break your code down into smaller chunks, decoupling from UI, allowing unit tests, and making things pluggable to share between platforms.
m

Michael Langford

11/01/2023, 6:43 PM
So in addition to this whole "where do you start KM" in the stack question, there is often a lot of "undecided data modelling" from the api side
If your backend folks are going to toss objects the size of a small bus at you, you Have Decisions
😂 1
Large hairy legacy objects are a lot bigger problem than greenfield "we aren't just the mobile team, we're the data team too"
with mobile, you're always fighting the "I have to fetch 43 layers of object to get a screen rendered" vs "omg that's a goddamn 3d render of a house on an infographic level" angle with respect to API granularity.
so if those models are big, then you have really an iffier observable type performance environment. Because iOS obserables involve a metric crapton of copying objects. If objects got big enough at one point, they intermittantly crashed iOS a couple years ago if you copied them fast enough.
If you want to know how big I'm talking, I'm talking like 98 fields some of which had subfields.
I'm not talking "a megabyte max"
j

Jacob Rhoda

11/01/2023, 7:08 PM
Ah I gotcha. Well, we don’t quite have that problem yet. I can also limit the specific fields and such which get passed around at the service-level. Additionally, we use GraphQL which allows me to target which particular fields I actually care about in an object graph.
@Darron Schall How do you make your Kotlin models @Observable? Are you referring to the new @Observable macro introduced in iOS 17?
m

Michael Langford

11/01/2023, 7:10 PM
GraphQL definitely helps a lot at getting the fields you need, yes. It sounds like there is some success at the level you're looking for above ^. I'd probably just reserve enough development capacity to lose a level on the iOS app if it doesn't pan out.
👍 1
it's not like the android app won't keep working no matter what you do there.
It also matters a lot how much "user opinion" of your app matters. You can get away with a lot less "native feeling" ui with internal users of large companies, and secondary app of large expensive physical component. With consumer facing you have a lot higher bar at times to keep marketshare
(not that KM doesn't make native feeling apps, it does, but the actual behavior for confirm, keyboards, etc is all a little different a lot of places, so if you don't write that twice, you can feel "off" in one of the two platforms).
j

Jacob Rhoda

11/01/2023, 7:15 PM
Yeah, that was part of what I like about KMP is that I can deliver native-feeling apps. Whereas Flutter and RN are going to be approximating it all the time. And this is a customer-facing app, so I care about the quality of the product a lot more.
m

Michael Langford

11/01/2023, 7:17 PM
Like on iOS, you can occasionally need to make a set of conditional code for iPad vs iPhone (and apple tests on iPads, so...). As long as you leave time and don't get intractable about getting that where you need it for your business, you'll make it.
👍 1
I was really here to 🍿 you grilling Darron for deets, not to talk you out of it.
😂 1
d

Darron Schall

11/01/2023, 7:32 PM
@Jacob Rhoda I meant to say
@ObservedObject
not
@Observable
. There are various ways to achieve view model sharing. I suggest taking a look at the samples - https://www.jetbrains.com/help/kotlin-multiplatform-dev/multiplatform-samples.html - and finding the samples that share models / view models. Looking through the samples, you should be able to find an approach that resonates with you and your team. Specifically for making a view model observable, you'll want a Swift extension that conforms your view model to the
ObservableObject
protocol, and then a helper that receives the uiState flow and fires off
objectWillChange.send()
. Rather than setting that all up by hand, I might suggest looking at a library that does it already, such as https://github.com/rickclephas/KMM-ViewModel
👍 1