I am struggling with a function which I have made to take the selected annotation (didSelect view:), check the coordinate against all annotation coordinates in the database, and return the uid of the matching annotation.
However, I think I am making a mistake with my for loop, as it is not returning the value for use in the didSelect function. The searchForEvent function is called in didSelect view:, and checks the lat and long of the selected annotation against the database.
Heres the code:
func searchForEvent(latitude: CLLocationDegrees, longitude: CLLocationDegrees) -> String? {
var eventCoordinate: CLLocationCoordinate2D?
var eventKey: String?
var selectedEventKey = ""
DataService.instance.REF_EVENTS.observeSingleEvent(of: .value, with: { (snapshot) in
print("1")
if let eventSnapshot = snapshot.children.allObjects as? [DataSnapshot] {
for event in eventSnapshot {
eventKey = event.key
print("\(eventKey)")
print("2")
if event.childSnapshot(forPath: "coordinate").value != nil {
if let eventDict = event.value as? Dictionary<String, AnyObject> {
print("3")
//pull out value of key coordinate
let coordinateArray = eventDict["coordinate"] as! NSArray
print(coordinateArray)
eventCoordinate = CLLocationCoordinate2D(latitude: coordinateArray[0] as! CLLocationDegrees, longitude: coordinateArray[1] as! CLLocationDegrees)
print(eventCoordinate)
if (eventCoordinate?.latitude, eventCoordinate?.longitude) == (latitude, longitude) {
selectedEventKey = eventKey!
print("\(selectedEventKey), correct event")
} else {
print("incorrect event")
}
}
}
}
}
})
return selectedEventKey
// if selectedEventKey != nil {
// print("4")
// print("\(selectedEventKey)")
// return selectedEventKey
// } else {
// print("empty key")
// return nil
// }
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
print("selected")
self.selectedAnnotation = view.annotation
print(selectedAnnotation?.coordinate.latitude as Any)
print(selectedAnnotation?.coordinate.longitude as Any)
let lat = selectedAnnotation?.coordinate.latitude
let lon = selectedAnnotation?.coordinate.longitude
selectedAnnotationKey = searchForEvent(latitude: lat!, longitude: lon!)
if selectedAnnotationKey == nil {
print("no key")
} else {
print("found event final! \(selectedAnnotationKey)")
}
}
The selectedAnnotationKey is always nil in the didSelect function :(
Any help is greatly appreciated!
EDIT
Here is the updated function, thank you Sh_Khan for your help with it. While it is printing the right value in the debug area, it continues looping through the "events" in the database and returns nil at the end after finishing.
func searchForEvent(latitude: CLLocationDegrees, longitude: CLLocationDegrees , completion:@escaping(_ str:String?) -> Void ) {
var eventCoordinate: CLLocationCoordinate2D?
var eventKey: String?
var selectedEventKey = ""
DataService.instance.REF_EVENTS.observeSingleEvent(of: .value, with: { (snapshot) in
print("1")
if let eventSnapshot = snapshot.children.allObjects as? [DataSnapshot] {
for event in eventSnapshot {
eventKey = event.key
print("\(eventKey)")
print("2")
if event.childSnapshot(forPath: "coordinate").value != nil {
if let eventDict = event.value as? Dictionary<String, AnyObject> {
print("3")
//pull out value of key coordinate
let coordinateArray = eventDict["coordinate"] as! NSArray
print(coordinateArray)
eventCoordinate = CLLocationCoordinate2D(latitude: coordinateArray[0] as! CLLocationDegrees, longitude: coordinateArray[1] as! CLLocationDegrees)
print(eventCoordinate)
if (eventCoordinate?.latitude, eventCoordinate?.longitude) == (latitude, longitude) {
selectedEventKey = eventKey!
print("\(selectedEventKey), correct event")
completion(selectedEventKey)
} else {
print("incorrect event")
completion(nil)
}
}
}
}
}
})
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
print("selected")
self.selectedAnnotation = view.annotation
let lat = selectedAnnotation?.coordinate.latitude
let lon = selectedAnnotation?.coordinate.longitude
searchForEvent(latitude: lat!, longitude: lon!) { (str) in
self.selectedAnnotationKey = str
print("here it is \(str)")
print(self.selectedAnnotationKey)
}
}
And the debug printout:
selected
1
Optional("31E2932B-A037-4BB1-B93E-7504B61AC4E7")
2
3
(
"-36.84745654404946",
"174.7760903030886"
)
Optional(__C.CLLocationCoordinate2D(latitude: -36.847456544049464, longitude: 174.77609030308864))
incorrect event
here it is nil
nil
Optional("71173419-7E08-415C-9236-B1C8495A6BA9")
2
3
(
"-36.86687593953122",
"174.7585811441448"
)
Optional(__C.CLLocationCoordinate2D(latitude: -36.866875939531219, longitude: 174.75858114414478))
Below it finds the correct event, both str and self.selectedAnnotationKey are correct, but then keeps going and overwrites it!!!
71173419-7E08-415C-9236-B1C8495A6BA9, correct event
here it is Optional("71173419-7E08-415C-9236-B1C8495A6BA9")
Optional("71173419-7E08-415C-9236-B1C8495A6BA9")
Optional("7AC6429E-74B6-4A4E-A638-53981ACBFFBA")
2
3
(
"-36.2429468",
"175.3981152"
)
Optional(__C.CLLocationCoordinate2D(latitude: -36.242946799999999, longitude: 175.39811520000001))
incorrect event
here it is nil
nil
You need a completion
func searchForEvent(latitude: CLLocationDegrees, longitude: CLLocationDegrees , completion:@escaping(_ str:String?) -> Void ) {
var eventCoordinate: CLLocationCoordinate2D?
var eventKey: String?
var selectedEventKey = ""
DataService.instance.REF_EVENTS.observeSingleEvent(of: .value, with: { (snapshot) in
print("1")
if let eventSnapshot = snapshot.children.allObjects as? [DataSnapshot] {
for event in eventSnapshot {
eventKey = event.key
print("\(eventKey)")
print("2")
if event.childSnapshot(forPath: "coordinate").value != nil {
if let eventDict = event.value as? Dictionary<String, AnyObject> {
print("3")
//pull out value of key coordinate
let coordinateArray = eventDict["coordinate"] as! NSArray
print(coordinateArray)
eventCoordinate = CLLocationCoordinate2D(latitude: coordinateArray[0] as! CLLocationDegrees, longitude: coordinateArray[1] as! CLLocationDegrees)
print(eventCoordinate)
if (eventCoordinate?.latitude, eventCoordinate?.longitude) == (latitude, longitude) {
selectedEventKey = eventKey!
print("\(selectedEventKey), correct event")
completion(selectedEventKey)
} else {
print("incorrect event")
completion(nil)
}
}
}
}
}
})
}
//
To call
searchForEvent(//value1,//value2) { (str) in
print(str)
}