I am caching an image locally..That same image will be used in few screens. Steps for doing this is as follows:
Get image from cache
If not present in NSCache, get image from Cache directory
If not present in Cache Directory, download from Internet
Save downloaded image to dir
Insert the image in cache
//Helper class is as
class ImageCacheHelper:NSObject{
static var cache = NSCache()
static var isNotRunningDispatch:Bool = true
class func setObjectForKey(imageData:NSData,imageKey:String){
ImageCacheHelper.cache.setObject(imageData, forKey: imageKey)
}
class func getObjectForKey(imageKey:String)->NSData?{
return ImageCacheHelper.cache.objectForKey(imageKey) as? NSData
}
class func getImage(imageUrl:String,completionHandler:(NSData)->()){
if ImageCacheHelper.isNotRunningDispatch{
ImageCacheHelper.isNotRunningDispatch = false
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), {
let imgUrl = NSURL(string:imageUrl)
let imageData = NSData(contentsOfURL: imgUrl!)!
ImageCacheHelper.setObjectForKey(imageData, imageKey: "\(imageUrl.hashValue)")
ImageCacheHelper.isNotRunningDispatch = true
completionHandler(imageData)
})
}else{
print("alerady started loading image")
}
}
}
//How i call this from ViewController class is as
let userImageUrl = "\(appBaseUrl)\(imageUrlString)"
let fileManager = NSFileManager.defaultManager()
let diskPaths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomainMask.UserDomainMask, true)
let cacheDirectory = diskPaths[0] as NSString
let diskPath = cacheDirectory.stringByAppendingPathComponent("\(userImageUrl.hashValue)")
if let data = ImageCacheHelper.getObjectForKey("\(userImageUrl.hashValue)"){
let userImage = UIImage(data: data)
self.userImgView.image = userImage
}else if fileManager.fileExistsAtPath(diskPath){
let image = UIImage(contentsOfFile: diskPath)
self.userImgView.image = image
ImageCacheHelper.setObjectForKey(UIImageJPEGRepresentation(image, 1.0)!, imageKey: "\(userImageUrl.hashValue)")
}else {
ImageCacheHelper.getImage(userImageUrl){ imageData in
imageData.writeToFile(diskPath, atomically: true)
dispatch_async(dispatch_get_main_queue()){
let userImage = UIImage(data: imageData)
self.userImgView.image = userImage
}
}
}
Flaws That I see in my code are as follows:
Creating a static variable for NSCache.
Would be great if settingObject in NSCache, getting would be as of NSUserDefaults.
How to optimize this?
Here is a snippet of project that i have tried to do https://drive.google.com/file/d/0B6dTvD1JbkgBS1k3Ry1xNmZ1VHc/view?usp=sharing