workflow-kotlin icon indicating copy to clipboard operation
workflow-kotlin copied to clipboard

Kotlin Multiplatform support

Open russhwolf opened this issue 3 years ago • 0 comments

This is a loose rundown of the state of the kmp branch, which contains the kotlin multiplatform conversion that @brady-aiello and myself began prototyping earlier this summer.

Things that exist in that branch include:

  • multiplatform conversion of workflow-core, workflow-runtime, and the core-common, backstack-common, and modal-common submodules of workflow-ui
  • Two new samples hello-workflow-multiplatform and tictactoe-multiplatform based on the existing hello-workflow and tictactoe samples. These mostly just exercise the multiplatform workflow-core.

Some design decisions we made that are worth highlighting

  • Some things that previously references java Class now instead use KClass. This has a slightly different toString() format, which impacts some things like WorkflowIdentifier tests.
  • We added a string-based WorkflowIdentifier implementation for iOS, since the KAnnotatedElement logic that exists in the current version mostly only works on JVM.
  • Some extensions in Snapshot.kt depend on the enumConstants field which doesn't have an equivalent on KClass, so these extensions were left as JVM-only.
  • The Worker class includes a TYPE_OF_NOTHING constant which is typeOf<Void>() on JVM. We added an expect class Void with an arbitrary actual class Void on native, but there may be other ways to handle this.
  • We had difficulty migrating the existing --friend-paths configuration that allows workflow-testing to read internal classes of workflow-core. We opted to introduce an opt-in annotation InternalWorkflowApi instead, to mark library API that consumers shouldn't depend on. Note that opt-in annotations are not yet stable as a language feature (but will be soon).
  • JMH performance testing configuration in workflow-runtime is currently disabled in the branch since it doesn't migrate naturally to the multiplatform plugin

TODOs and future work.

  • [ ] Multiplatform publishing configuration. We haven't touched publish scripts yet.
  • [ ] More targets. Current prototype uses only iosX64 for simulator builds on Intel mac hosts. At a minimum we'll want to also enable iosArm64 and iosSimulatorArm64, but it probably makes sense to do all darwin targets, and consider whether any Windows/Linux targets are worthwhile.
  • [ ] Reexamine native WorkflowIdentifier. If this is largely only needed for snapshots, which are largely only needed for Android, then maybe there's a better solution where WorkflowIdentifier moves to being JVM-only instead of having a native implementation that rarely get used.
  • [ ] Reexamine the workflow-runtime conversion. A bunch of functionality and tests were left JVM-only. Is the stuff in common useful?
  • [ ] Re-enable JMH tests in workflow-runtime, possibly by moving to an separate module
  • [ ] Add dependency on multiplatform kotlinx-coroutines-test when available, and move jvm-only tests to common where possible.
  • [ ] Try moving workflow-testing to common once multiplatform kotlinx-coroutines-test is available.
  • [ ] Demonstrate interop with a Worker involved, since this API is not exercised by the current multiplatform samples.
  • [ ] Figure out strategy for workflow-swift interop. There's some code in the samples that might be useful as library-level interop helpers, but we need to refine that API and figure out what's useful, as well as come up with a publishing strategy.
  • [ ] Explore ways to delegate between render methods of workflow-kotlin and workflow-swift, in order to avoid reimplementing this logic. There are probably adapters here that could live in an interop library.
  • [ ] Explore calling into renderWorkflowIn() from Swift in order to facilitate interop. This might need some helper code on the Kotlin and/or Swift side that could live in an interop library
  • [ ] Determine if multiplatform workflow-ui modules are useful. What sort of interop is needed to make these natural to call into from Swift?

There are probably other TODOs worth considering as well, and some of these might not be necessary for a first release, but hopefully this can start the ball rolling.

russhwolf avatar Sep 17 '21 00:09 russhwolf