1

In a SwiftUI app, I am facing a new challenge and hope someone can give me some hints or guidance. The mechanisms I have seen up to now to communicate between the parts of an app don't seem to quite fit here. But it is probably due to my still limited experience with SwiftUI.

First here is the relevant code:

class SceneDelegate {
  ... lot of code irrelevant to the question ...
  func scene(_ scene: UIScene, 
             continue userActivity: NSUserActivity) {
      ... useful things happening for the app ...
      // Now the view should change ... by some mechanism.
      // This is the point of the question.
  }
}

and:

struct ContentView: View {
    ... lot of code irrelevant to the question ...
    var body: some View {
        VStack {
          ... code to draw the view ...
        }
        ... more code to draw the view ...
    }
}

Second, my question is: how do I make my view to redraw itself, after processing has been performed inside scene(:continue ?

I had in mind some ideas, to do things in the scene(:continue function which would influence the drawing of the view.

Unfortunately, when trying to implement, I realized the code drawing the view was executed before the scene(:continue function. Therefore I need some other mechanism (notification like, bindings like, or ??) to have the view redrawn.

Is there a good practice or standard way of doing that?

Michel
  • 10,303
  • 17
  • 82
  • 179
  • Implement a root view (that sits above your `ContentView`) that displays some loading state, until .`onReceive` or until some environment variables changes, and then it would render the `ContentView` – New Dev Aug 14 '20 at 03:24

1 Answers1

2

It would be appropriate to use EnvironmentObject in this scenario

class AppState: ObservableObject
   @Published var someVar: Sometype
}

class SceneDelegate {
  let appState = AppState()

  func scene(_ scene: UIScene, 
             continue userActivity: NSUserActivity) {

     // ... other code 
     appState.someVar = ... // modify
  }
}

  func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

     // .. other code
    let contentView = ContentView()
        .environmentObject(appState)
     //
  }
}

struct ContentView: View {
    @EnvironmentObject var appState

    var body: some View {
        VStack {
            // ... other code
            appState.someVar // use here as needed
        }
    }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690
  • I am working to implement your suggestion. The last part (using appState.someVar inside ContentView) is the most difficult. Because as you know it is not possible to put an if statement in the middle of nowhere (in this kind of code), without making the compiler angry. I am now trying to figure out where I can put it to make things work. – Michel Aug 14 '20 at 05:44