问题
I need to open a view called PackageDetails
.
There are two cases in which this view could be opened.
1. If you tap a specific Package from a list of packages.
I have an array of all the packages. So I'm passing the specific struct from this list and I'm opening this package view.PackageDetail(package: package)
. I already have all the data I need so I do not need to make an extra call to Firestore to fetch this document.
2. Package view can be opened by a link from some other view in this app.
In this case I do not have all the details of this specific Package but I have just a reference to the Firestore document. I am using this reference to make a query as soon as this view appears and get the details about this Package PackageDetail(package: packageReference)
The ways I'm doing this is by declaring Package as an Optional @State var package: PackageModel?
and onAppear I'm checking if the Package is null or not.
.onAppear {
if let package = self.package {
// package data exists
} else {
// fetch it from firestore
}
}
The question is: Am I doing this right? Is this the best approach?
回答1:
The Package
is not view state, so @State
, by design does not fit here. Instead it is preferable to use view model pattern, so the approach (scratchy) might be like below:
class PackageViewModel: ObservableObject {
@Published var packageReference: URL?
@Published var package: PackageModel?
init(package: PackageModel? = nil, reference: URL? = nil) {
self.package = package
self.packageReference = reference
}
private func loadPackage() {
// do load here from 'self.packageReference' and in callback assign package created from result
DispatchQueue.main.async {
self.package = package
}
}
}
struct PackageView: View {
@ObservedObject var vm: PackageViewModel
var body: some View {
VStack {
// some main part here
if vm.package != nil {
PackageDetail(package: self.vm.package)
}
}
.onAppear {
if self.vm.package == nil {
self.vm.loadPackage()
}
}
}
}
来源:https://stackoverflow.com/questions/60688040/swiftui-open-view-with-data-or-only-with-a-reference-to-firestore-document