Reputation: 1008
In my app, I use GeoFire
to query users around user location.
It is a Tinder-like app, with cards, etc... I use KolodaView
for cards.
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)
}
}
When I launch the app, the queryUsers
function is called, the query
starts
User 1XXXXXXXXXXXXXXXX found
Adding user 1XXXXXXXXXXXXXXXX
User 2XXXXXXXXXXXXXXXX found
Adding user 2XXXXXXXXXXXXXXXX
User added
User added
addUser
function)The problem is that it didn't wait the addUser
completion to call addUser
for the second user found. The result is that in my KolodaView
, there is the second user found two times
because I think the call of addUser
for the second user found uses first user found parameters.
Is it possible to wait for the first addUser
completion and start again the query ? Or just "pause" the query after the first user was found, and start it again after the completion of the first addUser
call ?
Thanks for your help
I tried the @Rlee128 solution but nothing changed, I have the same output :( :
// 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
}
Upvotes: 0
Views: 370
Reputation: 117
In then location manger didUpdateLocations set manager.delegate to = nil after you call manager.stopUpdatingLocation(). Let me know if you want me to show you how it looks in my code.
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)
}
Upvotes: 1