You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将Firebase获取的数据从Model传递到SwiftUI View时数组为空如何解决

问题根源

Firestore 的 addSnapshotListener 是异步回调接口,你当前的代码在调用 fetchData 后立刻同步读取 foodEvents 构造坐标数组,此时网络请求还没有返回,数据还没完成填充,所以拿到的永远是空数组。等后续异步回调触发、数据实际加载完成后,你也没有对应的逻辑去更新需要传递给 View 的 eventLocations 属性,所以 View 感知不到数据变化。

修复方案

1. 修正 ViewModel 逻辑,把数组更新操作放到异步回调内

class FoodEventViewModel: ObservableObject {
  @Published var foodEvents = [FoodEvent]()
  @Published var eventLocations = [CLLocationCoordinate2D]()
  private var db = Firestore.firestore()

  init() {
    fetchData()
  }

  func fetchData() {
    let ref = db.collection("Food Submissions").order(by: "dateCreated", descending: true)
    // 加[weak self]避免循环引用
    ref.addSnapshotListener { [weak self] (querySnapshot, error) in
      guard let self = self, let documents = querySnapshot?.documents else {
        print("加载失败: \(error?.localizedDescription ?? "未知错误")")
        return
      }
      
      // 解析数据
      self.foodEvents = documents.compactMap { try? $0.data(as: FoodEvent.self) }
      // 数据加载完成后直接构造坐标数组,赋值给@Published属性
      self.eventLocations = self.foodEvents.map { 
        CLLocationCoordinate2D(latitude: $0.latitude, longitude: $0.longitude)
      }
    }
  }
}

修改说明:

  • 移除冗余的临时变量 events,直接解析有效数据赋值给 foodEvents
  • 坐标数组的构造逻辑移到异步回调末尾,保证只有数据加载完成后才会更新 eventLocations
  • 只要 @Published 标记的属性发生变更,SwiftUI 会自动通知关联的 View 刷新

2. 简化 View 逻辑,利用 SwiftUI 响应式特性自动刷新

struct FoodMapView: View {
  @EnvironmentObject var lm: LocationManager
  // iOS14及以上推荐用@StateObject代替@ObservedObject,避免View重绘时ViewModel被意外销毁
  @StateObject var viewModel = FoodEventViewModel()
  
  var body: some View {
    ZStack(alignment: .top) {
      // eventLocations更新后会自动传给MapView刷新
      MapView(locs: viewModel.eventLocations)
    }
    .navigationTitle("Map")
    // 可选添加空状态占位,优化加载体验
    .overlay {
      if viewModel.eventLocations.isEmpty {
        ProgressView("位置加载中...")
      }
    }
  }
}

修改说明:

  • 移除 onAppear 里的手动调用,ViewModel 初始化时已经会触发数据请求
  • 用 @StateObject 持有 ViewModel,保证 View 生命周期内 ViewModel 不会被意外重建

内容的提问来源于stack exchange,提问作者8bitwonder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 16:15:04