Leo Guo Leo Guo - 3 months ago 19
Swift Question

Swift: download image from Internet and cache them doesn't work properly. need suggestions

I am new to swift, and I am building an App that download images from the Internet and display in a UICollectionView, I can achieve this function successfully, however, it seems like overtime you scroll the screen, it downloaded the images again and again, which may causes a lot of data of the users. I found that I can use cache to solve this problem, but it didn't work, I think I did everything right, but seems the data didn't stored in the cache. here is the code, anyone can help me solve this? thanks

var imageCache = [String: UIImage]()
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

extension ViewController: UICollectionViewDataSource {

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CollectionViewCell

Alamofire.request(.GET, "http://localhost:8888/wordpress/wp-json/wp/v2/posts").responseJSON { (response) in
if let jsonFile = response.result.value {

var arrayOfPosts = [Posts]()

for post in jsonFile as! NSArray {

let postObj = Posts()
postObj.postThumbnailUrlString = post.valueForKeyPath("featured_image_thumbnail_url") as! String

arrayOfPosts.append(postObj)
}


let imageUrlString: String = arrayOfPosts[indexPath.row].postThumbnailUrlString

let imageUrl: NSURL = NSURL(string: imageUrlString)!







if let imageFromCache = imageCache[imageUrlString] {

cell.imageView.image = imageFromCache
return
}

let request = NSURLRequest(URL: imageUrl)
let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithRequest(request) { (data, response, error) in

let imageToCache = UIImage(data: data!)

imageCache[imageUrlString] = imageToCache

dispatch_async(dispatch_get_main_queue(), {



cell.imageView.image = imageToCache
})

}

dataTask.resume()



}

}


return cell

}}


I also have a class of Posts and a customized collectionviewcell. this stocked me a long time, really hope anyone can help me solve this problem. thanks!!

Answer

Use AlamofireImage

Add --> pod 'AlamofireImage', '~> 2.0' in your pod file. Put following line in your code which will automatically cache the image and download it as well.

override func viewDidLoad() {
     super.viewDidLoad()
     //hit your web service here to get all url's
 }

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
   return arrImageURL.count
}


func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{ 
   cell.imgViewPhoto.af_setImageWithURL(arrImageURL[indexPath.row], placeholderImage: UIImage())
}