因此,从本质上讲,我正在使用服务器来检索已存储的URL。一旦检索到URL(在for
循环中),我就会调用一个函数,该函数直接从AWS S3下载它们。问题是,当我一次只需要下载一张图像时,它就可以完美地工作。这包括以下情况:我已经下载了一个图像,上传了另一个图像,然后回到加载的主视图,并且两个图像正确显示。当我有多个需要下载的图像时(首次启动该应用程序时),图像数组会重叠。我正在为URL
使用一个数组,为UIImages
使用另一个数组。
这是我的ImageCache
代码:
class ImageCache {
static var urlCache: Array<String> = []
static var imageCache: Array<UIImage> = []
}
我之所以用它来代替NSCache
是因为我需要能够将imageCache
用作我的数据源,而且我不确定如何指定{{1}内的对象数}作为NSCache
对象是不可迭代的。
无论如何,这是我调用下载功能的代码:
NSCache
使用query.findObjectsInBackground { (results, error) in
var imageURL: String = ""
var count: Int = 1
if error == nil {
for result in results! {
print(result)
imageURL = result["imageURL"] as! String
let imageKey = imageURL.components(separatedBy: "/uploads")[1]
if !ImageCache.urlCache.contains(imageURL) {
self.downloadImageFromS3(key: "uploads\(imageKey)", count: results!.count, current: count, url: imageURL)
}
count += 1
}
}
}
和current
的原因是,当当前索引等于count
循环中的最后一个索引时,我们应该更新for
。这样,只有在下载了最后一张图片后,视图才会重新加载(至少这是目标)。
这是我的UICollectionView
函数:
downloadImageFromS3
编辑:我以为我已通过改行解决了问题
func downloadImageFromS3(key: String, count: Int, current: Int, url: String) {
DispatchQueue.main.async {
let transferManager = AWSS3TransferManager.default()
let downloadingFileURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("image.png")
let downloadRequest = AWSS3TransferManagerDownloadRequest()
downloadRequest!.bucket = "BUCKET_NAME"
downloadRequest!.key = key
downloadRequest!.downloadingFileURL = downloadingFileURL
transferManager.download(downloadRequest!).continueWith(executor: AWSExecutor.mainThread()) { (task) -> Any? in
if let error = task.error as NSError? {
if error.domain == AWSS3TransferManagerErrorDomain, let code = AWSS3TransferManagerErrorType(rawValue: error.code) {
switch code {
case .cancelled, .paused:
break
default:
print("Error downloading: \(String(describing: downloadRequest!.key)) Error: \(error)")
}
} else {
print("Error downloading: \(String(describing: downloadRequest!.key)) Error: \(error)")
}
return nil
} else {
let image = UIImage(contentsOfFile: downloadingFileURL.path)!
ImageCache.urlCache.append(url)
ImageCache.imageCache.append(image)
}
print("Download complete for: \(String(describing: downloadRequest!.key))")
if current == count && ImageCache.imageCache.count == count && ImageCache.urlCache.count == count {
self.collectionView?.reloadData()
print(ImageCache.imageCache)
print(ImageCache.urlCache)
}
return nil
}
}
}
我之前在解释的self.collectionView.reloadData()
语句之外。这将导致最后两个图像混乱,这意味着第一个和第二个图像看起来很好,但是第三个和第四个图像是同一图像。有人有解决方案吗?
编辑:我刚刚发现了真正的问题,即为什么某些最终图像重叠。下载图片时出现解码错误:
if
我的印象是该行中的错误:2018-08-10 22:26:57.826759-0500 PROJECT_NAME[81557:49209786] mapData:754: *** ImageIO - mmapped file changed (old: 8112955 new: 6209998)
2018-08-10 22:26:57.871970-0500 PROJECT_NAME[81557:49209786] [0x7fcf610c5a00] Decoding failed with error code -1
2018-08-10 22:26:57.872127-0500 PROJECT_NAME[81557:49209786] [0x7fcf610c5a00] Decoding: C0 0x10C00B20 0x0218304A 0x11111100 0x00590011 8112955
2018-08-10 22:26:57.872225-0500 PROJECT_NAME[81557:49209786] [0x7fcf610c5a00] Options: 1x-1 [00000000,10C003B6] 0001D060
2018-08-10 22:26:57.872341-0500 PROJECT_NAME[81557:49209786] imageBlockSetCreate:829: *** buffer height mismatch: rect:{0,0,4288,950} size:{4288,2848}
2018-08-10 22:26:57.873336-0500 PROJECT_NAME[81557:49209786] [Unknown process name] img_blocks_create: Null block
CGImageProviderCopyImageBlockSet(<CGImageProvider 0x6040002ed980> (component-type = Int8, pixel-size = 4, size = [4288 x 2848]));
<CGImageBlockSet 0x6000001357c0> (size = [4288 x 2848], rect = (0, 0) x [4288, 950], count = 3) [1]
2018-08-10 22:26:57.873474-0500 PROJECT_NAME[81557:49209786] [Unknown process name] img_blocks_create: Null block
CGImageProviderCopyImageBlockSet(<CGImageProvider 0x6040002ed980> (component-type = Int8, pixel-size = 4, size = [4288 x 2848]));
<CGImageBlockSet 0x6000001357c0> (size = [4288 x 2848], rect = (0, 0) x [4288, 950], count = 3)
。图像上传到S3后,已将let image = UIImage(contentsOfFile: downloadingFileURL.path)!
设置为Content-Encoding
。
答案 0 :(得分:1)
解决了我自己的问题。将downloadingFileURL
路径更改为.jpeg
文件路径并使其唯一之后,我就能看到问题。我还为UIImage
调用了错误的初始化程序。应该是UIImage(named: downloadingFileURL.path)!
而不是UIImage(contentsOfFile: downloadingFileURL.path)!