Joel Denke
05/25/2023, 7:53 AMArkadii Ivanov
05/25/2023, 8:40 AMDima Avdeev
05/25/2023, 10:24 AMJoel Denke
05/25/2023, 10:50 AMJoel Denke
05/25/2023, 10:51 AMJoel Denke
05/25/2023, 10:53 AMDima Avdeev
05/25/2023, 11:15 AMJoel Denke
05/25/2023, 12:03 PMJoel Denke
05/25/2023, 12:05 PMArkadii Ivanov
05/25/2023, 12:07 PMJoel Denke
05/25/2023, 12:07 PMJoel Denke
05/25/2023, 12:09 PMArkadii Ivanov
05/25/2023, 12:10 PMArkadii Ivanov
05/25/2023, 12:10 PMJoel Denke
05/25/2023, 12:11 PMJoel Denke
05/25/2023, 12:12 PMstruct ContentView: View {
var body: some View {
MainScreen {
TabView {
HomeScreen()
.tabItem {
Label("Home", systemImage: "house.fill")
}
TodoScreen()
.tabItem {
Label("Todo", systemImage: "list.bullet")
}.badge(2)
SearchScreen()
.tabItem {
Label("Search", systemImage: "magnifyingglass")
}
ProfileScreen()
.tabItem {
Label("Profile", systemImage: "person")
}
}
}.onOpenURL { url in
GIDSignIn.sharedInstance.handle(url)
}
.onAppear {
GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
// Check if `user` exists; otherwise, do something with `error`
}
}
}
}
But to be able to share this with Android, I also need to replace the NavHost thingy in androidx πArkadii Ivanov
05/25/2023, 12:12 PMJoel Denke
05/25/2023, 12:13 PMArkadii Ivanov
05/25/2023, 12:13 PMJoel Denke
05/25/2023, 12:13 PMJoel Denke
05/25/2023, 12:13 PMJoel Denke
05/25/2023, 12:14 PMJoel Denke
05/25/2023, 12:15 PMJoel Denke
05/25/2023, 12:15 PMArkadii Ivanov
05/25/2023, 12:16 PMJoel Denke
05/25/2023, 12:16 PMJoel Denke
05/25/2023, 12:17 PMJoel Denke
05/25/2023, 12:17 PMArkadii Ivanov
05/25/2023, 12:17 PMJoel Denke
05/25/2023, 12:17 PMJoel Denke
05/25/2023, 12:17 PMArkadii Ivanov
05/25/2023, 12:18 PMJoel Denke
05/25/2023, 12:19 PMJoel Denke
05/25/2023, 12:19 PMJoel Denke
05/25/2023, 12:19 PMJoel Denke
05/25/2023, 12:19 PMstruct ProfileScreen: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> some UIViewController {
return ScreenProvider.shared.createProfileScreenController()
}
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {}
}
Arkadii Ivanov
05/25/2023, 12:20 PMJoel Denke
05/25/2023, 12:20 PMNavHost(
modifier = Modifier.padding(it),
navController = navController,
startDestination = DirectionRoute.Home.route
) {
composable(DirectionRoute.Home.route) {
HomeScreen(homeViewModel)
}
composable(DirectionRoute.TodoList.route) {
TodoScreen(todoViewModel)
}
composable(DirectionRoute.Search.route) {
SearchScreen(searchViewModel)
}
composable(DirectionRoute.Profile.route) {
ProfileScreen(profileViewModel)
}
}
Joel Denke
05/25/2023, 12:20 PMJoel Denke
05/25/2023, 12:22 PMJoel Denke
05/25/2023, 12:22 PMJoel Denke
05/25/2023, 12:32 PMArkadii Ivanov
05/25/2023, 12:34 PMJoel Denke
05/25/2023, 12:35 PMJoel Denke
05/25/2023, 12:35 PMvar body: some View {
StackView(
stackValue: ObservableValue(component.stack),
onBack: component.onBackClicked
) { child in
switch child {
case let child as ConferenceComponentChild.Home: HomeView(child.component)
case let child as ConferenceComponentChild.SessionDetails: SessionDetailsView(child.component)
case let child as ConferenceComponentChild.SpeakerDetails: SpeakerDetailsView(child.component)
default: EmptyView()
}
}
}
Then would be possible sharing the code back into compose with Android, by decouple the navigation controller between iOS and Android, when click on tabs so both can observe same logic πJoel Denke
05/25/2023, 12:37 PMArkadii Ivanov
05/25/2023, 12:38 PMJoel Denke
05/25/2023, 12:39 PMJoel Denke
05/25/2023, 12:41 PMProper dependency injection (DI) and inversion of control (IoC) via constructor, including but not limited to type-safe arguments.
Lifecycle-aware components
Components in the back stack are not destroyed, they continue working in background without UI
Like this I dont want to have inherited from it π Then get into same issue again as had with androidx πJoel Denke
05/25/2023, 12:42 PMJoel Denke
05/25/2023, 12:42 PMJoel Denke
05/25/2023, 12:48 PMJoel Denke
05/25/2023, 2:07 PMclass AndroidNavigationController(private val navController: NavController): MyNavigationController {
override fun navigateTo(direction: DirectionRoute) {
navController.navigate(direction.route) {
launchSingleTop = true
restoreState = true
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
}
}
override fun currentPath(): CommonFlow<String> {
return navController.currentBackStackEntryFlow
.mapLatest { it.destination.route.orEmpty() }
.asCommonFlow()
}
}
I am doing the equivalent in iOS but more simple of just forward the navigateTo directly to currentPath() and observe in Swift:
struct ContentView: View {
@State private var selection: String? = nil
init() {
SharedController.shared.navigationPathSelected.watch { path in
self.selection = path
}
}
var body: some View {
MainScreen {
NavigationView {
VStack {
NavigationLink(destination: Text("Home"), tag: "home", selection: $selection) {
HomeScreen()
}
NavigationLink(destination: Text("Todo"), tag: "todo", selection: $selection) {
TodoScreen()
}
}
.navigationTitle("Navigation")
}
}.onOpenURL { url in
GIDSignIn.sharedInstance.handle(url)
}
.onAppear {
GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
}
}
}
}
This is the maximum possible shared code I can do I think with limitation we have at the moment π Leverage both NavigationView in iOS and NavigationHost in Androidx/Android π
Then have decoupled the logic and compose code from all of this mayhem π
If having any smarter way of observing Kotlin FLow in Swift let me know, or such.
Just sharing here if someone else struggle with same as me.