Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Integrating Kotlin Multiplatform Mobile with S...

Integrating Kotlin Multiplatform Mobile with SwiftUI

Allowing developers to share code between iOS, Android, and much more.

Talk for Cocoaheads Stockholm
https://www.meetup.com/cocoaheads-stockholm/events/292301636/
Meetup 120 @ UMain

Jackson F. de A. Mafra

April 17, 2023
Tweet

More Decks by Jackson F. de A. Mafra

Other Decks in Programming

Transcript

  1. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 umain.com Integrating ‘Kotlin Multiplatform Mobile’ { Allowing developers to share code between iOS, Android and much more Kotlin Multiplatform Mobile [with SwiftUI] } AppState.swift AppDelegate.swift
  2. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 umain.com struct Agenda { struct KMM { static let topic1 = "What is KMM?" static let topic2 = "Why we chose it?" } struct SwiftUI { static let topic1 = "Integration with SwiftUI" static let topic2 = "Wrapper" static let topic3 = "Model" static let topic4 = "UI rendering" } struct ProsCons { static let topic1 = "the good, the bad and the ugly" } } Kotlin Multiplatform Mobile AppState.swift AppDelegate.swift
  3. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 umain.com /* What is KMM ? Kotlin Multiplatform Mobile (KMM) is a technology developed by JetBrains, the creators of the Kotlin programming language, that allows developers to build cross-platform mobile applications using Kotlin. KMM enables developers to share common code between iOS and Android platforms, allowing them to write their business logic, data access, and other core features once and deploy them on multiple platforms. */ @main struct KMMApp: App { } Kotlin Multiplatform Mobile AppState.swift AppDelegate.swift 3
  4. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 umain.com /* Why we chose it? This approach allows developers to reuse their existing Kotlin skills and tools while leveraging the benefits of native development on each platform. KMM also works with popular mobile frameworks such as SwiftUI and Jetpack Compose. */ @main struct KMMApp: App { } Kotlin Multiplatform Mobile KMMApp.swift AppDelegate.swift 4
  5. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 umain.com Kotlin Multiplatform Mobile KMMApp.swift AppState.swift 5
  6. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 umain.com # Uncomment the next line to define a global platform for your project platform :ios, '15.0' # Comment the next line if you don't want to use dynamic frameworks Use_frameworks! def shared_pods pod 'MultiplatformLibrary', :git => '[email protected]/repository’, :tag => ‘x.y.z’ end Kotlin Multiplatform Mobile Podfile AppState.swift 6
  7. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 umain.com Kotlin Multiplatform Mobile KMM+Extensions.swift AppState.swift import MultiplatformLibrary import Combine extension DisposableHandler { func asCancellable() -> Cancellable { return CancellableWrapper { [weak self] in self?.dispose() } } } 7
  8. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 umain.com Kotlin Multiplatform Mobile ViewModel.swift AppState.swift import MultiplatformLibrary import Combine class ViewModel<T: BaseViewModel>: ObservableObject { internal var model: T internal var subscriptions: Set<AnyCancellable> = [] init(_ model: T) { self.model = model } deinit { model.dispose() } } 8
  9. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 umain.com import MultiplatformLibrary class MarketPickerModel: ViewModel<MarketPickerViewModel> { @Published private(set) var state: MarketPickerStateKs init(model: MarketPickerViewModel = KoinHelper().marketPickerViewModel) { super.init(model) setupObservers() } private func setupObservers() { model.state.watch { [weak self] state in self?.state = MarketPickerStateKs(state) }.asCancellable().store(in: &subscriptions) model.effect.watch { [unowned self] rawEffect in let effect = MarketPickerEffectKs(rawEffect) switch effect { default: break } } .asCancellable().store(in: &subscriptions) emitEvent() } } Kotlin Multiplatform Mobile MarketPickerModel.swift AppState.swift 9
  10. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 umain.com Kotlin Multiplatform Mobile MarketPickerView.swift AppState.swift struct MarketPickerView: View { @ObservableObject var viewModel: MarketPickerModel var body: some View { VStack { switch self.viewModel.state { case .loading: loadingView() case .marketInfo(): renderView() case .error(let value): errorView() } } } } 10
  11. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 umain.com Kotlin Multiplatform Mobile ProsCons.swift AppState.swift /* The good, the bad, and the ugly - One of the key benefits of KMM is the ability to share code for business logic, data access, and other core features between platforms, reducing the amount of duplicate code that needs to be written for each platform. - This can lead to significant time and cost savings for development teams, as well as improved code consistency and maintainability. */ 11
  12. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 umain.com Kotlin Multiplatform Mobile ProsCons.swift AppState.swift /* The good, the bad, and the ugly - KMM is still a relatively new technology and is evolving rapidly, with ongoing updates and improvements to its functionality and features. - Working through Cinterop complicates development. - First party library support */ 12
  13. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 umain.com Kotlin Multiplatform Mobile ProsCons.swift AppState.swift /* The good, the bad, and the ugly - Calling coroutines (like combine) in iOS - Strange variable names on iOS (e.g. Kotlinx_coroutines_coreCoroutineDispatcher) - Auto-complete in Xcode shows lots of unrelated variables */ 13
  14. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 umain.com Thank you! ‘Want to know more?’ { Kotlin Multiplatform Mobile [get inTouch] } AppState.swift AppState.swift // umain.com // @weareumain