I am saving photos a user takes with UIImagePickerController
to the user's documents directory. When the app successfully uploads the image to the server, I would like to delete the locally saved image.
I save the image to documents directory like this:
/*Save image to documents directory, as opposed to core data for better memory management*/
NSString *myUniqueName = [NSString stringWithFormat:@"%lu.png", (unsigned long)([[NSDate date] timeIntervalSince1970]*10.0)];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
NSString *filePath = [documentsPath stringByAppendingPathComponent:myUniqueName]; //Add the file name
BOOL successWriteLocalImage = [imageToUpload writeToFile:filePath options:NSDataWritingAtomic error:&error];
if(successWriteLocalImage){
//NSLog(@"no error success writing to file");
NSLog(@"successfully write to file path %@", filePath);
}else{
NSLog(@"Unresolved error writing to file %@, %@", [error localizedDescription], [error userInfo]);
}
/*Save file path of leaf image to core data here*/
collectedLeaf.localImageFilePath = filePath;
[context save:&error];
I delete the same file like so:
/*delete image stored in documents directory from collecting w/o internet connection*/
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
NSString *filePath = [documentsPath stringByAppendingPathComponent:collectedLeaf.localImageFilePath];
NSError *error;
BOOL successDeleteLocalImage = [fileManager removeItemAtPath:filePath error:&error];
if(successDeleteLocalImage){
NSLog(@"SUCCESS DELETE IMAGE NO ERROR");
collectedLeaf.localImageFilePath = nil;
}else{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
The successful write/save to documents directory prints, successfully write to file path /var/mobile/Containers/Data/Application/EA08B79A-7484-4568-82CE-079B4055CDA7/Documents/15130563374.png
.
The error in removing the file logs
Unresolved error Error Domain=NSCocoaErrorDomain Code=4 "“15130563374.png” couldn’t be removed." UserInfo={NSFilePath=/var/mobile/Containers/Data/Application/EA08B79A-7484-4568-82CE-079B4055CDA7/Documents/var/mobile/Containers/Data/Application/EA08B79A-7484-4568-82CE-079B4055CDA7/Documents/15130563374.png, NSUserStringVariant=(
), NSUnderlyingError=0x1c4a4b4c0 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}, {
NSUnderlyingError = "Error Domain=NSPOSIXErrorDomain Code=2 \"No such file or directory\"";
I'm not sure why the file can't be removed - or that it returns not found - when its the same exact file path as the one I write to.
Issue is pretty clear. The file where you saved the file is
/var/mobile/Containers/Data/Application/EA08B79A-7484-4568-82CE-079B4055CDA7/Documents/15130563374.png
And the location where you are trying to delete is
/var/mobile/Containers/Data/Application/EA08B79A-7484-4568-82CE-079B4055CDA7/Documents/var/mobile/Containers/Data/Application/EA08B79A-7484-4568-82CE-079B4055CDA7/Documents/15130563374.png
So clearly you are trying to delete image at wrong path.
Issue:
collectedLeaf.localImageFilePath = filePath;
Saves the images absolute path and not the relative path. So
NSString *filePath = [documentsPath stringByAppendingPathComponent:collectedLeaf.localImageFilePath];
will append the absolute path of the image to document directory path hence results in issue
Solution:
Save just the unique name of file in core data
collectedLeaf.localImageFilePath = myUniqueName;
That should solve your issue
Additional Piece of Information:
Never ever save the absolute path of file in core data. Location of the document directory will change between app quit and launch. So saving absolute file path is not a option. Save file name and reconstruct URL from file name