在我的应用中,我使用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
调用后再次启动它?
感谢您的帮助
我尝试了@ 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
}
答案 0 :(得分: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)
}