0

I have an app that deep links, so first I have a loading or home view rendered:

@main
struct AppMain: App {
    
    var body: some Scene {
        WindowGroup {
            LoadingView()
                .onContinueUserActivity(NSUserActivityTypeBrowsingWeb, perform: handleUserActivity)
        }
    }
}

However, in my handleUserActivity that responds to the activity, how do I update the screen based on the activity parameters? For example, I've extracted a value and would like to render the view from here:

private extension AppMain {
    
    func handleUserActivity(_ userActivity: NSUserActivity) {
        guard let url = userActivity.webpageURL,
              let components = NSURLComponents(url: url, resolvingAgainstBaseURL: true),
              let queryItems = components.queryItems
        else {
            return
        }
        
        if let modelID = queryItems.first(where: { $0.name == "id" })?.value {
            SmoothieView(id: modelID) // TODO: How to I render view??
        }
    }
}

How can I replace the LoadingView and display the SmoothieView?

TruMan1
  • 33,665
  • 59
  • 184
  • 335

1 Answers1

2

Here is a possible approach - use app state object and observer in top view to switch depending on state.

(Note: code is typed in place, so might be typos)

class AppState: ObservableObject {
   @Published var modelID: String?
}

@main
struct AppMain: App {
    @StateObject var appState = AppState()

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(appState)
                .onContinueUserActivity(NSUserActivityTypeBrowsingWeb, perform: handleUserActivity)
        }
    }
}

private extension AppMain {
    
    func handleUserActivity(_ userActivity: NSUserActivity) {
        guard let url = userActivity.webpageURL,
              let components = NSURLComponents(url: url, resolvingAgainstBaseURL: true),
              let queryItems = components.queryItems
        else {
            return
        }
        
        if let modelID = queryItems.first(where: { $0.name == "id" })?.value {

            self.appState.modelID = modelID // << here !!

        }
    }
}

// as soon as you receive model id the view will be refreshed
struct ContentView: View {
   @EnvironmentObject var appState: AppState

   var body: some View {
      if appState.modelID == nil {
         LoadingView()
      } else {
         SmoothieView(id: appState.modelID!)
      }
   }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690