非同期処理での実行される順番について
AWSののdynamoDBを用いて、loadUser()
データベースに上がってある画像のURLを持ってきて、downloadImage()
で画像をダウンロードして、addImage()
でscrollView
に追加するようなことをしています。
しかし、downloadImage()
内でダウンロードされた順番(loadCounter)を出力してみると
0
2
1
などのように出力されて、順番通りに出力されませんでした。
非同期処理で順番通りにダウンロードするにはどこを変更したらいいでしょうか。お願いします。
import UIKit
import AWSCore
import AWSS3
import AWSDynamoDB
class LoadViewController: UIViewController, UINavigationControllerDelegate,UIScrollViewDelegate {
var loadImages:[UIImage] = []
var loadItems:[DDBTableRow] = []
var userId:String?
var userName:String?
var pagniatedOutput: AWSDynamoDBPaginatedOutput?
@IBOutlet weak var scrollView: UIScrollView!
let defaults = NSUserDefaults.standardUserDefaults()
override func viewDidLoad() {
super.viewDidLoad()
self.scrollView.delegate = self
self.userName = defaults.stringForKey("userName")
self.userId = defaults.stringForKey("userId")
loadUser()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func addImage(image:UIImage)
{
let sheight = self.scrollView.frame.height
let swidth = self.scrollView.frame.width
loadImages.append(image)
let myImageView = UIImageView()
myImageView.frame = CGRectMake(swidth * CGFloat(loadImages.count-1), 0, swidth, sheight)
myImageView.image = image
myImageView.contentMode = .ScaleAspectFit
scrollView.addSubview(myImageView)
scrollView.contentSize = CGSizeMake(swidth * CGFloat(loadImages.count), sheight)
}
func loadUser()
{
let dynamoDBObjectMapper = AWSDynamoDBObjectMapper.defaultDynamoDBObjectMapper()
let queryExpression = AWSDynamoDBQueryExpression()
queryExpression.hashKeyValues = userId
queryExpression.scanIndexForward = false
var loadCounter:Int = 0
dynamoDBObjectMapper .query(DDBTableRow.self, expression: queryExpression) .continueWithExecutor(AWSExecutor.mainThreadExecutor(), withBlock: { (task:AWSTask!) -> AnyObject! in
if (task.error != nil) {
print("Error: \(task.error)")
} else {
if (task.result != nil) {
self.pagniatedOutput = task.result as? AWSDynamoDBPaginatedOutput
for item in (self.pagniatedOutput?.items)!
{
let tableRow = item as! DDBTableRow
print(tableRow.Date)
self.downloadImage(tableRow.ImageURL!,loadCounter: loadCounter)
self.loadItems.append(tableRow)
loadCounter += 1
}
}
self.performSegueWithIdentifier("unwindToMainSegue", sender: self)
}
return nil
})
}
func downloadImage(S3DownloadKeyName: String,loadCounter:Int){
var completionHandler: AWSS3TransferUtilityDownloadCompletionHandlerBlock?
let queue:dispatch_queue_t = dispatch_queue_create("com.gologo13.gcd", DISPATCH_QUEUE_SERIAL)
let expression = AWSS3TransferUtilityDownloadExpression()
expression.downloadProgress = {(task: AWSS3TransferUtilityTask, bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) in
dispatch_async(dispatch_get_main_queue(), {
let progress = Float(totalBytesSent) / Float(totalBytesExpectedToSend)
NSLog("Progress is: %f",progress)
})
}
completionHandler = { (task, location, data, error) -> Void in
dispatch_async(dispatch_get_main_queue(), {
if ((error) != nil){
NSLog("Failed with error")
NSLog("Error: %@",error!)
}
else{
print(Success)
self.addImage(UIImage(data: data!)!)
//loadCounterのデバック
print(loadCounter)
//loadCounterの出力される値が順番通りにならない
}
})
}
let transferUtility = AWSS3TransferUtility.defaultS3TransferUtility()
transferUtility.downloadToURL(nil, bucket: S3BucketName, key: S3DownloadKeyName, expression: expression, completionHander: completionHandler).continueWithBlock { (task) -> AnyObject! in
if let error = task.error {
NSLog("Error: %@",error.localizedDescription);
// self.statusLabel.text = "Failed"
}
if let exception = task.exception {
NSLog("Exception: %@",exception.description);
// self.statusLabel.text = "Failed"
}
if let _ = task.result {
// self.statusLabel.text = "Starting Download"
NSLog("Download Starting!")
// Do something with uploadTask.
}
return nil;
}
}
}