我想从服务器下载图像并在UICollectionView中显示。第一次用户连接互联网时,所有图像都将在后台下载,并在用户离线时从本地目录显示。我正在使用alamofire下载图像。首先,我检查图像的存在,如果它还没有下载,我下载它。问题是专辑在下载时没有显示。我不知道怎么。这是我的代码:
import UIKit
import Alamofire
var myurl : URL!
var imageName : String!
var bool = false
let docsurl = try! FileManager.default.url(for:.documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if (background_imageurl.count > 0) {
if Reachability.isConnectedToNetwork() == true{
downloadAllImages(urlArray : background_imageurl)
}
}
}
func downloadAllImages(urlArray:[String])->Void{
for i in 0 ..< urlArray.count {
let fullName = urlArray[i]
let fullNameArr = (fullName as AnyObject).components(separatedBy: "//")
let imgname = fullNameArr[1]
let tempimgname = imgname
let tempimgname2 = tempimgname.components(separatedBy: "/")
imageName = tempimgname2[4]
myurl = docsurl.appendingPathComponent("\("guidedCellImages")/\(self.imageName!)")
print("\n myurl", myurl)
if FileManager.default.fileExists(atPath: myurl.path, isDirectory: &bool),bool.boolValue {
print("\n fileExists", myurl.path)
}else{
downloadFile(url: urlArray[i] as! String)
}
}
}
func downloadFile(url: String)->Void{
let destination: (URL, HTTPURLResponse) -> (URL, DownloadRequest.DownloadOptions) = {
(temporaryURL, response) in
let directoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let filePath = directoryURL?.appendingPathComponent("\("guidedCellImages")/\(self.imageName!)")
return (filePath!, [.removePreviousFile, .createIntermediateDirectories])
}
let utilityQueue = DispatchQueue.global(qos: .utility)
print("url", url)
Alamofire.download(
url,
method: .get,
encoding: JSONEncoding.default,
to: destination)
.downloadProgress(queue: utilityQueue) { progress in
}
.response(completionHandler: { (DefaultDownloadResponse) in
if (self.urlArray.count > 0){
self.urlArray.removeFirst()
print("self.urlArray", self.urlArray.count)
}
if DefaultDownloadResponse.response?.statusCode == 200 {
print(DefaultDownloadResponse.destinationURL!)
}
})
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell : CollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! CollectionViewCell
myurl = docsurl.appendingPathComponent("\("guidedCellImages")")
if FileManager.default.fileExists(atPath: myurl.path, isDirectory: &bool),bool.boolValue {
let directoryContents = try! fileManager.contentsOfDirectory(at: myurl, includingPropertiesForKeys: nil)
print("\ndirectoryContents", directoryContents)
for imageURL in directoryContents where imageURL.pathExtension == "png" {
if let image = UIImage(contentsOfFile: imageURL.path) {
cell.tab1GuidedimageView.image = image
} else {
fatalError("Can't create image from file \(imageURL)")
}
}
}else{
if (background_imageurl.count > 0 ){
cell.tab1imageView.sd_setImage(with: URL(string: background_imageurl[indexPath.row]), placeholderImage: UIImage(named: "background"),options: .refreshCached)
}
}
return cell
}
答案 0 :(得分:0)
self.imageName似乎存在问题。下载图像时,imageName将在for循环中更改。确保每次从URL生成图像名称。在下载和保存时以及检查时。
实际上,您可以将imageName变量的范围从全局更改为本地。
建议使用write函数来获取图像名称以避免冗余。
修改强>
guidedCellImages文件夹必须存在,只需添加guidedCEllImages即可自动创建文件夹。确保在guidedCellImages
之前添加斜杠(/)请检查如何在文档目录here
中创建文件夹希望它有所帮助...... !!!
答案 1 :(得分:0)
试试此代码
func downloadFile(url: String)-> Void {
let directoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let filePath = directoryURL?.appendingPathComponent("\("guidedCellImages")/\(self.imageName!)")
let data = NSData(contentsOf: URL(string: url)!)
data?.write(toFile: filePath, atomically: true)
}
答案 2 :(得分:0)
尝试以下程序,这可能有助于您
struct Animal{
var name: String
var url: String
var image: UIImage?
}
extension Animal{
init(info: [String: String]) {
self.name = info["name"]!
self.url = info["url"]!
}
}
class CollectionViewCell{
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var label: UILabel!
}
class ViewController: UIViewController{
var animals = [Animal]()
override func viewDidLoad(){
super.viewDidLoad()
}
func getAnimals(){
// hit server api to get the images
// assuming that the following json is coming from server
let jsonResponse = [["name":"Dog","url":"https://animals.com/images/image/dog.jpeg"],
["name":"Lion","url":"https://animals.com/images/image/lion.jpeg"],
["name":"Tiger","url":"https://animals.com/images/image/tiger.jpeg"],
["name":"Horse","url":"https://animals.com/images/image/horse.jpeg"],
["name":"Elephant","url":"https://animals.com/images/image/elephant.jpeg"]]
for animal in jsonResponse {
let lAnimal = Animal(info: animal)
// get locally saved image initially from collectionview cell, if it is existed then add it to your response model
let directoryURL = getDocumentsDirectory()
let imageURL = URL(string: lAnimal.url)
let imagePath = directoryURL.appendingPathComponent("animals/\(imageURL.lastPathComponent)")
if fileManager.fileExistsAtPath(imagePAth){
// pass locallay saved image path
lAnimal.image = UIImage(contentsOfFile: imagePAth)
}else{
print("image needs to be downloaded")
}
}
}
func getDocumentsDirectory() -> URL {
let directoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
return directoryURL!
}
}
extension ViewController: UICollectionViewDataSource{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.animals.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell : CollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "reuseIdentifier", for: indexPath) as! CollectionViewCell
let animal = self.animals[indexPath.row]
cell.label.text = animal.name
if let animalImage = animal.image{
//if animal image existis from local them simply display it
cell.imageView.image = animalImage
}else{
//download image from server using simple url task or by using alamofire
let imageURL = URL(string: animal.url)!
let task = URLSession.shared.dataTask(with: imageURL, completionHandler: { (data, response, error) in
if let lData = data {
let image = UIImage(data: lData)
cell.imageView.image = image
let filename = getDocumentsDirectory().appendingPathComponent("animals/\(imageURL.lastPathComponent)")
try? lData.write(to: filename)
//update local data model object
animal.image = image
}
if let lError = error{
/** Handle session error ..................... **/
}
})
}
return cell
}
}