Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Geofire/Firebase函数正在swift中多次执行处理程序_Swift_Firebase_Geofire - Fatal编程技术网

Geofire/Firebase函数正在swift中多次执行处理程序

Geofire/Firebase函数正在swift中多次执行处理程序,swift,firebase,geofire,Swift,Firebase,Geofire,我有下面的函数,它使用Geofire获取用户列表,然后在嵌套设置中使用Firebase查询 我首先执行Geofire查询以获取键,然后执行Firebase查询并创建与键匹配的用户对象,将用户附加到数组中,然后通过处理程序传回 用户数组然后在集合视图中使用,问题是当显示集合视图时,它只显示一个用户对象 我在代码中放置了一些print()行以进行调试,并发现每次添加项时,函数都通过handler传递数据,因此在到达时数组的计数达到VC,它显示CollectionViewis1 将下一行移动到循环的外

我有下面的函数,它使用Geofire获取用户列表,然后在嵌套设置中使用Firebase查询

我首先执行Geofire查询以获取
,然后执行Firebase查询并创建与
匹配的
用户
对象,将
用户
附加到数组中,然后通过
处理程序传回

用户
数组
然后在
集合视图
中使用,问题是当显示
集合视图
时,它只显示一个
用户
对象

我在代码中放置了一些
print()
行以进行调试,并发现每次添加项时,函数都通过
handler
传递数据,因此在到达时数组的计数达到
VC
,它显示
CollectionView
is
1

将下一行移动到循环的
外部
括号传递一个空的
数组

如何更新我的函数,以便只调用一次
处理程序
,并传递完整的
数组

handler(self.shuffleArray(array: filteredUsers) as! [User], true)
以下是函数:

    //Fetches all users currently at a Venue location of radius 50 metres
func getUsersAtVenue(forVenueLocation venueLocation: CLLocation, forUid uid: String, handler: @escaping (_ users: [User], _ success: Bool) -> ()){

    print("uid: \(uid)")

    var users = [User]()

    guard let currentLocation = LocationSingleton.sharedInstance.lastLocation else { return}//get current user's (device) location

    let distanceApart = round(10 * (venueLocation.distance(from: currentLocation) / 1000)) / 10 //get distance between currentLocation and venueLocation and convert from Mts to Kms rounding to 2 decimals

    if distanceApart <= 50 { //if distance apart if within 50kms then proceed

        let query = self.GEOFIRE_USERS_LOC.query(at: currentLocation, withRadius: 50)//radius in Kms

        query.observe(.keyEntered) { (key: String!, userLocation: CLLocation!) in

            print(key)

            self.REF_USERS.observeSingleEvent(of: .value, with: { (snapshot) in

                guard let usersSnapshot = snapshot.children.allObjects as? [DataSnapshot] else { return }

                for user in usersSnapshot{

                    let discoverable = user.childSnapshot(forPath: "discoverable").value as! Bool

                    if user.key == key && discoverable == true {

                        let uid = user.key
                        let name = user.childSnapshot(forPath: "name").value as! String
                        let email = user.childSnapshot(forPath: "email").value as! String
                        let profilePictureURL = user.childSnapshot(forPath: "profilePictureURL").value as! String

                        let birthday = user.childSnapshot(forPath: "birthday").value as! String
                        let firstName = user.childSnapshot(forPath: "firstName").value as! String
                        let lastName = user.childSnapshot(forPath: "lastName").value as! String
                        let gender = user.childSnapshot(forPath: "gender").value as! String
                        let discoverable = user.childSnapshot(forPath: "discoverable").value as! Bool
                        let online = user.childSnapshot(forPath: "online").value as! Bool

                        let dictionary: [String : Any] = ["uid": uid, "name": name, "email": email, "profilePictureURL": profilePictureURL, "birthday": birthday, "firstName": firstName, "lastName": lastName, "gender": gender, "discoverable": discoverable, "online": online]

                        let user = User(uid: uid, dictionary: dictionary)

                        users.append(user)

                    }//end if

                }//end for

                //filter out current user from array
                let filteredUsers = users.filter({ (user: User) -> Bool in return !user.uid.contains(uid) })

                print("filteredUsers count: \(filteredUsers.count)")

                //handler passing a shuffled version of the array
                handler(self.shuffleArray(array: filteredUsers) as! [User], true)

            })//end FIR snapshot call

        }//end geoquery


    } else {//if distanace apart is NOT within 50kms then do this
        print("You're too far apart.")
        handler(users, false)
    }



}//end func

对于geoquery范围内的每个键,都会触发
.keyEntered
事件。所以,最初这意味着它会为范围内的所有关键点触发,从那一刻起,它将在新关键点进入范围时触发(即,如果您在范围内添加新用户,或者如果用户移动到范围内)

听起来您想检测所有初始用户何时调用了
.keyEntered
。因此,您可以观察ready事件

query.observeReadyWithBlock({
    //handler passing a shuffled version of the array
    handler(self.shuffleArray(array: filteredUsers) as! [User], true)
})
如果您对在初始查询后获取新用户/移动用户的更新不感兴趣,那么现在也是通过调用
removeObserverWithFirebaseHandle
removeAllObserver
来删除您的观察者的好时机


另请参见Geofire文档。

我确实希望在新用户进入和离开查询范围时获得更新,并相应地更新视图。我有一种感觉,我没有为此正确地构建代码。我调用上面的函数,然后将数组传递给VC,VC显示CollectionView,而CollectionView只能看到数组中的一个对象。如何构造显示CollectionView的VC以直接调用上面的函数,然后在数据更改时重新加载?
query.observeReadyWithBlock({
    //handler passing a shuffled version of the array
    handler(self.shuffleArray(array: filteredUsers) as! [User], true)
})