与Firestore侦听器分离

Mar*_*tin 1 ios firebase swift google-cloud-firestore

我正在将Firestore与Swift一起使用。

我有一个单例数据类UserManager。我从不同的ViewControllers调用它来获取数据以填充表视图。我希望表视图在集合更新时自动更新,因此我需要使用SnapshotListener。一切正常,但是我不确定在关闭Viewcontroller时如何从侦听器分离。

在单例类中,下面有这样的方法。该方法提供了一个用户列表,将在我的应用程序中的多个不同位置调用该方法。

我还想返回对侦听器的引用,以便在关闭Viewcontroller时可以将其分离。但是我无法正常工作。以下解决方案给出了编译器错误。

我一直在尝试查看参考,例如在这里 https://firebase.google.com/docs/firestore/query-data/listen,但是当数据加载到单例类中时,我需要使其工作直接在Viewcontroller中。去这里的路是什么?

在UserManager中:

func allUsers(completion:@escaping ([User], ListenerRegistration?)->Void) {
    let listener = db.collection("users").addSnapshotListener { querySnapshot, error in
        if let documents = querySnapshot?.documents {
            var users = [User]()
            for document in documents {
                let user = User(snapshot: document)
                users.append(user)
            }
            completion(users, listener)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在ViewController中:

override func viewDidLoad() {
    super.viewDidLoad()
    UserManager.shared.allUsers(completion: { (users, listener) in
        self.users = users
        self.listener = listener
        self.tableView.reloadData()
    })
}

deinit {
    self.listener.remove()
}
Run Code Online (Sandbox Code Playgroud)

Mih*_*atu 7

您看到的编译器错误是指您在listener其自己的定义上下文中使用的事实。

尝试以下更改:

在UserManager中:

func allUsers(completion:@escaping ([User])->Void) -> ListenerRegistration? {
    return db.collection("users").addSnapshotListener { querySnapshot, error in
        if let documents = querySnapshot?.documents {
            var users = [User]()
            for document in documents {
                let user = User(snapshot: document)
                users.append(user)
            }
            completion(users)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在ViewController中:

override func viewDidLoad() {
    super.viewDidLoad()
    self.listener = UserManager.shared.allUsers(completion: { (users) in
        self.users = users
        self.tableView.reloadData()
    })
}

deinit {
    self.listener.remove()
}
Run Code Online (Sandbox Code Playgroud)