У меня возникла проблема, когда у меня есть несколько асинхронных запросов, которые захватывают изображения и информацию из API Facebook и моей базы данных Firebase. Я хочу выполнить все мои асинхронные запросы, а затем сохранить все данные, которые я захватил из базы данных Facebook API/Firebase, в один объект, который я могу быстро загрузить. Я настроил обработчики завершения для каждого асинхронного запроса, который, как я думал, заставляет программу "ждать" до тех пор, пока запрос не будет завершен, а затем продолжит работу, но это, похоже, не работает для меня. Ниже приведена моя попытка:
func setupEvents(completion: (result: Bool, Event: Event) -> Void){
// Get a reference to Events
eventsReference = Firebase(url:"<DB Name>")
eventAttendeesRef = Firebase(url:"<DB Name>")
//Read the data at our posts reference
println("Event References: \(eventsReference)")
eventsReference.observeEventType(FEventType.ChildAdded, withBlock: { (snapshot) -> Void in
let eventName = snapshot.value["eventName"] as? String
let eventLocation = snapshot.value["eventLocation"] as? String
let eventCreator = snapshot.value["eventCreator"] as? String
var attendees: NSMutableDictionary = [:]
var attendeesImages = [UIImage]()
let attendee: NSMutableDictionary = [:]
let group = dispatch_group_create()
//Get attendees first
dispatch_group_enter(group)
self.getAttendees(snapshot.key as String, completion:{ (result, name, objectID) -> Void in
if(result == true){
println("Finished grabbing \(name!) \(objectID!)")
attendees.addEntriesFromDictionary(attendee as [NSObject : AnyObject])
}
else {
println("False")
}
dispatch_group_leave(group)
})
//Get attendees photos
dispatch_group_enter(group)
self.getAttendeesPictures(attendee, completion: { (result, image) -> Void in
if result == true {
println("Finished getting attendee photos. Now to store into Event object.")
attendeesImages.append(image!)
}
else{
println("false")
}
dispatch_group_leave(group)
})
dispatch_group_notify(group, dispatch_get_main_queue()) {
println("both requests done")
//Maintain array snapshot keys
self.eventIDs.append(snapshot.key)
if snapshot != nil {
let event = Event(eventName: eventName, eventLocation:eventLocation, eventPhoto:eventPhoto, fromDate:fromDate, fromTime:fromTime, toDate:toDate, toTime:toTime, attendees: attendees, attendeesImages:attendeesImages, attendeesImagesTest: attendeesImagesTest, privacy:privacy, eventCreator: eventCreator, eventCreatorID: eventCreatorID)
println("Event: \(event)")
completion(result: true, Event: event)
}
}
}) { (error) -> Void in
println(error.description)
}
}
Я знаю, что мои обработчики завершения корректно установлены, как я тестировал в своей программе. Тем не менее, я хочу, чтобы только после завершения функций getAttendees
и getAttendeesPictures
, я хочу сохранить всю информацию, которую я захватил в функции snapshot
, getAttendees
и getAttendeesPictures
, и сохранить их в event
объект. Любые идеи о том, как это сделать? Я попытался заглянуть в dispatch_groups
, чтобы помочь мне справиться с этим по этой ссылке: Проверка нескольких асинхронных ответов от Alamofire и Swift, но моя программа, похоже, выполняет только getAttendees
, но не функция getAttendeesPictures
. Ниже также находятся функции getAttendees
и getAttendeesPictures
:
func getAttendees(child: String, completion: (result: Bool, name: String?, objectID: String?) -> Void){
//Get event attendees of particular event
var attendeesReference = self.eventAttendeesRef.childByAppendingPath(child)
println("Loading event attendees")
//Get all event attendees
attendeesReference.observeEventType(FEventType.ChildAdded, withBlock: { (snapshot) -> Void in
let name = snapshot.value.objectForKey("name") as? String
let objectID = snapshot.value.objectForKey("objectID") as? String
println("Name: \(name) Object ID: \(objectID)")
completion(result: true, name: name, objectID: objectID)
}) { (error) -> Void in
println(error.description)
}
func getAttendeesPictures(attendees: NSMutableDictionary, completion: (result: Bool, image: UIImage?)-> Void){
println("Attendees Count: \(attendees.count)")
for (key, value) in attendees{
let url = NSURL(string: "https://graph.facebook.com/\(key)/picture?type=large")
println("URL: \(url)")
let urlRequest = NSURLRequest(URL: url!)
//Asynchronous request to display image
NSURLConnection.sendAsynchronousRequest(urlRequest, queue: NSOperationQueue.mainQueue()) { (response:NSURLResponse!, data:NSData!, error:NSError!) -> Void in
if error != nil{
println("Error: \(error)")
}
// Display the image
let image = UIImage(data: data)
if(image != nil){
completion(result: true, image: image)
}
}
}
}