swift - 调用 init() 以查看提取 firebase 数据的最佳方式?
问题描述
我有一个SearchView()
struct SearchView: View {
@ObservedObject var searchViewModel = SearchViewModel()
init() {
searchViewModel.LoadAllUsers()
}
var body: some View {
NavigationView {
VStack {
List {
ForEach(searchViewModel.allUsers, id: \.uid) { user in
......
}
}
}
}
}
在我的SearchViewModel
我有一个函数可以从firebase获取所有用户并将它们存储在@Published
allUsers
数组中:
@Published var allUsers: [User] = []
func LoadAllUsers() {
Firestore.firestore().collection("users").document(Auth.auth().currentUser!.uid).getDocument{(snapshot, error) in
....
}
每次我单击SearchView()
它正在运行并运行该函数并调用 firebase 并获取数据时。这是最好的方法吗?从长远来看,这会增加firebase的成本吗?有没有办法在每次加载应用程序时而不是每次加载时调用此函数SearchView()
?
更新
var window: UIWindow?
var searchViewModel = SearchViewModel()
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
// Create the SwiftUI view that provides the window contents.
//let contentView = ContentView()
searchViewModel.LoadAllUsers()
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: InitialView().environmentObject(SessionStore()).environmentObject(searchViewModel))
self.window = window
window.makeKeyAndVisible()
}
}
在我的 SearchViewModel 中,由于以下原因而出现问题:
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
由于以下原因:
Auth.auth().currentUser!.uid
解决方案
在这种情况下,将其SceneDelegate
作为环境对象放入并注入层次结构中是合适的,例如
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var searchViewModel = SearchViewModel() // create
...
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
searchViewModel.LoadAllUsers() // << preload !!
...
let contentView = ContentView().environmentObject(searchViewModel) // << inject !!
和
struct SearchView: View {
@EnvironmentObject var searchViewModel: SearchViewModel // << use !!
// nothing in init
推荐阅读
- python - 我的 SpamBot 项目有问题,即使我按照教程进行操作,它也没有做任何事情
- r - 清洁地址 - 根据其他记录在缺少的街道名称(Ave、St、..)中添加最后一个标记
- redis - redis如何获得带有分数的排序集成员?
- java - OSGi - 捆绑更新后的 NoClassDefFoundError
- python - 动态编程脚本,用于求和数字的最佳方法
- ios - 你可以通过使用expo在windows上连接ios设备来为ios开发吗
- java - 如何用java将图像裁剪成圆形?
- c - zlib 在压缩前获取 gzip-file-size
- laravel - 为什么 laraval 路由返回对象而不是回显它或直接打印它?
- yaml - 如何简化 Azure 管道并避免大量重复