I have the following function which fetches data from Firebase, fills a compliments array and is suppose to pass the array back via the completion handler.
The array that is returned is always empty even though objects are added to it?
Have I placed the completion handler code in the wrong location, I have tried inserting within all the curly braces and nothing works.
Break point at handler(compliments, true) execution line outputs this:
0x0000000102bb3fe8 vipeeps`partial apply forwarder for closure #1 (Swift.Array<Any>, Swift.Bool) -> () in vipeeps.ConversationsListVC.loadNewInvitesData() -> () at ConversationsListVC.swift
Function:
func getComplimentsReceived(forUserId forId: String, handler: @escaping (_ complimentPack: [[String : Any]] ,_ success: Bool) -> ()){
var compliments = [[String : Any]]()//empty array to hold compliments
REF_USERS_COMPLIMENTS.child(forId).observe(.value) { (snapshot) in
for item in snapshot.children{
let itemSnap = item as! DataSnapshot
let dict = itemSnap.value as! [String : Bool]
for (key, status) in dict {
switch status {
case true:
//print(status)
self.REF_USERS.child(snapshot.key).observeSingleEvent(of: .value, with: { (snapshot) in
let uid = snapshot.key
let name = snapshot.childSnapshot(forPath: "name").value as! String
let email = snapshot.childSnapshot(forPath: "email").value as! String
let profilePictureURL = snapshot.childSnapshot(forPath: "profilePictureURL").value as! String
let birthday = snapshot.childSnapshot(forPath: "birthday").value as! String
let firstName = snapshot.childSnapshot(forPath: "firstName").value as! String
let lastName = snapshot.childSnapshot(forPath: "lastName").value as! String
let gender = snapshot.childSnapshot(forPath: "gender").value as! String
let discoverable = snapshot.childSnapshot(forPath: "discoverable").value as! Bool
let online = snapshot.childSnapshot(forPath: "online").value as! Bool
let discoveryPrefs = snapshot.childSnapshot(forPath: "discoveryPrefs").value as! [String : Any]
let dictionary: [String : Any] = ["uid": uid, "name": name, "email": email, "profilePictureURL": profilePictureURL, "birthday": birthday, "firstName": firstName, "lastName": lastName, "gender": gender, "discoverable": discoverable, "online": online, "discoveryPrefs": discoveryPrefs]
let user = User(uid: uid, dictionary: dictionary)
let complimentPack = [
"type": "compliment",
"complimentId": key,
"active": status,
"fromUser": user
] as [String : Any]
compliments.append(complimentPack)
print("compliments.count: \(compliments.count)")
})//end observer
case false:
print(status)
break
}//end switch
}//end for dict
}//end for snapshot.item
handler(compliments, true)
}//end observe
}//end func
Data structure:

handler(..)statement before the inner (asynchronous) closures are called. By the way: Why do you declarecomplimentsand the array parameter as unspecified[Any]although you clearly know that's more specified[[String:Any]]?? And the Swift 3+ syntax for a closure is@escaping ([Any] , Bool) -> ()without underscores and parameter labels.observeSingleEventworks asynchronously. The loop is executed instantly andhandler(..)is called a long time (in terms of computer speed) before the first closure passes itssnapshot.