问题
I have a view that's receiving an ID value from the previous view. I need to also take that ID value and pass it into an ObservableObject so that I can run a Firestore query on that ID. I'm at a loss as to how to grab that ID for my ObservableObject.
struct ItemView: View {
   var itemName: String
   var itemID: String
   @ObservedObject var items = getItemsData()
   // ..... etc
   }
 class getItemsData() {
    @Published var data = [items]()
    init() {
       let db = Firestore.firestore()
       db.collection("items").whereField("itemID", isEqualTo: *THIS IS WHERE I NEED THE ITEMID *),addSnapshotListner {(snap, err) in ...
}
So in the query call, I need to call the ItemID value to query based on that value that's defined at the top of the view.
回答1:
I think your getItemsData class should inherit from ObservableObject
class GetItemsData: ObservableObject {...}
To get itemId into your GetItemsData instance, you can add a parameter to your init()
class GetItemsData: ObservableObject {
    init(itemId: String) {
        ...
    }
}
}
To tie it all together you have two choices. you could add an init to your ItemView like:
struct ItemView: View {
    let itemName: String
    let itemModel: GetItemsData
    init(itemName: String, itemID: String) {
        self.itemName = itemName
        itemModel = GetItemsData(itemId: itemID)
    }
}
I prefer instead to pass the observable object into the view, so it is more like a view model in MVVM
struct ItemView: View {
    let itemName: String
    let itemModel: GetItemsData
回答2:
if your ObservableObject has any state or is not located at top level view @tomcully way will end up with instantiating it with each parent view updating.
And also if you call an api inside init(), you will make many unnecessary api call.
You can do like this:
struct ItemView: View {
   var itemName: String
   var itemID: String
   @ObservedObject var items = getItemsData()
   var body: some View {
     ...
    .onAppear {
      items.setID(itemID)
    }
  }
}
class getItemsData: ObservedObject {
    let db = Firestore.firestore()
    @Published var data = [items]()
    var itemID: String = ""
    
    func setID(_ id: String) {
        if itemID != id {
            itemID = id
            db.collection("items").whereField("itemID", isEqualTo: itemID),addSnapshotListner {(snap, err) in ...
            }
        }
    }
}
Note: but even the above way, you cannot avoid instantiation of the ObservableObject with each parent view update, so if you don't want to it, you can use @StateObject(only ios 14 or above), or you can instantiate ObservableObject in different view and pass it as @environmentObject.
来源:https://stackoverflow.com/questions/60868330/swiftui-passing-a-variable-to-observable-object