简体   繁体   中英

Download and Show Array of images in UICollectionView Swift3

I want to download images from server and display in UICollectionView. First time when user connect with internet than all images will download in background and display from local directory when user is offline. I am using alamofire to download the images. Firstly i am checking existence of image, if it is not already dowloaded than i download it. The problem is that the album is not showing when it is already downloaded. I do not know how. Here is my code:

   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
}

The issue seems with self.imageName. When you are downloading image, the imageName Would have changed in the for loop. Make sure to generate the image name each time from url. while downloading and saving and also while checking.

In fact you can change the scope of imageName variable from global to local.

Recommended is write function to get the image name to avoid redundancy.

EDIT

The guidedCellImages folder must exists, just by adding guidedCEllImages will not create the folder automatically. make sure to add slash (/) before the guidedCellImages

Please check how to create the folder inside document directory here

Hope it helps..!!!

Try this code

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)

}

Try this below procedure, this might helps you

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM