Reputation: 1000
I have an app that downloads and displays a lot of images from parse. An image is added to the database almost every minute. Since PFFile is automatically cached with no expiration date, even though I only need to display recent images, the older images still stay in cache thus occupying a lot of storage space. Because of this now the app takes about 5GB of storage on my iPhone. I have been doing a lot of research on this issue and found out that Parse does not have a public api for cleaning up PFFile Cache and also it doesn't allow setting expiration date on the cached files. Is there a workaround on this where I could manually delete older cache data?
Thank you in advance.
Upvotes: 3
Views: 2086
Reputation: 1661
TimWhiting's answer translated to Swift 2.1:
Note: I have to say thought that is better to use file urls and use your own cache system as Matt S says, I'm using this just for testing purposes. I wish also that Parse could provide us with the correct path instead of having to hardcode it, that's why I think is 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)")
}
}
Upvotes: 4
Reputation: 2497
deadbeef's answer translated to Swift for anyone that needs 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")
}
}
}
Upvotes: 1
Reputation: 5563
Here is a method you can use to clean up the PFFile Cache. If you call it when your app starts, before initializing Parse, I think it should be safe. You can check the file creation date in the for loop if you don't want to remove 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;
}
}
}
Upvotes: 10
Reputation: 1902
Per this answer from Hector: https://www.parse.com/questions/pffile-cache-size you can manually clear your applications ~/Library/Caches folder if you are insistent upon it. However, I'm fairly certain this will also impact things like NSURL/AFNetworking caches, amongst others.
My suggestion? Don't use PFFile to download the file. PFFile gives you back the remote URL to where it's hosted on Parse's site, so you can pass that to something like AFNetworking or NSURLSession to actually download the image for you, and then you can then assign cache lifetimes (or manage it yourself) since those systems actually support that, unlike PFFile.
Upvotes: 1