Skip to content

Commit

Permalink
Merge pull request #1 from zalando/invalidateDownloadingImagesOnReusa…
Browse files Browse the repository at this point in the history
…bleImageViews

invalidate downloading operations for imageViews when the image is set a...
  • Loading branch information
gdj4ever committed Dec 19, 2014
2 parents ae22132 + 35bcfc2 commit dc17ad3
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 5 deletions.
19 changes: 17 additions & 2 deletions Library/MapleBacon/MapleBacon/ImageDownloader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class ImageDownloader: NSObject, NSURLSessionDownloadDelegate {
private var task: NSURLSessionDownloadTask!
private var progress: NSProgress?
private var resumeData: NSData?
private var invalidated = false

public convenience override init() {
self.init(delegate: nil)
Expand Down Expand Up @@ -86,11 +87,15 @@ public class ImageDownloader: NSObject, NSURLSessionDownloadDelegate {
public func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {
let newData = NSData(contentsOfURL: location)!
let newImage = UIImage.imageWithData(newData)
let newImageInstance = ImageInstance(image: newImage, data: newData, state: .New, url: imageURL)
let newImageInstance = ImageInstance(image: newImage, data: newData, state: finishedState(), url: imageURL)
completionHandler?(newImageInstance, nil)
progress = nil
}

public func finishedState() -> ImageInstanceState {
return invalidated ? .Invalidated : .New
}

public func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
if let error = error {
println("API error: \(error), \(error.userInfo)")
Expand All @@ -103,10 +108,15 @@ public class ImageDownloader: NSObject, NSURLSessionDownloadDelegate {
self.completionHandler!(nil, nil)
startTask(image: request.URL)
}

public func invalidateDownload() {
invalidated = true
}

}

public enum ImageInstanceState {
case New, Cached, Downloading
case New, Cached, Downloading, Invalidated
}

public struct ImageInstance {
Expand All @@ -121,4 +131,9 @@ public struct ImageInstance {
self.url = url
self.data = data
}

public func isInvalidated() -> Bool {
return state == .Invalidated
}

}
13 changes: 12 additions & 1 deletion Library/MapleBacon/MapleBacon/ImageManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import Foundation
import UIKit

var ImageViewAssociatedObjectHandle: UInt8 = 0

public class ImageManager: NSObject {

lazy var downloadsInProgress = [NSURL: ImageDownloader]()
Expand Down Expand Up @@ -45,7 +47,7 @@ public class ImageManager: NSObject {
storage.storeImage(newImage, data: imageData!, forKey: url.absoluteString!)
}

completion(ImageInstance(image: newImage, state: .New, url: imageInstance?.url), nil)
completion(ImageInstance(image: newImage, state: imageInstance!.state, url: imageInstance?.url), nil)
}
}
})
Expand All @@ -68,4 +70,13 @@ public class ImageManager: NSObject {
return !downloadsInProgress.isEmpty
}

public func invalidateDownloadForImageView(imageView: UIImageView) {
if let url = objc_getAssociatedObject(imageView, &ImageViewAssociatedObjectHandle) as? NSURL {
if let operation = downloadsInProgress[url] {
operation.invalidateDownload()
}
}

}

}
7 changes: 6 additions & 1 deletion Library/MapleBacon/MapleBacon/ImageViewExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,17 @@ extension UIImageView {
}

public func setImageWithURL(url: NSURL, cacheScaled: Bool = false, completion: ImageDownloaderCompletion?) {
ImageManager.sharedManager.invalidateDownloadForImageView(self)
objc_setAssociatedObject(self, &ImageViewAssociatedObjectHandle, url, objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN_NONATOMIC))

ImageManager.sharedManager.downloadImageAtURL(url, cacheScaled: cacheScaled, imageView: self, completion: {
[weak self] (imageInstance: ImageInstance?, error: NSError?) -> Void in

dispatch_async(dispatch_get_main_queue()) {
if let image = imageInstance?.image {
self?.image = image
if !imageInstance!.isInvalidated() {
self?.image = image
}
}
if let completion = completion {
completion(imageInstance, error)
Expand Down
2 changes: 1 addition & 1 deletion Library/MapleBacon/MapleBacon/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>1.0.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down

0 comments on commit dc17ad3

Please sign in to comment.