Skip to content

Commit

Permalink
Recreate the iOS app UI on a new deep link incoming
Browse files Browse the repository at this point in the history
With this change whenever a deep link is received, we create a
completely new AppComponent so that we start from a clean slate.
In order to be able to observe this change from SwiftUI we also store a
local @State object which we increment at the same time in order to
trigger a re-render of the View.
This is absolutely a hack and we should find a better approach as soon
as possible
  • Loading branch information
StylianosGakis committed Apr 7, 2024
1 parent aec1b4e commit 48f0fea
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 10 deletions.
12 changes: 11 additions & 1 deletion iosApp/iosApp/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import ConfettiKit

class AppDelegate : NSObject, UIApplicationDelegate {

let root: AppComponent
var root: AppComponent

override init() {
KoinKt.doInitKoin()
Expand All @@ -24,4 +24,14 @@ class AppDelegate : NSObject, UIApplicationDelegate {
initialConferenceId: nil
)
}

func onConferenceDeepLink(conferenceId: String) {
root = DefaultAppComponent(
componentContext: DefaultComponentContext(lifecycle: ApplicationLifecycle()),
onSignOut: {},
onSignIn: {},
isMultiPane: UIDevice.current.userInterfaceIdiom != UIUserInterfaceIdiom.phone,
initialConferenceId: conferenceId
)
}
}
18 changes: 17 additions & 1 deletion iosApp/iosApp/iOSApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ struct iOSApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self)
var appDelegate: AppDelegate

@State
private var reRenderIndex: Int = 0

var body: some Scene {
WindowGroup {
EmptyView(reRenderIndex: reRenderIndex)
ConfettiApp(appDelegate.root)
.onOpenURL(perform: { url in
let pathComponents = url.pathComponents
Expand All @@ -21,7 +25,8 @@ struct iOSApp: App {
for char in conferenceId {
if !char.isLetter && !char.isNumber { return }
}
appDelegate.root.onConferenceDeepLink(conferenceId: conferenceId)
appDelegate.onConferenceDeepLink(conferenceId: conferenceId)
reRenderIndex += 1
})
}
.onChange(of: phase) { newPhase in
Expand All @@ -41,3 +46,14 @@ func scheduleDataRefresh() {
request.earliestBeginDate = .now.addingTimeInterval(24 * 3600)
try? BGTaskScheduler.shared.submit(request)
}

/**
This view exists so that there is a way for us to read the change in `@State reloadIndex`, so that the view will try to re-render itself and pick up the latest value from appDelegate.root. This is done since `AppComponent` is not an object that can be observed by SwiftUI in some way, so this workaround was added.
*/
private struct EmptyView: View {
var reRenderIndex: Int

var body: some View {
Group {}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ import org.koin.core.component.inject
interface AppComponent {
val stack: Value<ChildStack<*, Child>>

fun onConferenceDeepLink(conferenceId: String)

sealed class Child {
object Loading : Child()
class Conferences(val component: ConferencesComponent) : Child()
Expand Down Expand Up @@ -80,12 +78,6 @@ class DefaultAppComponent(
}
}

override fun onConferenceDeepLink(conferenceId: String) {
coroutineScope.launch {
selectAndNavigateToDeepLinkedConference(conferenceId)
}
}

private suspend fun selectAndNavigateToDeepLinkedConference(conferenceId: String) {
// todo, consider changing how conference theme colors are decided so that only knowing the conference
// ID is enough to also get the right color
Expand Down

0 comments on commit 48f0fea

Please sign in to comment.