在UICollectionView Swift3中下载并显示图像数组

时间:2018-02-01 12:34:04

标签: ios swift3 alamofire nsfilemanager

我想从服务器下载图像并在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
}

3 个答案:

答案 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
    }
}