Вызов init () - лучший способ получить данные firebase? - PullRequest
0 голосов
/ 10 июля 2020

У меня есть 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()?

UPDATE

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

1 Ответ

1 голос
/ 10 июля 2020

В таком случае было бы целесообразно сделать это в 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

...