【发布时间】:2015-09-24 12:34:18
【问题描述】:
我遇到了一个问题,我有多个异步请求发生,这些请求从 Facebook API 和我的 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 来帮助我处理这个问题:Checking for multiple asynchronous responses from Alamofire and 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)
}
}
}
}
【问题讨论】:
标签: ios swift firebase asynchronous firebase-realtime-database