非同期通信でのUIScrollViewの更新について
アマゾンのAWSのS3に上がっている画像データを読み込み、ScrollView
に表示するというコードを書きました。
UIの更新はdispatch_get_main_queue()
の中に明記することを記事で見たので、以下のように記述したのですが、最初の一枚しかscrollview
に追加されません。デバックをしたところ、addImage
は画像の枚数回呼び出されているそうです。
複数枚の画像を非同期的に読み込んで、一枚一枚順を追ってscrollview
に追加したいです。複数枚の追加はどうしたらいいでしょうか?
downloadメソッドを追加しました。
class LoadViewController: UIViewController,UIScrollViewDelegate {
var loadImages:[UIImage] = []
@IBOutlet weak var scrollView: UIScrollView!
var uploadRequests = Array<AWSS3TransferManagerUploadRequest?>()
var uploadFileURLs = Array<NSURL?>()
var downloadRequests = Array<AWSS3TransferManagerDownloadRequest?>()
var downloadFileURLs = Array<NSURL?>()
override func viewDidLoad() {
super.viewDidLoad()
self.scrollView.delegate = self
do {
try NSFileManager.defaultManager().createDirectoryAtURL(
NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent("download"),
withIntermediateDirectories: true,
attributes: nil)
} catch let error1 as NSError {
error.memory = error1
print("Creating 'download' directory failed. Error: \(error)")
}
listObjects()
}
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
scrollView.addSubview(myImageView)
scrollView.contentSize = CGSizeMake(swidth * CGFloat(loadImages.count), sheight)
}
func listObjects() {
let s3 = AWSS3.defaultS3()
let listObjectsRequest = AWSS3ListObjectsRequest()
listObjectsRequest.bucket = S3BucketName
s3.listObjects(listObjectsRequest).continueWithBlock { (task) -> AnyObject! in
if let error = task.error {
print("listObjects failed: [\(error)]")
}
if let exception = task.exception {
print("listObjects failed: [\(exception)]")
}
if let listObjectsOutput = task.result as? AWSS3ListObjectsOutput {
if let contents = listObjectsOutput.contents as [AWSS3Object]? {
for s3Object in contents {
let downloadingFileURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent("download").URLByAppendingPathComponent(s3Object.key!)
let downloadingFilePath = downloadingFileURL.path!
if NSFileManager.defaultManager().fileExistsAtPath(downloadingFilePath) {
self.downloadRequests.append(nil)
self.downloadFileURLs.append(downloadingFileURL)
} else {
let downloadRequest = AWSS3TransferManagerDownloadRequest()
downloadRequest.bucket = S3BucketName
downloadRequest.key = s3Object.key
downloadRequest.downloadingFileURL = downloadingFileURL
self.downloadRequests.append(downloadRequest)
self.downloadFileURLs.append(nil)
}
dispatch_async(dispatch_get_main_queue(), { () -> Void in
if let data = NSData(contentsOfURL: downloadingFileURL) {
self.addImage(UIImage(data: data)!)
self.displayNum++
}
})
}
}
}
return nil
}
}
func download(downloadRequest: AWSS3TransferManagerDownloadRequest) {
switch (downloadRequest.state) {
case .NotStarted, .Paused:
let transferManager = AWSS3TransferManager.defaultS3TransferManager()
transferManager.download(downloadRequest).continueWithBlock({ (task) -> AnyObject! in
if let error = task.error {
if error.domain == AWSS3TransferManagerErrorDomain as String
&& AWSS3TransferManagerErrorType(rawValue: error.code) == AWSS3TransferManagerErrorType.Paused {
print("Download paused.")
} else {
print("download failed: [\(error)]")
}
} else if let exception = task.exception {
print("download failed: [\(exception)]")
} else {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
if let index = self.indexOfDownloadRequest(self.downloadRequests, downloadRequest: downloadRequest) {
self.downloadRequests[index] = nil
self.downloadFileURLs[index] = downloadRequest.downloadingFileURL
if let data = NSData(contentsOfURL: downloadRequest.downloadingFileURL) {
self.addImage(UIImage(data: data)!)
self.displayNum++
}
}
})
}
return nil
})
break
default:
break
}
}
}