dbaroncelli/D-KMP-sample

[Question] Architecture and implementation details

ajacquierbret opened this issue · 1 comments

Hi!

First, thank you for the huge amount of work you put in defining a neat and future-proof architecture, and for making it publicly available. I've been waiting for something like this for months.

I have several questions about it (some of it may be exclusively related to Compose/SwiftUI as I'm quite new to native development):

  • Navigation:

    • How would you implement a second layer of navigation? e.g. A layer for onboarding unauthenticated users and another for logged-in users.
    • How would you handle actions depending on a screen's lifecycle? e.g. Doing something when the screen is rendered. Should lifecycle hooks be part of the architecture or should Compose/SwiftUI hooks be used to achieve this kind of action? e.g. A LaunchedEffect hook calls a function defined in the shared module
  • State:

    • Do you think this architecture is compatible with any kind of local cache as a single source of truth for the state? e.g. Apollo HTTP/Normalized GraphQL cache
    • If so, would you implement the caching behaviour inside the runtimecache or the localdb directory?
  • General:

    • Don't you think some of the unchanged files included in the sample should be upstreamed and packaged in a multiplatform library or some kind of DSL?

If it helps, here's more information about what I'm trying to build: apollographql/apollo-kotlin#3106

Thanks in advance for your time!

Hi Adrien,

In terms of Navigation:
I haven't implemented a use case where login is involved, however thinking about it, this is probably how I would structure it:

  • I would define a Login screen, like any other, with its own state and its own events.
  • Inside the "callOnInit" function of any Screen requiring authentication, I would include the logic that if the user isn't authenticated (you could keep a flag about it, in the NavigationSettings.kt), it would redirect to the Login screen.
    At the moment, in terms of screen's lifecycle, I have just defined "callOnInit", which is executed each time the app navigates to that screen. I haven't defined anything like "callOnDisappear", as I haven't found a use case for that yet.
    Generally speaking, I would keep actions separated by the UI definition. E.g. I would tend to avoid stuff like LaunchedEffect, as it makes testing more difficult. Better to define actions/events (and any concurrency involved) in the shared code.

In terms of GraphQL:
I think the architecture perfectly fits. You just need to create a new property in the Repository.kt file, calling it for example graphQL. And then define any GraphQL related code inside the "sources/graphQL" directory, similarly to any other source.

In terms of packaging D-KMP files as a multiplatform library:
It might happen eventually, but at the moment the project is still at an early stage, so I prefer to keep the code "in the open", as it's easier to debug and spot any issue.

I hope I was able to give some clarifications.
If you have any other questions, feel free to ask.