From 8ac74dc8035dcfddc964f280965f288f45e8f684 Mon Sep 17 00:00:00 2001 From: xxfast Date: Fri, 20 Oct 2023 14:48:15 +1100 Subject: [PATCH 1/9] Add missing default router context declarations --- app/build.gradle.kts | 5 ++++- app/ios/ios/AppDelegate.swift | 9 ++++----- .../decompose/router/app/Application.kt | 7 ++----- .../decompose/router/app/AppDelegate.kt | 13 ++++++------ .../router/app/utils/RouterContext.kt | 15 -------------- ...rContextExt.kt => DefaultRouterContext.kt} | 0 .../decompose/router/DefaultRouterContext.kt | 20 +++++++++++++++++++ .../decompose/router/DefaultRouterContext.kt | 19 ++++++++++++++++++ .../xxfast/decompose/router/RouterContext.kt | 11 ---------- ...uterContext.kt => DefaultRouterContext.kt} | 0 10 files changed, 55 insertions(+), 44 deletions(-) delete mode 100644 app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/utils/RouterContext.kt rename decompose-router/src/androidMain/kotlin/io/github/xxfast/decompose/router/{RouterContextExt.kt => DefaultRouterContext.kt} (100%) create mode 100644 decompose-router/src/desktopMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt create mode 100644 decompose-router/src/iosMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt delete mode 100644 decompose-router/src/iosMain/kotlin/io/github/xxfast/decompose/router/RouterContext.kt rename decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/{RouterContext.kt => DefaultRouterContext.kt} (100%) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 23305f0..3b9392b 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -30,6 +30,9 @@ kotlin { it.binaries{ framework { baseName = "app" + + // Only need this if you wish to add your own AppDelegate in swift + export(project(":decompose-router")) } executable { @@ -59,7 +62,7 @@ kotlin { sourceSets { val commonMain by getting { dependencies { - implementation(project(":decompose-router")) + api(project(":decompose-router")) implementation(compose.runtime) implementation(compose.foundation) diff --git a/app/ios/ios/AppDelegate.swift b/app/ios/ios/AppDelegate.swift index ef4ba3e..0698037 100644 --- a/app/ios/ios/AppDelegate.swift +++ b/app/ios/ios/AppDelegate.swift @@ -5,7 +5,7 @@ import app class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - var rootRouterContext = RouterContextKt.defaultRouterContext() + var rootRouterContext = DefaultRouterContextKt.defaultRouterContext() func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { window = UIWindow(frame: UIScreen.main.bounds) @@ -15,17 +15,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate { return true } - func applicationDidBecomeActive(_ application: UIApplication) { - RouterContextKt.resume(rootRouterContext.lifecycle) + rootRouterContext.resume() } func applicationWillResignActive(_ application: UIApplication) { - RouterContextKt.stop(rootRouterContext.lifecycle) + rootRouterContext.stop() } func applicationWillTerminate(_ application: UIApplication) { - RouterContextKt.destroy(rootRouterContext.lifecycle) + rootRouterContext.destroy() } } diff --git a/app/src/desktopMain/kotlin/io/github/xxfast/decompose/router/app/Application.kt b/app/src/desktopMain/kotlin/io/github/xxfast/decompose/router/app/Application.kt index d0e9539..f05341a 100644 --- a/app/src/desktopMain/kotlin/io/github/xxfast/decompose/router/app/Application.kt +++ b/app/src/desktopMain/kotlin/io/github/xxfast/decompose/router/app/Application.kt @@ -12,15 +12,12 @@ import com.arkivanov.essenty.lifecycle.LifecycleRegistry import io.github.xxfast.decompose.router.LocalRouterContext import io.github.xxfast.decompose.router.RouterContext import io.github.xxfast.decompose.router.app.screens.HomeScreen +import io.github.xxfast.decompose.router.defaultRouterContext -@OptIn(ExperimentalDecomposeApi::class) fun main() { - val lifecycle = LifecycleRegistry() - val rootRouterContext = RouterContext(lifecycle = lifecycle) - application { val windowState: WindowState = rememberWindowState() - LifecycleController(lifecycle, windowState) + val rootRouterContext: RouterContext = defaultRouterContext(windowState = windowState) Window( title = "App", diff --git a/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/AppDelegate.kt b/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/AppDelegate.kt index 1a03353..0a3a396 100644 --- a/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/AppDelegate.kt +++ b/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/AppDelegate.kt @@ -1,11 +1,10 @@ package io.github.xxfast.decompose.router.app -import com.arkivanov.essenty.lifecycle.destroy -import com.arkivanov.essenty.lifecycle.resume -import com.arkivanov.essenty.lifecycle.stop import io.github.xxfast.decompose.router.RouterContext -import io.github.xxfast.decompose.router.app.utils.registry import io.github.xxfast.decompose.router.defaultRouterContext +import io.github.xxfast.decompose.router.destroy +import io.github.xxfast.decompose.router.resume +import io.github.xxfast.decompose.router.stop import kotlinx.cinterop.BetaInteropApi import kotlinx.cinterop.ExperimentalForeignApi import platform.UIKit.UIApplication @@ -40,14 +39,14 @@ class AppDelegate @OverrideInit constructor() : UIResponder(), UIApplicationDele } override fun applicationDidBecomeActive(application: UIApplication) { - routerContext.lifecycle.registry.resume() + routerContext.resume() } override fun applicationWillResignActive(application: UIApplication) { - routerContext.lifecycle.registry.stop() + routerContext.stop() } override fun applicationWillTerminate(application: UIApplication) { - routerContext.lifecycle.registry.destroy() + routerContext.destroy() } } diff --git a/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/utils/RouterContext.kt b/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/utils/RouterContext.kt deleted file mode 100644 index e4520b3..0000000 --- a/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/utils/RouterContext.kt +++ /dev/null @@ -1,15 +0,0 @@ -package io.github.xxfast.decompose.router.app.utils - -import com.arkivanov.essenty.lifecycle.Lifecycle -import com.arkivanov.essenty.lifecycle.LifecycleRegistry -import com.arkivanov.essenty.lifecycle.destroy -import com.arkivanov.essenty.lifecycle.resume -import com.arkivanov.essenty.lifecycle.stop -import io.github.xxfast.decompose.router.RouterContext -import io.github.xxfast.decompose.router.defaultRouterContext - -fun defaultRouterContext(): RouterContext = defaultRouterContext() -val Lifecycle.registry get() = this as LifecycleRegistry -fun Lifecycle.destroy() = registry.destroy() -fun Lifecycle.resume() = registry.resume() -fun Lifecycle.stop() = registry.stop() diff --git a/decompose-router/src/androidMain/kotlin/io/github/xxfast/decompose/router/RouterContextExt.kt b/decompose-router/src/androidMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt similarity index 100% rename from decompose-router/src/androidMain/kotlin/io/github/xxfast/decompose/router/RouterContextExt.kt rename to decompose-router/src/androidMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt diff --git a/decompose-router/src/desktopMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt b/decompose-router/src/desktopMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt new file mode 100644 index 0000000..2d68ade --- /dev/null +++ b/decompose-router/src/desktopMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt @@ -0,0 +1,20 @@ +package io.github.xxfast.decompose.router + +import androidx.compose.runtime.Composable +import androidx.compose.ui.window.WindowState +import androidx.compose.ui.window.rememberWindowState +import com.arkivanov.decompose.ExperimentalDecomposeApi +import com.arkivanov.decompose.extensions.compose.jetbrains.lifecycle.LifecycleController +import com.arkivanov.essenty.backhandler.BackDispatcher +import com.arkivanov.essenty.lifecycle.LifecycleRegistry + +@OptIn(ExperimentalDecomposeApi::class) +@Composable +fun defaultRouterContext( + backDispatcher: BackDispatcher = BackDispatcher(), + lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(), + windowState: WindowState = rememberWindowState(), +): RouterContext { + LifecycleController(lifecycleRegistry, windowState) + return RouterContext(lifecycle = lifecycleRegistry, backHandler = backDispatcher) +} diff --git a/decompose-router/src/iosMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt b/decompose-router/src/iosMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt new file mode 100644 index 0000000..f38d381 --- /dev/null +++ b/decompose-router/src/iosMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt @@ -0,0 +1,19 @@ +package io.github.xxfast.decompose.router + +import com.arkivanov.essenty.backhandler.BackDispatcher +import com.arkivanov.essenty.lifecycle.Lifecycle +import com.arkivanov.essenty.lifecycle.LifecycleRegistry +import com.arkivanov.essenty.lifecycle.destroy +import com.arkivanov.essenty.lifecycle.resume +import com.arkivanov.essenty.lifecycle.stop + +fun defaultRouterContext(): RouterContext { + val backDispatcher = BackDispatcher() + val lifecycle = LifecycleRegistry() + return RouterContext(lifecycle = lifecycle, backHandler = backDispatcher) +} + +private val RouterContext.lifecycleRegistry: LifecycleRegistry get() = this.lifecycle as LifecycleRegistry +fun RouterContext.destroy() = lifecycleRegistry.destroy() +fun RouterContext.resume() = lifecycleRegistry.resume() +fun RouterContext.stop() = lifecycleRegistry.stop() diff --git a/decompose-router/src/iosMain/kotlin/io/github/xxfast/decompose/router/RouterContext.kt b/decompose-router/src/iosMain/kotlin/io/github/xxfast/decompose/router/RouterContext.kt deleted file mode 100644 index 17f8bd0..0000000 --- a/decompose-router/src/iosMain/kotlin/io/github/xxfast/decompose/router/RouterContext.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.xxfast.decompose.router - -import com.arkivanov.essenty.backhandler.BackDispatcher -import com.arkivanov.essenty.lifecycle.LifecycleRegistry - -fun defaultRouterContext(): RouterContext { - val backDispatcher = BackDispatcher() - val lifecycle = LifecycleRegistry() - return RouterContext(lifecycle = lifecycle, backHandler = backDispatcher) -} - diff --git a/decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/RouterContext.kt b/decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt similarity index 100% rename from decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/RouterContext.kt rename to decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt From 7e1b39aeca6430d1e9927de0fa7bd3be6774cb86 Mon Sep 17 00:00:00 2001 From: xxfast Date: Fri, 20 Oct 2023 15:47:25 +1100 Subject: [PATCH 2/9] Add swiftui example --- app/build.gradle.kts | 1 + app/ios/ios.xcodeproj/project.pbxproj | 8 ++++++++ app/ios/ios/App.swift | 20 +++++++++++++++++++ app/ios/ios/AppDelegate.swift | 4 ++-- app/ios/ios/HomeView.swift | 20 +++++++++++++++++++ .../decompose/router/app/AppDelegate.kt | 2 +- .../decompose/router/app/Application.kt | 2 +- 7 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 app/ios/ios/App.swift create mode 100644 app/ios/ios/HomeView.swift diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3b9392b..06be369 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -62,6 +62,7 @@ kotlin { sourceSets { val commonMain by getting { dependencies { + // Only need to add this as api if you wish to add your own AppDelegate in swift api(project(":decompose-router")) implementation(compose.runtime) diff --git a/app/ios/ios.xcodeproj/project.pbxproj b/app/ios/ios.xcodeproj/project.pbxproj index 5e784eb..ff16383 100644 --- a/app/ios/ios.xcodeproj/project.pbxproj +++ b/app/ios/ios.xcodeproj/project.pbxproj @@ -10,6 +10,8 @@ 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557BA273AAA24004C7B11 /* Assets.xcassets */; }; 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; }; 2152FB042600AC8F00CF470E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* AppDelegate.swift */; }; + DB85742B2AE2331E0069250C /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB85742A2AE2331E0069250C /* App.swift */; }; + DB85742D2AE234B10069250C /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB85742C2AE234B10069250C /* HomeView.swift */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -31,6 +33,8 @@ 2152FB032600AC8F00CF470E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7555FF7B242A565900829871 /* ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ios.app; sourceTree = BUILT_PRODUCTS_DIR; }; 7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + DB85742A2AE2331E0069250C /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = ""; }; + DB85742C2AE234B10069250C /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -76,6 +80,8 @@ 7555FF8C242A565B00829871 /* Info.plist */, 2152FB032600AC8F00CF470E /* AppDelegate.swift */, 058557D7273AAEEB004C7B11 /* Preview Content */, + DB85742A2AE2331E0069250C /* App.swift */, + DB85742C2AE234B10069250C /* HomeView.swift */, ); path = ios; sourceTree = ""; @@ -179,7 +185,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + DB85742D2AE234B10069250C /* HomeView.swift in Sources */, 2152FB042600AC8F00CF470E /* AppDelegate.swift in Sources */, + DB85742B2AE2331E0069250C /* App.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/app/ios/ios/App.swift b/app/ios/ios/App.swift new file mode 100644 index 0000000..67c3e1d --- /dev/null +++ b/app/ios/ios/App.swift @@ -0,0 +1,20 @@ +// +// App.swift +// ios +// +// Created by Rajapaksage Isuru Rajapakse on 20/10/2023. +// Copyright © 2023 orgName. All rights reserved. +// + +import SwiftUI + +@main +struct Application: App { + @UIApplicationDelegateAdaptor var delegate: AppDelegate + + var body: some Scene { + WindowGroup { + HomeView(routerContext: delegate.rootRouterContext) + } + } +} diff --git a/app/ios/ios/AppDelegate.swift b/app/ios/ios/AppDelegate.swift index 0698037..6320ca5 100644 --- a/app/ios/ios/AppDelegate.swift +++ b/app/ios/ios/AppDelegate.swift @@ -1,7 +1,7 @@ import SwiftUI import app -@UIApplicationMain +//@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? @@ -9,7 +9,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { window = UIWindow(frame: UIScreen.main.bounds) - let mainViewController = ApplicationKt.MainUIController(routerContext: rootRouterContext) + let mainViewController = ApplicationKt.HomeUIViewController(routerContext: rootRouterContext) window?.rootViewController = mainViewController window?.makeKeyAndVisible() return true diff --git a/app/ios/ios/HomeView.swift b/app/ios/ios/HomeView.swift new file mode 100644 index 0000000..472d4e1 --- /dev/null +++ b/app/ios/ios/HomeView.swift @@ -0,0 +1,20 @@ +// +// HomeView.swift +// ios +// +// Created by Rajapaksage Isuru Rajapakse on 20/10/2023. +// Copyright © 2023 orgName. All rights reserved. +// + +import SwiftUI +import app + +struct HomeView: UIViewControllerRepresentable { + let routerContext: RouterContext + + func makeUIViewController(context: Context) -> UIViewController { + return ApplicationKt.HomeUIViewController(routerContext: routerContext) + } + + func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} +} diff --git a/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/AppDelegate.kt b/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/AppDelegate.kt index 0a3a396..7857f53 100644 --- a/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/AppDelegate.kt +++ b/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/AppDelegate.kt @@ -33,7 +33,7 @@ class AppDelegate @OverrideInit constructor() : UIResponder(), UIApplicationDele didFinishLaunchingWithOptions: Map? ): Boolean { window = UIWindow(frame = UIScreen.mainScreen.bounds) - window!!.rootViewController = MainUIController(routerContext) + window!!.rootViewController = HomeUIViewController(routerContext) window!!.makeKeyAndVisible() return true } diff --git a/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/Application.kt b/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/Application.kt index 32e1c29..494efb1 100644 --- a/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/Application.kt +++ b/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/Application.kt @@ -37,7 +37,7 @@ fun main() { } @OptIn(ExperimentalDecomposeApi::class) -fun MainUIController(routerContext: RouterContext): UIViewController = ComposeUIViewController { +fun HomeUIViewController(routerContext: RouterContext): UIViewController = ComposeUIViewController { CompositionLocalProvider( LocalRouterContext provides routerContext, ) { From 16a57fd7f0752c4f1b8b12355d2cd7f95cce6e1c Mon Sep 17 00:00:00 2001 From: xxfast Date: Fri, 20 Oct 2023 15:50:23 +1100 Subject: [PATCH 3/9] Update readme --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 74afc77..43a8f6f 100644 --- a/README.md +++ b/README.md @@ -230,8 +230,11 @@ class DetailInstance(savedState: SavedStateHandle, detail: String) : InstanceKee } ``` > [!IMPORTANT] - > You will need to tie root `RouterContext`'s lifecycle to an `AppDelegate`. See example kotlin app delegate [here](https://github.com/xxfast/Decompose-Router/blob/main/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/AppDelegate.kt), or swift delegate [here](https://github.com/xxfast/Decompose-Router/blob/main/app/ios/ios/AppDelegate.swift). Read more on the docs [here](https://arkivanov.github.io/Decompose/getting-started/quick-start/#ios-with-swiftui) - + > You will need to tie root `RouterContext`'s lifecycle to an `AppDelegate`. + > See Kotlin app delegate [here](https://github.com/xxfast/Decompose-Router/blob/main/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/AppDelegate.kt), + > See Swift UIKit AppDelegate [here](https://github.com/xxfast/Decompose-Router/blob/main/app/ios/ios/AppDelegate.swift). + > See SwiftUI [here](https://github.com/xxfast/Decompose-Router/blob/main/app/ios/ios/App.swift). + > Read more on the docs [here](https://arkivanov.github.io/Decompose/getting-started/quick-start/#ios-with-swiftui)
From 96195cfea24e01335adfcc93c70512627f28fc8a Mon Sep 17 00:00:00 2001 From: xxfast Date: Sat, 21 Oct 2023 13:33:25 +1100 Subject: [PATCH 4/9] Update api --- decompose-router/api/android/decompose-router.api | 10 +++++----- decompose-router/api/desktop/decompose-router.api | 4 ++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/decompose-router/api/android/decompose-router.api b/decompose-router/api/android/decompose-router.api index 642e587..d22331c 100644 --- a/decompose-router/api/android/decompose-router.api +++ b/decompose-router/api/android/decompose-router.api @@ -1,3 +1,8 @@ +public final class io/github/xxfast/decompose/router/DefaultRouterContextKt { + public static final fun defaultRouterContext (Landroidx/activity/ComponentActivity;)Lio/github/xxfast/decompose/router/RouterContext; + public static final fun defaultRouterContext (Landroidx/fragment/app/Fragment;Landroidx/activity/OnBackPressedDispatcher;)Lio/github/xxfast/decompose/router/RouterContext; +} + public final class io/github/xxfast/decompose/router/Router : com/arkivanov/decompose/router/stack/StackNavigation { public static final field $stable I public fun (Lcom/arkivanov/decompose/router/stack/StackNavigation;Landroidx/compose/runtime/State;)V @@ -17,11 +22,6 @@ public final class io/github/xxfast/decompose/router/RouterContext : com/arkivan public fun getStateKeeper ()Lcom/arkivanov/essenty/statekeeper/StateKeeper; } -public final class io/github/xxfast/decompose/router/RouterContextExtKt { - public static final fun defaultRouterContext (Landroidx/activity/ComponentActivity;)Lio/github/xxfast/decompose/router/RouterContext; - public static final fun defaultRouterContext (Landroidx/fragment/app/Fragment;Landroidx/activity/OnBackPressedDispatcher;)Lio/github/xxfast/decompose/router/RouterContext; -} - public final class io/github/xxfast/decompose/router/RouterContextKt { public static final fun getLocalRouterContext ()Landroidx/compose/runtime/ProvidableCompositionLocal; } diff --git a/decompose-router/api/desktop/decompose-router.api b/decompose-router/api/desktop/decompose-router.api index d87e0e0..b219ff1 100644 --- a/decompose-router/api/desktop/decompose-router.api +++ b/decompose-router/api/desktop/decompose-router.api @@ -1,3 +1,7 @@ +public final class io/github/xxfast/decompose/router/DefaultRouterContextKt { + public static final fun defaultRouterContext (Lcom/arkivanov/essenty/backhandler/BackDispatcher;Lcom/arkivanov/essenty/lifecycle/LifecycleRegistry;Landroidx/compose/ui/window/WindowState;Landroidx/compose/runtime/Composer;II)Lio/github/xxfast/decompose/router/RouterContext; +} + public final class io/github/xxfast/decompose/router/Router : com/arkivanov/decompose/router/stack/StackNavigation { public static final field $stable I public fun (Lcom/arkivanov/decompose/router/stack/StackNavigation;Landroidx/compose/runtime/State;)V From cce8addda286216485b1911bac700634492a16b4 Mon Sep 17 00:00:00 2001 From: xxfast Date: Sat, 21 Oct 2023 13:48:56 +1100 Subject: [PATCH 5/9] Fix the swift up app delegate --- app/ios/ios.xcodeproj/project.pbxproj | 20 +++---- app/ios/ios/App.swift | 20 ------- app/ios/ios/HomeView.swift | 20 ------- app/ios/ios/SwiftUIApp.swift | 56 +++++++++++++++++++ ...pDelegate.swift => UIKitAppDelegate.swift} | 2 +- .../decompose/router/DefaultRouterContext.kt | 2 + 6 files changed, 67 insertions(+), 53 deletions(-) delete mode 100644 app/ios/ios/App.swift delete mode 100644 app/ios/ios/HomeView.swift create mode 100644 app/ios/ios/SwiftUIApp.swift rename app/ios/ios/{AppDelegate.swift => UIKitAppDelegate.swift} (93%) diff --git a/app/ios/ios.xcodeproj/project.pbxproj b/app/ios/ios.xcodeproj/project.pbxproj index ff16383..a2f26e3 100644 --- a/app/ios/ios.xcodeproj/project.pbxproj +++ b/app/ios/ios.xcodeproj/project.pbxproj @@ -9,9 +9,8 @@ /* Begin PBXBuildFile section */ 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557BA273AAA24004C7B11 /* Assets.xcassets */; }; 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; }; - 2152FB042600AC8F00CF470E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* AppDelegate.swift */; }; - DB85742B2AE2331E0069250C /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB85742A2AE2331E0069250C /* App.swift */; }; - DB85742D2AE234B10069250C /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB85742C2AE234B10069250C /* HomeView.swift */; }; + 2152FB042600AC8F00CF470E /* UIKitAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* UIKitAppDelegate.swift */; }; + DB85742B2AE2331E0069250C /* SwiftUIApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB85742A2AE2331E0069250C /* SwiftUIApp.swift */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -30,11 +29,10 @@ /* Begin PBXFileReference section */ 058557BA273AAA24004C7B11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - 2152FB032600AC8F00CF470E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 2152FB032600AC8F00CF470E /* UIKitAppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitAppDelegate.swift; sourceTree = ""; }; 7555FF7B242A565900829871 /* ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ios.app; sourceTree = BUILT_PRODUCTS_DIR; }; 7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - DB85742A2AE2331E0069250C /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = ""; }; - DB85742C2AE234B10069250C /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = ""; }; + DB85742A2AE2331E0069250C /* SwiftUIApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIApp.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -78,10 +76,9 @@ children = ( 058557BA273AAA24004C7B11 /* Assets.xcassets */, 7555FF8C242A565B00829871 /* Info.plist */, - 2152FB032600AC8F00CF470E /* AppDelegate.swift */, + 2152FB032600AC8F00CF470E /* UIKitAppDelegate.swift */, 058557D7273AAEEB004C7B11 /* Preview Content */, - DB85742A2AE2331E0069250C /* App.swift */, - DB85742C2AE234B10069250C /* HomeView.swift */, + DB85742A2AE2331E0069250C /* SwiftUIApp.swift */, ); path = ios; sourceTree = ""; @@ -185,9 +182,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DB85742D2AE234B10069250C /* HomeView.swift in Sources */, - 2152FB042600AC8F00CF470E /* AppDelegate.swift in Sources */, - DB85742B2AE2331E0069250C /* App.swift in Sources */, + 2152FB042600AC8F00CF470E /* UIKitAppDelegate.swift in Sources */, + DB85742B2AE2331E0069250C /* SwiftUIApp.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/app/ios/ios/App.swift b/app/ios/ios/App.swift deleted file mode 100644 index 67c3e1d..0000000 --- a/app/ios/ios/App.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// App.swift -// ios -// -// Created by Rajapaksage Isuru Rajapakse on 20/10/2023. -// Copyright © 2023 orgName. All rights reserved. -// - -import SwiftUI - -@main -struct Application: App { - @UIApplicationDelegateAdaptor var delegate: AppDelegate - - var body: some Scene { - WindowGroup { - HomeView(routerContext: delegate.rootRouterContext) - } - } -} diff --git a/app/ios/ios/HomeView.swift b/app/ios/ios/HomeView.swift deleted file mode 100644 index 472d4e1..0000000 --- a/app/ios/ios/HomeView.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// HomeView.swift -// ios -// -// Created by Rajapaksage Isuru Rajapakse on 20/10/2023. -// Copyright © 2023 orgName. All rights reserved. -// - -import SwiftUI -import app - -struct HomeView: UIViewControllerRepresentable { - let routerContext: RouterContext - - func makeUIViewController(context: Context) -> UIViewController { - return ApplicationKt.HomeUIViewController(routerContext: routerContext) - } - - func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} -} diff --git a/app/ios/ios/SwiftUIApp.swift b/app/ios/ios/SwiftUIApp.swift new file mode 100644 index 0000000..fb4b90f --- /dev/null +++ b/app/ios/ios/SwiftUIApp.swift @@ -0,0 +1,56 @@ +// +// App.swift +// ios +// +// Created by Rajapaksage Isuru Rajapakse on 20/10/2023. +// Copyright © 2023 orgName. All rights reserved. +// + +import SwiftUI +import app + +class DefaultRouterHolder : ObservableObject { + let defaultRouterContext: RouterContext = DefaultRouterContextKt.defaultRouterContext() + + deinit { + // Destroy the root component before it is deallocated + defaultRouterContext.destroy() + } +} + +class AppDelegate: NSObject, UIApplicationDelegate { + let holder: DefaultRouterHolder = DefaultRouterHolder() +} + +@main +struct SwiftUIApp: App { + @UIApplicationDelegateAdaptor var delegate: AppDelegate + @Environment(\.scenePhase) var scenePhase: ScenePhase + + var defaultRouterContext: RouterContext { delegate.holder.defaultRouterContext } + + var body: some Scene { + WindowGroup { + HomeView(routerContext: defaultRouterContext) + } + .onChange(of: scenePhase) { newPhase in + switch newPhase { + case .background: defaultRouterContext.stop() + case .inactive: defaultRouterContext.pause() + case .active: defaultRouterContext.resume() + @unknown default: break + } + } + } +} + +struct HomeView: UIViewControllerRepresentable { + let routerContext: RouterContext + + func makeUIViewController(context: Context) -> UIViewController { + return ApplicationKt.HomeUIViewController(routerContext: routerContext) + } + + func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} +} + diff --git a/app/ios/ios/AppDelegate.swift b/app/ios/ios/UIKitAppDelegate.swift similarity index 93% rename from app/ios/ios/AppDelegate.swift rename to app/ios/ios/UIKitAppDelegate.swift index 6320ca5..8d62be7 100644 --- a/app/ios/ios/AppDelegate.swift +++ b/app/ios/ios/UIKitAppDelegate.swift @@ -2,7 +2,7 @@ import SwiftUI import app //@UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { +class UIKitAppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? var rootRouterContext = DefaultRouterContextKt.defaultRouterContext() diff --git a/decompose-router/src/iosMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt b/decompose-router/src/iosMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt index f38d381..bdda8ab 100644 --- a/decompose-router/src/iosMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt +++ b/decompose-router/src/iosMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt @@ -4,6 +4,7 @@ import com.arkivanov.essenty.backhandler.BackDispatcher import com.arkivanov.essenty.lifecycle.Lifecycle import com.arkivanov.essenty.lifecycle.LifecycleRegistry import com.arkivanov.essenty.lifecycle.destroy +import com.arkivanov.essenty.lifecycle.pause import com.arkivanov.essenty.lifecycle.resume import com.arkivanov.essenty.lifecycle.stop @@ -17,3 +18,4 @@ private val RouterContext.lifecycleRegistry: LifecycleRegistry get() = this.life fun RouterContext.destroy() = lifecycleRegistry.destroy() fun RouterContext.resume() = lifecycleRegistry.resume() fun RouterContext.stop() = lifecycleRegistry.stop() +fun RouterContext.pause() = lifecycleRegistry.pause() From bcf192f84341a84aa04401fdf518ef5146778ee4 Mon Sep 17 00:00:00 2001 From: xxfast Date: Sat, 21 Oct 2023 13:50:07 +1100 Subject: [PATCH 6/9] Update readme --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 43a8f6f..b96e320 100644 --- a/README.md +++ b/README.md @@ -231,10 +231,10 @@ class DetailInstance(savedState: SavedStateHandle, detail: String) : InstanceKee ``` > [!IMPORTANT] > You will need to tie root `RouterContext`'s lifecycle to an `AppDelegate`. - > See Kotlin app delegate [here](https://github.com/xxfast/Decompose-Router/blob/main/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/AppDelegate.kt), - > See Swift UIKit AppDelegate [here](https://github.com/xxfast/Decompose-Router/blob/main/app/ios/ios/AppDelegate.swift). - > See SwiftUI [here](https://github.com/xxfast/Decompose-Router/blob/main/app/ios/ios/App.swift). - > Read more on the docs [here](https://arkivanov.github.io/Decompose/getting-started/quick-start/#ios-with-swiftui) + > * See Kotlin app delegate [here](https://github.com/xxfast/Decompose-Router/blob/main/app/src/iosMain/kotlin/io/github/xxfast/decompose/router/app/AppDelegate.kt), + > * See Swift UIKit AppDelegate [here](https://github.com/xxfast/Decompose-Router/blob/main/app/ios/ios/UIKitAppDelegate.swift). + > * See SwiftUI App [here](https://github.com/xxfast/Decompose-Router/blob/main/app/ios/ios/SwiftUIApp.swift). + > * Read more on the docs [here](https://arkivanov.github.io/Decompose/getting-started/quick-start/#ios-with-swiftui)
From 815618fb8fc9ba76a16314db3aec1b34b4fde064 Mon Sep 17 00:00:00 2001 From: xxfast Date: Sun, 22 Oct 2023 14:32:29 +1100 Subject: [PATCH 7/9] Fix conflicting overloads --- .../io/github/xxfast/decompose/router/app/Application.kt | 2 +- .../xxfast/decompose/router/{ => js}/DefaultRouterContext.kt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) rename decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/{ => js}/DefaultRouterContext.kt (90%) diff --git a/app/src/jsMain/kotlin/io/github/xxfast/decompose/router/app/Application.kt b/app/src/jsMain/kotlin/io/github/xxfast/decompose/router/app/Application.kt index 5aef9ca..3d79caf 100644 --- a/app/src/jsMain/kotlin/io/github/xxfast/decompose/router/app/Application.kt +++ b/app/src/jsMain/kotlin/io/github/xxfast/decompose/router/app/Application.kt @@ -6,7 +6,7 @@ import io.github.xxfast.decompose.router.LocalRouterContext import io.github.xxfast.decompose.router.RouterContext import io.github.xxfast.decompose.router.app.screens.HomeScreen import io.github.xxfast.decompose.router.app.utils.BrowserViewportWindow -import io.github.xxfast.decompose.router.defaultRouterContext +import io.github.xxfast.decompose.router.js.defaultRouterContext import org.jetbrains.skiko.wasm.onWasmReady fun main() { diff --git a/decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt b/decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/js/DefaultRouterContext.kt similarity index 90% rename from decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt rename to decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/js/DefaultRouterContext.kt index 91f39af..ea7930e 100644 --- a/decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt +++ b/decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/js/DefaultRouterContext.kt @@ -1,9 +1,10 @@ -package io.github.xxfast.decompose.router +package io.github.xxfast.decompose.router.js import com.arkivanov.essenty.backhandler.BackDispatcher import com.arkivanov.essenty.lifecycle.LifecycleRegistry import com.arkivanov.essenty.lifecycle.resume import com.arkivanov.essenty.lifecycle.stop +import io.github.xxfast.decompose.router.RouterContext import kotlinx.browser.document import org.w3c.dom.Document From 323e6e2cd73747bb0626b998993db1cf3868d9a5 Mon Sep 17 00:00:00 2001 From: xxfast Date: Mon, 23 Oct 2023 09:23:21 +1100 Subject: [PATCH 8/9] Revert moving default context --- .../io/github/xxfast/decompose/router/app/Application.kt | 2 +- .../xxfast/decompose/router/{js => }/DefaultRouterContext.kt | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) rename decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/{js => }/DefaultRouterContext.kt (90%) diff --git a/app/src/jsMain/kotlin/io/github/xxfast/decompose/router/app/Application.kt b/app/src/jsMain/kotlin/io/github/xxfast/decompose/router/app/Application.kt index 3d79caf..5aef9ca 100644 --- a/app/src/jsMain/kotlin/io/github/xxfast/decompose/router/app/Application.kt +++ b/app/src/jsMain/kotlin/io/github/xxfast/decompose/router/app/Application.kt @@ -6,7 +6,7 @@ import io.github.xxfast.decompose.router.LocalRouterContext import io.github.xxfast.decompose.router.RouterContext import io.github.xxfast.decompose.router.app.screens.HomeScreen import io.github.xxfast.decompose.router.app.utils.BrowserViewportWindow -import io.github.xxfast.decompose.router.js.defaultRouterContext +import io.github.xxfast.decompose.router.defaultRouterContext import org.jetbrains.skiko.wasm.onWasmReady fun main() { diff --git a/decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/js/DefaultRouterContext.kt b/decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt similarity index 90% rename from decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/js/DefaultRouterContext.kt rename to decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt index ea7930e..91f39af 100644 --- a/decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/js/DefaultRouterContext.kt +++ b/decompose-router/src/jsMain/kotlin/io/github/xxfast/decompose/router/DefaultRouterContext.kt @@ -1,10 +1,9 @@ -package io.github.xxfast.decompose.router.js +package io.github.xxfast.decompose.router import com.arkivanov.essenty.backhandler.BackDispatcher import com.arkivanov.essenty.lifecycle.LifecycleRegistry import com.arkivanov.essenty.lifecycle.resume import com.arkivanov.essenty.lifecycle.stop -import io.github.xxfast.decompose.router.RouterContext import kotlinx.browser.document import org.w3c.dom.Document From d4c40385a9729f4fe3818db468b29f56f07d52b6 Mon Sep 17 00:00:00 2001 From: xxfast Date: Mon, 23 Oct 2023 09:28:48 +1100 Subject: [PATCH 9/9] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b96e320..4a57a9a 100644 --- a/README.md +++ b/README.md @@ -195,13 +195,10 @@ class DetailInstance(savedState: SavedStateHandle, detail: String) : InstanceKee **build.gradle.kts** ```kotlin fun main() { - val lifecycle = LifecycleRegistry() - val rootRouterContext = RouterContext(lifecycle = lifecycle) + val windowState: WindowState = rememberWindowState() + val rootRouterContext: RouterContext = defaultRouterContext(windowState = windowState) application { - val windowState: WindowState = rememberWindowState() - LifecycleController(lifecycle, windowState) - Window(state = windowState) { CompositionLocalProvider(LocalRouterContext provides rootRouterContext) { MaterialTheme { @@ -235,6 +232,9 @@ class DetailInstance(savedState: SavedStateHandle, detail: String) : InstanceKee > * See Swift UIKit AppDelegate [here](https://github.com/xxfast/Decompose-Router/blob/main/app/ios/ios/UIKitAppDelegate.swift). > * See SwiftUI App [here](https://github.com/xxfast/Decompose-Router/blob/main/app/ios/ios/SwiftUIApp.swift). > * Read more on the docs [here](https://arkivanov.github.io/Decompose/getting-started/quick-start/#ios-with-swiftui) + + > [!NOTE] + > To invoke decompose router's `defaultRouterContext()` from swift, you will need to export decompose-router from your shared module