How to clear the PFFIle cache (Parse.com)

I have an application that downloads and displays a lot of images from parsing. The image is added to the database almost every minute. Since the PFFile is automatically cached with no expiration date, although I only need to display the latest images, the old images still remain in the cache, so they take up a lot of storage space. Because of this, the app now takes up about 5GB of storage on my iPhone. I did a lot of research into this issue and found out that Parse does not have a public api to clear the PFFile cache, nor does it allow you to set an expiration date for cached files. Is there a workaround for this where I could manually delete the old cache data?

Thanks in advance.

+3


source to share


4 answers


In response to this answer from Hector: https://www.parse.com/questions/pffile-cache-size, you can manually empty the ~ / Library / Caches folder if you're persistent with it. However, I'm pretty sure it will also affect things like NSURL / AFNetworking caches.



My suggestion? Don't use PFFile to download the file. PFFile returns your remote url to where it is hosted on the Parse site, so you can pipe that to something like AFNetworking or NSURLSession to load the image for you, and then you can assign a cache lifetime (or manage it yourself) as these systems actually support this, unlike PFFile.

+1


source


Here is the method you can use to clear the PFFile cache. If you call this when your application starts, before initializing Parse, I think it should be safe. You can check the file creation date in a for loop if you don't want to delete everything.



+ (void)cleanUpPFFileCacheDirectory
{
    NSError *error = nil;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSURL *cacheDirectoryURL = [[fileManager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] lastObject];
    NSURL *PFFileCacheDirectoryURL = [cacheDirectoryURL URLByAppendingPathComponent:@"Parse/PFFileCache" isDirectory:YES];
    NSArray *PFFileCacheDirectory = [fileManager contentsOfDirectoryAtURL:PFFileCacheDirectoryURL includingPropertiesForKeys:nil options:0 error:&error];

    if (!PFFileCacheDirectory || error) {
        if (error && error.code != NSFileReadNoSuchFileError) {
            NSLog(@"Error : Retrieving content of directory at URL %@ failed with error : %@", PFFileCacheDirectoryURL, error);
        }
        return;
    }

    for (NSURL *fileURL in PFFileCacheDirectory) {
        BOOL success = [fileManager removeItemAtURL:fileURL error:&error];
        if (!success || error) {
            NSLog(@"Error : Removing item at URL %@ failed with error : %@", fileURL, error);
            error = nil;
        }
    }
}

      

+10


source


TimWhiting's answer translated into Swift 2.1:

Note. I have to say that it is better to use file urls and use your own caching system, as Matt S says, I only use this for testing purposes. I also want Parse to be able to provide us with the correct path and not require hardcoding, so I think it's better to use URLs.

func cleanUpParseDirectory(){
    let parseFilesCache = "Parse/PFFileCache"
    let fileManager = NSFileManager.defaultManager()
    let cacheDirectoryURL  = fileManager.URLsForDirectory(NSSearchPathDirectory.CachesDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask)
    let PFFileCacheDirectoryURL = cacheDirectoryURL[0].URLByAppendingPathComponent(parseFilesCache, isDirectory: true)
    do {
        let PFFileCacheDirectory = try fileManager.contentsOfDirectoryAtURL(PFFileCacheDirectoryURL, includingPropertiesForKeys: nil, options: [])
        print("number of cached files: \(PFFileCacheDirectory.count)")
        for fileURL in PFFileCacheDirectory {
            try fileManager.removeItemAtURL(fileURL)
        }
        print("Success removing items")
    } catch let error {
        print("Error: \(error)")
    }
}

      

+3


source


deadbeef's answer translates to Swift for those who need it.

func cleanUpParseDirectory(){

    var error: NSError?

    var fileManager: NSFileManager = NSFileManager.defaultManager()

    var cacheDirectoryURL: [NSURL] = fileManager.URLsForDirectory(NSSearchPathDirectory.CachesDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask) as! [NSURL]

    var PFFileCacheDirectoryURL: NSURL = cacheDirectoryURL[0].URLByAppendingPathComponent("Parse/PFFileCache", isDirectory: true)

    var PFFileCacheDirectory: [AnyObject]? = fileManager.contentsOfDirectoryAtURL(PFFileCacheDirectoryURL, includingPropertiesForKeys: nil, options: NSDirectoryEnumerationOptions.allZeros, error: &error)// [fileManager contentsOfDirectoryAtURL:PFFileCacheDirectoryURL includingPropertiesForKeys:nil options:0 error:&error];

    if (PFFileCacheDirectory == nil || error != nil) {
        if ((error != NSFileReadNoSuchFileError && error!.code != NSFileReadNoSuchFileError)) {
            println("error finding path")
        } else {
            println("no error finding path")
        }
        return
    }

    println("number of cached files: \(PFFileCacheDirectory!.count)")

    for fileURL in PFFileCacheDirectory! {


        var success: Bool = fileManager.removeItemAtURL(fileURL as! NSURL, error: &error)

        if ((!success != false || error != nil) ) {

            println("error removing item")

            error = nil

        } else {
            println("success removing item")
        }
    }
}

      

+1


source







All Articles