I’ve been working on sharing logic between Android and iOS and I’d like to share my experience with working with images in a platform agnostic way.
Kotlin Multiplatform lets you share non platform specific logic ( “non UI code”) between different platforms (Android, jvm, js, iOS, macOS, etc…) and gives you the possibility of creating abstractions over platform specific logic.
I won’t dive into more detail about the technology, you can read more about it here.
The feature was about uploading an application, with an icon and screenshots. Check out the final versions:
Additionally my goal was to test out Kotlin Multiplatform with the following technical decisions:
- A shared ViewModel layer
- Unidirectional data flow
Practically this means, that all the icons, screenshots you see above will be part of the state stored in a shared ViewModel, with the following events:
- All platforms submit their platform specific representation of the selected image
- The ViewModel works with these images in a platform agnostic way
- All platforms receive back the platform specific representation of the image and show it on the UI
Kotlin Multiplatform is really clever and it lets us create the platform agnostic abstractions with an
expected declaration that needs to have an
actual implementation (read more about expect/actual).
Since the image will travel frequently from platform specific to platform agnostic code, I had a strong feeling, that because of the unidirectional pattern of the code, I’ll face two unpleasant issues:
- Platform specific information will be lost
- I’ll need to use some primitives (like bytes) and do some ugly conversions
It turned out KMP is neater than I’ve expected and I didn’t have to do either of those.
As I’ve mentioned earlier we need to make a platform agnostic abstraction for the images and we’ll need a way to convert these images into
bytes before uploading it to the backend:
We could move the
toByteArray() inside our
ImageFile class, but instead we’d like to leverage
typealiases , when defining the
actual implementations for the platforms:
The neat part is, that since we are using
typealiases for the
actual implementations, all the platforms have the freedom to submit their native implementation of the
ImageFile and the updated state from the
ViewModel will contain it without any information loss:
Yes, cross-platform frameworks may be okay(ish), but show me a technology that can achieve this level of interoperability between platforms 🚀
For sending out the request, I’ve used Ktor as it provides a seamless way for sharing the network layer between different platforms:
If you’d like to check out the full project: https://github.com/halcyonmobile/MultiplatformPlayground