我有一系列链接到图像文件的URL,如何将它们存储到UIImages数组中?
var imagesArray = [UIImage]()
let links = ["http://example.com/image1.jpg","http://example.com/image2.jpg"] as [String]
必须有一个简单的解决方案。 如果是一张图片,我可以做如下的事情:
let url = URL(string: link2image!)!
let imageData = try? Data(contentsOf: url)
let image = UIImage(data: imageData!)!
self.image.append(image)
答案 0 :(得分:3)
最简单的解决方案是迭代数组并使用Data(contentsOf:)
同步下载图像,但是,由于同步执行,这将是非常不充分的。
let images = links.flatMap{ link->UIImage? in
guard let url = URL(string: link) else {return nil}
guard let imageData = try? Data(contentsOf: url) else {return nil}
return UIImage(data: imageData)
}
更好的解决方案是并行异步下载图像,我使用PromiseKit为此编写了UIImage
扩展名:
extension UIImage {
class func downloadedAsync(fromUrl url: URL)->Promise<UIImage> {
return Promise{ fulfill, reject in
URLSession.shared.dataTask(with: url, completionHandler: { data, response, error in
guard let data = data, error == nil else {
reject(error!); return
}
guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
reject(NSError(domain: "Wrong HTTP response code when downloading image asynchronously",code: (response as? HTTPURLResponse)?.statusCode ?? 1000));return
}
guard let mimeType = response?.mimeType, mimeType.hasPrefix("image"), let image = UIImage(data: data) else {
reject(NSError(domain: "No image in response", code: 700)); return
}
fulfill(image)
}).resume()
}
}
}
你可以通过这样的链接来调用它:
var imageDownloadTasks = links.flatMap{ link in
guard let url = URL(string: link) else {return nil}
return UIImage.downloadedAsync(fromUrl: url)
}
然后执行承诺:
when(fulfilled: imageDownloadTasks).then{ images in
//use the images, images is of type [UIImage]
}
答案 1 :(得分:0)
也许你可以尝试使用函数式编程:map closure ...
links.map({
if let imageData = try? Data(contentsOf: URL(string: $0)!) {
UIImage(data: imageData)
}
})
但你必须知道你的链接是否错误,它会崩溃。所以,我建议你做一些防范以防止这些崩溃。像这样...
guard let url = URL(string: $0) else { return nil }