如何清除PFFIle缓存(Parse.com)

时间:2014-11-05 21:30:27

标签: ios caching parse-platform nscache pffile

我有一个应用程序,可以从解析中下载并显示大量图像。几乎每分钟都会将图像添加到数据库中。由于PFFile自动缓存没有过期日期,即使我只需要显示最近的图像,旧的图像仍然保留在缓存中,因此占用了大量的存储空间。因此,该应用程序在我的iPhone上占用大约5GB的存储空间。我一直在对这个问题进行大量研究,发现Parse没有用于清理PFFile Cache的公共API,也不允许在缓存文件上设置过期日期。有没有解决方法,我可以手动删除旧的缓存数据?

提前谢谢。

4 个答案:

答案 0 :(得分:10)

这是一种可用于清理PFFile缓存的方法。如果你在应用程序启动时调用它,在初始化Parse之前,我认为它应该是安全的。如果您不想删除所有内容,可以在for循环中检查文件创建日期。

+ (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;
        }
    }
}

答案 1 :(得分:3)

TimWhiting的回答翻译成Swift 2.1:

注意:我必须说最好使用文件网址并使用自己的缓存系统,因为Matt S说,我只是出于测试目的使用它。我也希望Parse可以为我们提供正确的路径而不必对其进行硬编码,这就是我认为使用URL更好的原因。

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)")
    }
}

答案 2 :(得分:1)

根据Hector的答案:https://www.parse.com/questions/pffile-cache-size如果您坚持使用它,您可以手动清除您的应用程序〜/ Library / Caches文件夹。但是,我相当肯定这也会影响NSURL / AFNetworking缓存等等。

我的建议?不要使用PFFile下载文件。 PFFile会将您的远程URL返回到Parse网站上的托管位置,因此您可以将其传递给AFNetworking或NSURLSession以实际为您下载图像,然后您可以分配缓存生命周期(或自己管理),因为这些与PFFile不同,系统实际上支持它。

答案 3 :(得分:1)

对于任何需要它的人来说,deadbeef的答案都被翻译成了Swift。

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")
        }
    }
}