When using dispatch_group_async to call methods that are themselves asynchronous, the group will exit immediately after all asynchronous tasks are started, but does not wait for them to complete. Instead, you can manually call dispatch_group_enter before making an asynchronous call, and then call dispatch_group_leave when the asynchronous call ends. Then dispatch_group_wait will behave as expected.
To accomplish this, first modify downloadImage to include the completion handler parameter:
private func downloadImage(serverFile: AdFileInfo, completionHandler: (NSError?)->()) { let destinationPath = imageDirectoryURL.URLByAppendingPathComponent(serverFile.fileName) Alamofire.download(.GET, serverFile.imageUrl) { temporaryURL, response in return destinationPath } .response { _, _, _, error in if let error = error { print("Error downloading \(serverFile.fileName): \(error)") } else { print("Done downloading \(serverFile.fileName)") } completionHandler(error) } }
I made a completion handler that returns an error code. Emphasize this as you see fit, but hopefully this illustrates this idea.
But by providing a completion handler, now that you are doing the downloads, you can create a group, an βenterβ group, before you start each download, βleaveβ the group when the completion handler is called asynchronously.
But dispatch_group_wait may come to a standstill if you are not careful, it may block the user interface if it is made from the main thread, etc. Better, you can use dispatch_group_notify to achieve your desired behavior.
func downloadImages(imageFilesOnServer: [AdFileInfo], completionHandler: (Int) -> ()) { let group = dispatch_group_create() var downloaded = 0 for serverFile in imageFilesOnServer { dispatch_group_enter(group) print("Start downloading \(serverFile.fileName)") self.downloadImage(serverFile) { error in if error == nil { downloaded += 1 } dispatch_group_leave(group) } } dispatch_group_notify(group, dispatch_get_main_queue()) { completionHandler(downloaded) } }
And you would call it that:
downloadImages(arrayOfAdFileInfo) { downloaded in