iOS - Get sum of filesize in directory - objective-c

I have the following code I use to cache photos I load off Flickr in the device's memory:
NSURL *urlForPhoto = [FlickrFetcher urlForPhoto:self.photo format:FlickrPhotoFormatLarge];
NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *imagePath = [rootPath stringByAppendingString:[self.photo objectForKey:FLICKR_PHOTO_ID]];
NSData *dataForPhoto;
NSError *error = nil;
if ([[NSFileManager defaultManager] fileExistsAtPath:imagePath]) {
dataForPhoto = [NSData dataWithContentsOfFile:imagePath];
} else {
dataForPhoto = [NSData dataWithContentsOfURL:urlForPhoto];
[dataForPhoto writeToFile:imagePath atomically:YES];
}
I want to limit this to 10MB and then if the limit is reached to remove the oldest photo in the cache, how can I get the total size of all the files I've saved and check which one is the oldest?

You can get the size of a file like so
NSError *attributesError = nil;
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:URL error:&attributesError];
int fileSize = [fileAttributes fileSize];
So you can maybe iterate through all the files in the folder and add up the file sizes...not sure if theres a direct way to get the directory size, also theres this SO post talking about this aswell, you can find a solution here
To find the creation date of the file you can do
NSString *path = #"";
NSDictionary* fileAttribs = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
NSDate *result = [fileAttribs valueForKey:NSFileCreationDate]; //or NSFileModificationDate
Hope it helps

Related

Save locally generated PDF to app's documents folder in iOS8

