Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Haneke Swift

Hermes Pique
November 06, 2014

Haneke Swift

Hermes Pique

November 06, 2014
Tweet

More Decks by Hermes Pique

Other Decks in Technology

Transcript

  1. Lightweight generic cache for iOS let cache = Cache<JSON>(name: "github")

    let URLString = "https://api.github.com/users/haneke" let URL = NSURL(string: URLString)! cache.fetch(URL: URL).onSuccess { JSON in println(JSON.dictionary?["bio"]) }
  2. Cache all the types! Memory and LRU disk cache for:

    • UIImage • NSData • JSON • String • Or any other type that can be read or written as data
  3. Features • Generic cache with out-of-the-box support for UIImage, NSData,

    JSON and String • First-level memory cache using NSCache • Second-level LRU disk cache using the file system • Asynchronous fetching from network or disk
  4. More features • All disk access is performed in background

    • Thread-safe • Automatic cache eviction on memory warnings or when the disk capacity is reached
  5. Image features • Zero-config UIImageView and UIButton extensions • Optimized

    for UITableView and UICollectionView cell reuse • Background image resizing and decompression imageView.hnk_setImageFromURL(url)
  6. Using the cache let cache = Haneke.sharedDataCache cache.set(value: data, key:

    "funny-games.mp4") // Eventually... cache.fetch(key: "funny-games.mp4").onSuccess { data in // Do something with data }
  7. Fetching Fetch operation can also set if a source is

    provided. let cache = Haneke.sharedJSONCache let URLString = "https://api.github.com/users/haneke" let URL = NSURL(string: URLString)! cache.fetch(URL: URL).onSuccess { JSON in println(JSON.dictionary?["bio"]) }
  8. cache.fetch(URL: URL).onSuccess { JSON in } 1. Fetch the required

    JSON from (in order) memory, disk or NSURLCache. 2. If not available, fetch the JSON from the url, parse it and return it asynchronously. 3. And immediately afterwards cache the JSON in background.
  9. Extra ὑ for images Smart UIKit categories. // Setting a

    remote image imageView.hnk_setImageFromURL(url) // Setting an image manually. Requires you to provide a key. imageView.hnk_setImage(image, key: key)
  10. The above lines take care of: • If cached, retrieving

    an appropriately sized image from the memory or disk cache (in background). • If not cached, loading the original from its source and producing an appropriately sized image (both in background). • Remote images will also be retrieved from the shared NSURLCache if available.
  11. Then: • Setting the image and animating the change if

    appropriate. • Or doing nothing if the UIImageView was reused during any of the above steps. • Caching the resulting image. • If needed, evicting the least recently used images in the cache.
  12. If you need more control public func hnk_setImageFromURL(URL: NSURL, placeholder

    : UIImage? = nil, format : Format<UIImage>? = nil, failure fail : ((NSError?) -> ())? = nil, success succeed : ((UIImage) -> ())? = nil) { ... }
  13. Formats Allow transformations to the values before being cached. For

    example, the UIImageView extension uses a format that resizes images to fit or fill the image view as needed.
  14. Format example let cache = Haneke.sharedImageCache let iconFormat = Format<UIImage>(name:

    "icons") { image in return imageByRoundingCornersOfImage(image) } cache.addFormat(iconFormat) let URL = NSURL(string: "http://haneke.io/icon.png")! cache.fetch(URL: URL, formatName: "icons").onSuccess { image in // image will be a nice rounded icon }
  15. Fetchers The fetch functions for urls and paths are actually

    convenience methods. Under the hood Haneke uses fetcher objects: let URL = NSURL(string: "http://haneke.io/icon.png")! let fetcher = NetworkFetcher<UIImage>(URL: URL) cache.fetch(fetcher: fetcher).onSuccess { image in // Do something with image }
  16. Two specialized fetchers: • NetworkFetcher<T> • DiskFetcher<T>. You can also

    implement your own fetchers by subclassing Fetcher<T>.
  17. Custom fetchers Fetch original values from other sources than network

    or disk (e.g., Core Data) Or even change how Haneke acceses network or disk (e.g., use Alamofire for networking instead of NSURLSession).
  18. Implementing custom fetchers A custom fetcher must subclass Fetcher<T>. Responsibilities:

    • Providing the key associated with the value to be fetched (e.g., NSURL.absoluteString in the case of NetworkFetcher) • Fetching the value in background and calling the success or failure closure (both in the main queue) • Cancelling the fetch on demand, if possible Type restriction: must implement DataConvertible.
  19. Supporting additional types By implementing protocols: public protocol DataConvertible {

    typealias Result class func convertFromData(data:NSData) -> Result? } public protocol DataRepresentable { func asData() -> NSData! }
  20. E.g., support for NSDictionary extension NSDictionary : DataConvertible, DataRepresentable {

    public typealias Result = NSDictionary public class func convertFromData(data:NSData) -> Result? { return NSKeyedUnarchiver.unarchiveObjectWithData(data) as? NSDictionary } public func asData() -> NSData! { return NSKeyedArchiver.archivedDataWithRootObject(self) } }
  21. Then creating a NSDictionary cache would be as simple as:

    let cache = Cache<NSDictionary>(name: "dictionaries")