Завершение запроса GeoFire - Swift

В моем приложении я использую 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
  1. Пользователь найден
  2. Добавление пользователя (звонок 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 ответ

В этом случае менеджер местоположения didUpdateLocations устанавливает manager.delegate в значение = nil после вызова manager.stopUpdatingLocation(). Дайте мне знать, если вы хотите, чтобы я показал вам, как это выглядит в моем коде.

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)

}
Другие вопросы по тегам