以下是我用于从AWS S3服务器下载图像并将其指定为图像视图中显示的图像的代码:
let s3BucketName = "bucketName"
let fileName = Globals.currAuthorName.filter { $0 != Character(" ") } + ".jpg"
let downloadFilePath = NSTemporaryDirectory().stringByAppendingPathComponent(fileName)
let downloadingFileURL = NSURL.fileURLWithPath(downloadFilePath)
// Create a credential provider for AWS requests
let credentialsProvider = AWSCognitoCredentialsProvider(
regionType: AWSRegionType.USEast1,
identityPoolId: "us-east-1:********-****-****-****-************")
// Create a service configuration for AWS requests
let defaultServiceConfiguration = AWSServiceConfiguration(
region: AWSRegionType.USEast1,
credentialsProvider: credentialsProvider)
// Create a new download request to S3, and set its properties
AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = defaultServiceConfiguration
let downloadRequest = AWSS3TransferManagerDownloadRequest()
downloadRequest.bucket = s3BucketName
downloadRequest.key = "folderName/" + fileName
downloadRequest.downloadingFileURL = downloadingFileURL
let transferManager = AWSS3TransferManager.defaultS3TransferManager()
transferManager.download(downloadRequest)
// Set the UIImageView to show the file that was downloaded
let image = UIImage(contentsOfFile: downloadFilePath)
authorImage.contentMode = UIViewContentMode.ScaleAspectFit
authorImage.image = image
问题是,当我运行iOS模拟器并导航到相应的页面时,我第一次访问页面时从不加载图像。但是,当我离开页面然后返回页面时,它总是被加载,并且每次我访问页面时都会加载。当我停止运行应用程序然后再次启动它并再次访问该页面时,图像仍然加载。我第一次访问某个iOS模拟器的页面时才会加载图像(即它在iPhone 6模拟器,iPhone 5模拟器等中发生一次)
我尝试通过添加这段代码来解决问题:
while (image == nil) {
transferManager.download(downloadRequest)
let image = UIImage(contentsOfFile: downloadFilePath)
}
但这只是在我第一次访问该页面时导致无限循环。控制台最终也输出了这个错误:
2015-07-06 23:26:28.529 CCBF [19839:92323] 19839:CFNetwork内部错误(0xc01a:/SourceCache/CFNetwork_Sim/CFNetwork-711.3.18/Foundation/NSURLRequest.mm:798) 2015-07-06 23:26:28.564 AuthorProject [19839:92323] AWSiOSSDKv2 [错误] AWSURLSessionManager.m行:240 | __41- [AWSURLSessionManager taskWithDelegate:] _ block_invoke222 | AWSURLSessionTaskType无效。
修改
我尝试实现以下continuewithblock:
var image : UIImage!
let task = transferManager.download(downloadRequest)
task.continueWithBlock({
if task.error != nil {
println(task.error)
} else {
dispatch_async(dispatch_get_main_queue(), {
image = UIImage(contentsOfFile: downloadFilePath)
self.authorImage.contentMode = UIViewContentMode.ScaleAspectFit
self.authorImage.image = image
})
}
return nil
}())
但是,当我运行它并尝试加载图像时,我收到一个运行时错误,指向我的#34; continueWithExecutor"方法。具体来说,代码行:
result = block(self);
消息为:
EXC_BAD_ACCESS(代码:1,地址= 0x10)
EDIT2:
我似乎找到了一个有效的解决方案:
var image : UIImage!
let taskTODO = transferManager.download(downloadRequest)
taskTODO.continueWithBlock{ (task: AWSTask!) -> AnyObject! in
if task.error != nil {
println(task.error)
} else {
dispatch_async(dispatch_get_main_queue(), {
image = UIImage(contentsOfFile: downloadFilePath)
self.authorImage.contentMode = UIViewContentMode.ScaleAspectFit
self.authorImage.image = image
})
}
return nil
}
这看起来是正确的方法吗?
答案 0 :(得分:1)
transferManager.download(downloadRequest)是异步的,这意味着下载图像大约需要20毫秒。但是,第一次进入屏幕时,您尝试立即分配图像(尚未下载)。在随后的屏幕加载中 - 图像已经下载并缓存 - 因此它可以立即显示,。你需要的是一个完成块,它指示图像何时完成下载并准备好显示,在那个块中你应该分配图像。见下面的例子:
let readRequest1 : AWSS3TransferManagerDownloadRequest = AWSS3TransferManagerDownloadRequest()
readRequest1.bucket = "shrikar-picbucket"
readRequest1.key = "bingo"
readRequest1.downloadingFileURL = downloadingFileURL1
let task = transferManager.download(readRequest1)
task.continueWithBlock { (task) ->; AnyObject! in
println(task.error)
if task.error != nil {
} else {
dispatch_async(dispatch_get_main_queue()
, { () ->; Void in
self.selectedImage.image = UIImage(contentsOfFile: downloadingFilePath1)
self.selectedImage.setNeedsDisplay()
self.selectedImage.reloadInputViews()
})
println("Fetched image")
}
return nil
}