It would seem that my apps no longer are able to save files to their documents folder when doing this:
NSString *path = [documentsDirectory stringByAppendingPathComponent:fileName];
NSData *dta = [[NSData alloc] init];
dta = [NSData dataWithContentsOfFile:path];
NSLog(#"writing file: %#", path);
if ([dta writeToFile:path options:NSAtomicWrite error:nil] == NO) {
NSLog(#"writeToFile error");
}else {
NSLog(#"Written: %#", path);
[self addSkipBackupAttributeToItemAtURL:[NSURL fileURLWithPath:path]];
}
I do get "Written" in the log with the full path:
Written: /var/mobile/Containers/Data/Application/ECBCD65D-A990-4758-A07F-ECE48E269278/Documents/9d440408-4758-4219-9c9c-12fe69cf82f2_pdf.pdf
And as long as I don't quit the app I can load the PDF in a UIWebView like this (pdfPath is a string that I pass to the function that loads the PDF file):
[www loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:pdfPath]]];
Any help at all is as always greatly appreciated.
Okay, after mucking about I found that since the documents directory changes path every time I run the app, I had to:
Write the file to the documents folder with the complete path to
the file:
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask ,YES );
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent: fileName];
NSData *dta = [[NSData alloc] init];
dta = [NSData dataWithContentsOfFile:path];
if ([dta writeToFile:path options:NSAtomicWrite error:nil] == NO) {
NSLog(#"writeToFile error");
}else {
NSLog(#"Written: %#", path);
[self addSkipBackupAttributeToItemAtURL:[NSURL fileURLWithPath:path]];
}
Save only the file name to my database
Load the file by using the full newly generated Documents directory path and append the file name from my database:
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent: pdfPath];

Using apples suggested code isnt excluding files from icloud backup

I have an app that has been rejected 3 times due to icloud backup issues. Apple have written back to say that I need to use there bit of code to exclude the files from being backed up. However this isnt working and i am at wits end.
Here is the code i've used
- (BOOL)downloadFile:(NSString *)fileURI targetFolder:(NSString *)targetFolder targetFilename:(NSString *) targetFilename{
#try{
NSError *error = nil;
NSURL *url = [NSURL URLWithString:fileURI];
if(![url setResourceValue:#"YES" forKey:NSURLIsExcludedFromBackupKey error:&error]){
NSLog(#"KCDM: Error excluding %# from backup %#", fileURI, error);
}else{
NSData *urlData = [NSData dataWithContentsOfURL:url];
if ( urlData )
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dataPath = [documentsDirectory stringByAppendingString:targetFolder];
NSError *error = nil;
if(![[NSFileManager defaultManager] fileExistsAtPath:dataPath]){
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:YES attributes:nil error:&error];
}
NSString *filePath = [NSString stringWithFormat:#"%#/%#%#", documentsDirectory,targetFolder,targetFilename];
return [urlData writeToFile:filePath atomically:YES];
}
}
}
#catch(NSException * e){
NSLog(#"Error download: %#",e);
}
return false;
}
what am i doing wrong?
You try to set NSURLIsExcludedFromBackupKey for the http://-Url you download from the web. That won't work.
You have to set this key-value pair for the actual file that is saved on the device.
Additionally you are not supposed to set this value to the string #"YES", you must use a NSNumber object representing the boolean value YES.
For example:
NSString *filePath = [NSString stringWithFormat:#"%#/%#%#", documentsDirectory,targetFolder,targetFilename];
if ([urlData writeToFile:filePath atomically:YES]) {
// did write correctly
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
if(![fileURL setResourceValue:#YES forKey:NSURLIsExcludedFromBackupKey error:&error]){
NSLog(#"KCDM: Error excluding %# from backup %#", fileURI, error);
return NO;
}
// could set NSURLIsExcludedFromBackupKey
return YES;
}
// could not write to file
return NO;

How to save and retrieve files to apps temp folder in ios

I'm new to IOS development. I'm developing an app which involves downloading files and saving that to apps temp folder and I dont know how to do that my current code is given below
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
NSLog(#"%#",tmpDirURL);
NSString *myString = [tmpDirURL absoluteString];
for(int i=0;i<responseArray.count;i++){
ASIHTTPRequest *saveUrl = [ASIHTTPRequest requestWithURL:responseArray[i]];
[saveUrl setDownloadDestinationPath:myString];
[request startSynchronous];
}
NSError * error;
NSArray * directoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:myString error:&error];
NSLog(#"%#",directoryContents);
The response array contain a list of URL for downloading files. I know something wrong with my code but I cant find out that error please help me to solve this problem
I found the solution'
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *htmlFilePath = [documentsDirectory stringByAppendingPathComponent:fileName];
[data writeToFile:htmlFilePath atomically:YES];
When downloadDestinationPath is set, the result of this request will be downloaded to the file at this location. If downloadDestinationPath is not set, download data will be stored in memory
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
NSLog(#"%#",tmpDirURL);
NSString *myString = [tmpDirURL absoluteString];
for(int i=0;i<responseArray.count;i++){
ASIHTTPRequest *saveUrl = [ASIHTTPRequest requestWithURL:responseArray[i]];
[saveUrl setDownloadDestinationPath:[myString stringByAppendingPathComponent:[NSString stringWithFormat:#"%i",i ]]; // for each file set a new location inside tmp
[request startSynchronous];
}
NSError * error;
NSArray * directoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:myString error:&error];
NSLog(#"%#",directoryContents);

Saving images to a directory

Hi I want to save an image to a directory, I pass the NSData and do what I think will save the file in a directory I create but the problem is that it doesn't save. This is what I have so far. Why doesn't the initWithContentsOfURL:encoding:error: work, it returns null but the other method I used works? The main problem is WRITETOURL which returns a 0 which i think means that the information wasn't stored properly, any tips?
NSFileManager *fm = [[NSFileManager alloc] init];
NSArray * directoryPaths = [fm URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask];
NSLog(#"%#", directoryPaths);
NSURL* dirPath = nil;
dirPath = [[directoryPaths objectAtIndex:0] URLByAppendingPathComponent:[NSString stringWithFormat:#"photos.jpeg"]];
NSError* theError = nil;
[fm createDirectoryAtURL:dirPath withIntermediateDirectories:YES attributes:nil error:&theError];
UIImage* photoToStore = [UIImage imageWithData:photoToSave];
NSString *pathContainingPhoto = [[NSString alloc] initWithFormat:#"%#.jpeg", UIImageJPEGRepresentation(photoToStore, 1.0)];
NSError *error = nil;
BOOL OK = [pathContainingPhoto writeToURL:dirPath atomically:YES encoding:NSUTF8StringEncoding error:&error];
NSLog(#"OK = %d", OK); //Returns 0
NSLog(#"%#", dirPath);
//WHY DOESNT THIS VERSION WORK?
// NSString *pathToFile = [[NSString alloc] initWithContentsOfURL:dirPath encoding:NSUTF8StringEncoding error:&error];
NSLog(#"%#", pathToFile);
NSString* pathToFile = [NSString stringWithContentsOfURL:dirPath encoding:nil error:nil];
NSArray *dirContents = [fm contentsOfDirectoryAtPath:pathToFile error:nil];
NSLog(#"%#", dirContents);
Do like this and int count in .h file and set its intial value count = 0; in viewDidLoad:
NSString *stringPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:[NSString stringWithFormat:#"Image_%d.png",count];
error = nil;
if (![[NSFileManager defaultManager] fileExistsAtPath:stringPath]) // removing item it already exuts
{
[[NSFileManager defaultManager] removeItemAtPath:stringPath error:&error];
}
if(photoToSave) // nsdata of image that u have
{
[photoToSave writeToFile:stringPath atomically:YES];
}
count++; // maintaining count of images

How to save an image dynamically

I am using photo library in my app. And after selecting image from photo library or camera i want to save that image into my Documents folder. So here i want to give name to that image while saving is it possible to set name to the selected image? If means please let me know. I am trying that only if possible i will post that.Thank you.
This is how I do it.. I'm copying and pasting my code so there's some additional functionality.
// image is a UIImage
// inputText is the user selected imagename
// date is a string I inserting to make pictures a unique identifier (i.e. no duplicate names)
NSData *imageData1 = UIImageJPEGRepresentation(image, 1.0);
NSString *imageFilename = [NSString stringWithFormat:#"%#-%#.jpg", inputText,date];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [NSString stringWithFormat:#"%#/%#", [paths objectAtIndex:0], imageFilename];
if([imageData1 writeToFile:path atomically:YES]){
NSLog(#"Write to Document folder success filename = %#",path);
}
Use following :
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *photoImage = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
NSString *savedDoc = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/myImageName.png"];
BOOL status = [[NSFileManager defaultManager] fileExistsAtPath:savedDoc];
if(status){
[[NSFileManager defaultManager] removeItemAtPath:savedDoc error:nil];
}
[UIImagePNGRepresentation(photoImage) writeToFile:savedDoc atomically:YES];
[picker dismissModalViewControllerAnimated:YES];
}
You can set any desired name when saving to document directory.
Declare an integer counterNo and initialize it to 0. And increase its value to change name dynamically.
UIImage *photoImage = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
counterNo++;
NSString *aaa = [NSString stringWithFormat:#"Documents/myImage-%d.png" , counterNo];
NSString *savedDoc = [NSHomeDirectory() stringByAppendingPathComponent:aaa];
BOOL status = [[NSFileManager defaultManager] fileExistsAtPath:savedDoc];
if(status){
[[NSFileManager defaultManager] removeItemAtPath:savedDoc error:nil];
}
[UIImagePNGRepresentation(photoImage) writeToFile:savedDoc atomically:YES];
[picker dismissModalViewControllerAnimated:YES];