Post

Replies

Boosts

Views

Activity

How to tackle Routing in a SwitUI app (aka Deep Linking)
This year we got great new APIs to push forward how we build apps with SwiftUI, from @StateObject to GridItem or Lazy*Stack, a bunch of other new views. All great additions. But there's something that I miss, I haven't seen documentation/examples on how should routing be managed in a SwiftUI app. How should deep link be tackled. For example, how should we manage: Opening an universal link Opening a push notification with a deeplink Continue User Activity: Navigating to a view opened with hand off. State restoration: Navigate to the view the user was at, after the app was close Do you have any examples on how should it be done? Or documentation on this topic? I'd love to see something in this regard. Thank you.
2
0
3.1k
Jun ’20
Load NavigationLink destination lazily
NavigationLink needs a constructed destination to work, as opposed to modals (.sheet/.fullScreenCover) where the destination is lazy. Creating views in SwiftUI is very light, but it's not the same when you're working with hundreds of entries on a list and each row creates its own NavigationLink(s), plus those views also create (on init or through a factory) their dependencies (ViewModel, DataModel, Logic, etc). This means every time the view is updated all the displayed NavigationLinks will be recreated, consuming a lot of resources that are not needed since those destination views could not ever be used if the user doesn't navigate there. Should we have a NavigationLink that takes a destination lazily, or is there something else I'm missing? In this regard, there's another issue which is views "popping" on a NavigationView don't get deallocated. This works just fine with modals, views presented modally deallocate as soon as the user go back, but it's not the case for views loaded using NavigationLink. I think it's related to the issue I described above. Is this intended behaviour? Thank you.
4
1
4.7k
Jun ’20
Is it possible to have another @main for testing?
Before, when we could check: let isRunningTests = NSClassFromString("XCTestCase") != nil And then load a "testing AppDelegate" instead of the app's one on main.swift, so you could avoid making extra configurations that just add overhead when running unit tests. I think it's not possible to have 2 @main structs, how should we achieve this now? Thank you.
1
0
511
Jun ’20
[SwiftUI] We can't inject @StateObject since it's read-only
@StateObject is read-only, so we can't inject it. The next block of code shows how we could inject 2 presenters through the init, which are then assigned to a @StateObject variable and a @ObservedObject variable. Notice: Assigning a value directly to a @StateObject works fine. (presenterStateWorking). Injecting a presenter that is then assigned to a @StateObject doesn't work. Throws an error in the init. (presenterStateNotWorking). Injecting a presenter that is then assigned to a @ObservedObject works fine. (presenterObserved). /* (You can drop this chunk of code in a playground) */ import SwiftUI import PlaygroundSupport class Presenter: ObservableObject {     @Published var viewModel = ViewModel(number: 42) } struct ViewModel: Equatable {     let number: Int } struct ContentView: View {     @StateObject var presenterStateWorking = Presenter()     @StateObject var presenterStateNotWorking: Presenter     @ObservedObject var presenterObserved: Presenter     init(presenter1: Presenter, presenter2: Presenter) {         self.presenterStateNotWorking = presenter1 /* (error thrown on this line) */         self.presenterObserved = presenter2     }     var body: some View {         VStack {             Text("Hi 🍎 Engineer 😊")                 .padding()         }     } } let view = ContentView(presenter1: Presenter(), presenter2: Presenter()) PlaygroundPage.current.liveView = UIHostingController(rootView: view) (Feedback issue number: FB7774103)
7
0
6.6k
Jun ’20