GeoFire 查询完成 - Swift

Posted

技术标签:

【中文标题】GeoFire 查询完成 - Swift【英文标题】:GeoFire query completion - Swift 【发布时间】:2017-05-20 11:59:02 【问题描述】:

在我的应用程序中,我使用GeoFire 来查询用户位置周围的用户。 这是一个类似于 Tinder 的应用程序,有卡片等...我使用 KolodaView 表示卡片。

查询功能:

func queryUsers(searchRadius: Int, center: CLLocation) 

    print("Query started")

    let geofireRef = Database.database().reference().child("usersLocations")
    let geoFire = GeoFire(firebaseRef: geofireRef)

    let circleQuery = geoFire?.query(at: center, withRadius: Double(searchRadius))

    _ = circleQuery?.observe(.keyEntered, with:  (result, location) in

        print("User \(result!) found")
        print("Adding user \(result!)")

        addUser(userID: result!, completionHandler:  (success) in

            print("User added")

        )

    )


添加用户功能:

func addUser(userID: String, completionHandler:@escaping (Bool) -> ()) 

    let foundUsers = UserDefaults.standard.array(forKey: "foundUsers")

    let databaseRef = Database.database().reference()

    databaseRef.observeSingleEvent(of: .value, with:  (snapshot) in

        if (foundUsers?.count)! < 20 

            // USERS

            let users = (snapshot.value as? NSDictionary)?["users"] as! NSDictionary

            // USER

            let user = users[userID] as! NSDictionary

            getFirstUserPicture(userID: userID, completionHandler:  (data) in

                if let data = data 

                    DispatchQueue.main.async 

                        user.setValue(data, forKey: "picture")

                        // APPEND FOUND USERS ARRAY

                        var foundUsers = UserDefaults.standard.array(forKey: "foundUsers")

                        foundUsers?.append(user)

                        // STORE FOUND USERS ARRAY

                        UserDefaults.standard.set(foundUsers, forKey: "foundUsers")
                        UserDefaults.standard.synchronize()

                        // UPDATE CARD VIEW

                        if foundUsers?.count == 1 

                            NotificationCenter.default.post(name: .loadCardView, object: nil)

                         else 

                            NotificationCenter.default.post(name: .loadCardsInArray, object: nil)

                        

                        // COMPLETION

                        completionHandler(true)

                    

                

            )

        

    )  (error) in

        print(error.localizedDescription)

    


当我启动应用程序时,queryUsers 函数被调用,查询 开始

输出

User 1XXXXXXXXXXXXXXXX found
Adding user 1XXXXXXXXXXXXXXXX
User 2XXXXXXXXXXXXXXXX found
Adding user 2XXXXXXXXXXXXXXXX
User added
User added
    找到用户 添加用户(调用addUser函数)

问题是它没有等待addUser 完成为找到的第二个用户调用addUser。结果是在我的KolodaView中,有第二个用户被找到了两次 因为我认为addUser 对找到的第二个用户的调用使用了第一个用户找到的参数。

是否可以等待第一个addUser 完成并重新开始查询?还是在找到第一个用户后“暂停”查询,并在第一个addUser 调用完成后重新开始?

感谢您的帮助

更新 1

我尝试了@Rlee128 解决方案,但没有任何改变,我有相同的输出:( :

// MARK: UPDATE USER LOCATION - FUNCTION

func updateUserLocation() 

    let databaseRef = Database.database().reference().child("usersLocations")
    let geoFire = GeoFire(firebaseRef: databaseRef)

    let userID = UserDefaults.standard.string(forKey: "userID")!

    let locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.startUpdatingLocation()

    geoFire?.setLocation(locationManager.location, forKey: userID, withCompletionBlock:  (error) in

        if error != nil 

            print(error as Any)

         else 

            // Location updated

        

    )




// MARK: LOCATION MANAGER DELEGATE - FUNCTION

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) 

    manager.stopUpdatingLocation()
    manager.delegate = nil


【问题讨论】:

【参考方案1】:

在调用 manager.stopUpdatingLocation() 之后,位置管理器 didUpdateLocations 将 manager.delegate 设置为 = nil。如果您希望我向您展示它在我的代码中的外观,请告诉我。

func findLocation() 
    locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest

    locationManager.requestAlwaysAuthorization()

    if CLLocationManager.locationServicesEnabled() 
        locationManager.startUpdatingLocation()
    


func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) 
    let userLocation = locations[0] as CLLocation
    manager.stopUpdatingLocation()
    manager.delegate = nil
    let loc = CLLocation(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
    getLocation(location: loc)


【讨论】:

以上是关于GeoFire 查询完成 - Swift的主要内容,如果未能解决你的问题,请参考以下文章

Android geofire获取一定半径内的用户列表

如何在 Swift 中为以下观察删除 GeoFire 句柄?

如何在 Swift 中为以下观察删除 GeoFire 句柄?

如何在 Swift 中使用 Geofire 从一个模拟器存储位置,然后在另一个模拟器中显示该位置。

解析查询后 Swift 数组为空 - 完成处理程序?

iOS Swift:查询完成后将数据传递给其他 VC 的最佳方式