Haneke / HanekeSwift

A lightweight generic cache for iOS written in Swift with extra love for images.
Apache License 2.0
5.2k stars 591 forks source link

Failed to write key <url> with error #245

Open egorzhdan opened 9 years ago

egorzhdan commented 9 years ago

I'm using hnk_setImageFromURL method to load images inside of UITableView custom cell. I'm getting this error:

[HANEKE][ERROR] Failed to write key with error Error Domain=NSCocoaErrorDomain Code=4 "The file “%6C%57%6C%38%57%55%46%6B%5F%6E%6F%72%6D%61%6C%2E%6A%70%65%67” doesn’t exist." UserInfo={NSFilePath=/var/mobile/Containers/Data/Application/124D0E32-2D2F-4147-B4F6-E7BAD612374E/Library/Caches/io.haneke/shared-images/auto-40.0x40.0-fill/%68%74%74%70%73:/%70%62%73%2E%74%77%69%6D%67%2E%63%6F%6D/%70%72%6F%66%69%6C%65%5F%69%6D%61%67%65%73/%35%37%31%30%31%33%36%30%33%34%36%31%38%34%34%39%39%32/%6C%57%6C%38%57%55%46%6B%5F%6E%6F%72%6D%61%6C%2E%6A%70%65%67, NSUnderlyingError=0x15f018850 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}

I think this is a bug in Haneke. If not, how can I fix it? Thanks.

talkaboutdesign commented 8 years ago

Have exactly the same thing happening.

dcharbonnier commented 8 years ago

Is there a way to reproduce this, can you share a piece of code ?

talkaboutdesign commented 8 years ago

I am setting my images inside a CollectionViewCell. Everything is smooth right away, scrolling down a collection view. If you quickly jump back up, these errors popup all the time. I am using lots of images. Sometimes the number can get high, like 200-300.

inspirationImage.hnk_setImageFromURL(image!, placeholder: UIImage(named: "Placeholder"), format: nil, failure: { (error) -> () in
                print("error getting image")
                }, success: { (image) -> () in
                    print("got image")
                    self.inspirationImage.image = image

                   // print(image.size.height, image.size.width)

            })

FYI I am also seeing a leak in Instruments that points back to this code in Haneke:

screenshot 2016-01-14 11 48 19

Thanks for your feedback in advance.

Macmee commented 8 years ago

+1 also having this issue

edit: for me the way to reproduce the bug is to:

let cache: Cache<UIImage> = {
  let cache = Cache<UIImage>(name: "video-thumbnails")
  cache.removeAll()
  return cache
}
  1. create a cache
  2. call removeAll on the cache
  3. attempt to insert into the cache
  4. an error writing to the file occurs "No such file or directory"

the problem does not occur if I remove the call to removeAll, or alternatively at the top of setDataSync I can put the following which fixes the problem as well:

let fileManager = NSFileManager.defaultManager()
if (!fileManager.fileExistsAtPath(path)) {
  do {
    try fileManager.createDirectoryAtPath(path, withIntermediateDirectories: true, attributes: nil)
  } catch {
    print("error re-creating directory", error as NSError)
  }
}
aksswami commented 8 years ago

I am facing the same issue as @Macmee. If I clear the cache and try to save image after that, I get above error.

coolnalu commented 8 years ago

same error!

[HANEKE][ERROR] Failed to write key http://domain.com/TqPVZbjF2UPRCpvuLm6Q7NKlcBNpJ22IPJvzAHP2/ca22e256-1b86-48a2-a9c0-d766884a163e_image.jpg with error Error Domain=NSCocoaErrorDomain Code=4 "The folder “http%3A%2F%2Fdomain.com%2FTqPVZbjF2UPRCpvuLm6Q7NKlcBNpJ22IPJvzAHP2%2Fca22e256-1b86-48a2-a9c0-d766884a163e_image.jpg” doesn’t exist." UserInfo={NSFilePath=/Users/terry/Library/Developer/CoreSimulator/Devices/6D75FE0E-832E-4E05-B6BB-3187705783AF/data/Containers/Data/Application/7D132826-410D-4D36-ABE3-FD2C3098634B/Library/Caches/io.haneke/shared-images/Default/http%3A%2F%2Fdomain.com%2Fsmack%2Ffiles%2FTqPVZbjF2UPRCpvuLm6Q7NKlcBNpJ22IPJvzAHP2%2Fca22e256-1b86-48a2-a9c0-d766884a163e_image.jpg, NSUserStringVariant=Folder, NSUnderlyingError=0x7fb4f4e91080 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
greendog99 commented 7 years ago

It looks like the cache directory is being deleted in Haneke/Cache.swift in the removeAll() function. The exact line is try FileManager.default.removeItem(atPath: path). If I comment this line out of the Haneke code, things appear to work correctly (cached items are removed, but the cache directory remains).

I don't know enough about the Haneke source code (which has no comments) to know why this is there, or what the side effects might be to removing it. I suspect it's there as a failsafe in case the removeAllData() call a few lines above misses something.

Another option may be adding a createDirectoryAtPath() statement (per @Macmee) immediately after the removeItem() statement?