Data not being written to file? - ios

I'm using FastttCamera as a wrapper on AVFoundation in order to implement a camera in my app. Things appear to work fine until I try to save a captured image with the following code:
- (void)cameraController:(FastttCamera *)cameraController didFinishScalingCapturedImage:(FastttCapturedImage *)capturedImage
{
//Use the image's data that is received
pngData = UIImagePNGRepresentation(capturedImage.scaledImage);
NSLog(#"1 The size of pngData should be %lu",(unsigned long)pngData.length);
//Save the image someplace, and add the path to this transaction's picPath attribute
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
int timestamp = [[NSDate date] timeIntervalSince1970];
NSString *timeTag = [NSString stringWithFormat:#"%d",timestamp];
filePath = [documentsPath stringByAppendingString:timeTag]; //Add the file name
NSLog(#"The picture was saved at %#",filePath);
[self.imageWell setImage:capturedImage.scaledImage];
}
and
...
[pngData writeToFile:filePath atomically:YES]; //Write the file
NSLog(#"The pngData is written to file at %#",filePath);
NSLog(#"2 The size of this file should be %lu",(unsigned long)pngData.length);
self.thisTransaction.picPath = filePath;
...
I try to retrieve the picture later for use in a tableview cell, but nothing shows up. So I started trying to track where things go wrong, and apparently the data is not actually being written to the file specified by the file path. I'm getting the following console readouts from strategically placed NSLogs:
The pngData is written to file at /var/mobile/Containers/Data/Application/114FC402-83E0-4D15-B1E0-68E09DAB34DC/Documents1431292149
The size of this file should be 213633
and this return from the file at the file path:
The size of fileSizeFromFilePath is 0
I've looked at quite a few SO questions, but haven't been able to figure it out. Can someone please show me where I'm going wrong?

The pngData is written to a incorrect path /path/to/sandbox/Documents1431292149 which is not exist.
You should replace
filePath = [documentsPath stringByAppendingString:timeTag];
with
filePath = [documentsPath stringByAppendingPathComponent:timeTag];

Related

Cleared the files but memory is not reduced

I am creating an application. I am storing the files in Document directory. And after my work completed, delete the files from document directory as like below:
NSMutableDictionary * Dictionary = [NSMutableDictionary alloc]init];
// Next every file storing into this dictionary like below
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *baseDir = [paths objectAtIndex:0];
NSString *pathComp = [baseDir stringByAppendingPathComponent:[NSString stringWithFormat:#"IMG%d.PNG",presentCount];
fileURL = [NSURL fileURLWithPath:pathComp];
[Dictionary setObject:fileURL forKey:fileURL];
while ([[Dictionary allKeys]count]!=0) {
NSURL *deleteFileURL = [[Dictionary allKeys] lastObject];
NSLog(#"Path %#",deleteFileURL.path);
[[NSFileManager defaultManager] removeItemAtPath:deleteFileURL.path error:nil];
[Dictionary removeObjectForKey:deleteFileURL];
}
Here my problem is, after delete the files from document directory, memory is not reduced, still it's occupying as like files exist. Due to this issue, my is crashing. So please help me how to clear the memory.
Actually i am getting the files(Photos ) from the server and first placing in documents directory,and trying to save using photo library.Once i give input from dictionary to photo library, after completion handler, i am trying to delete the file.Its removed and photo saved, but memory is not reduced.
1、Remove the file after checking for the existence of a file on the path, and check the return value of removeItemAtPath: to determine if the deletion succeeded.
NSString *path = #"a/b";
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
BOOL success = [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
// Check the success's value
}

Saved photos don't appear on device after update

On my iPhone app, I'm saving pictures associated with an event via this code:
[pngData writeToFile:filePath atomically:YES]; //Write the file
self.thisTransaction.picPath = filePath;
Later I retrieve and display the photo with this code:
UIImage * image = [UIImage imageWithContentsOfFile:thisTransaction.picPath];
Works great on my iPad (I don't have an iPhone).
However, if I update the app by connecting the iPad to my MB Pro after an Xcode code modification not involving the above lines, then disconnect and run it independently, the picture at the expected picPath is not retrieved. All other data associated with thisTransaction in Core Data is intact and unchanged, but the expected picture doesn't appear on the device after the update.
Can someone please tell me where I'm going wrong?
Edit to clarify file path construction
pngData = UIImagePNGRepresentation(capturedImage.scaledImage);
NSLog(#"1 The size of pngData should be %lu",(unsigned long)pngData.length);
//Save the image someplace, and add the path to this transaction's picPath attribute
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
int timestamp = [[NSDate date] timeIntervalSince1970];
NSString *timeTag = [NSString stringWithFormat:#"%d",timestamp];
filePath = [documentsPath stringByAppendingPathComponent:timeTag]; //Add the file name
NSLog(#"1 The picture was saved at %#",filePath);
The console log shows this filePath:
/Users/YoursTruly/Library/Developer/CoreSimulator/Devices/65FB33E1-03A7-430D-894D-0C1893E03120/data/Containers/Data/Application/EB9B9523-003E-4613-8C34-4E91B3357F5A/Documents/1433624434
The issue you are having is that the location of an app's sandbox can change over time. Typically this happens when an app is updated. So the worst thing you can do is persist absolute file paths.
What you need to do is persist just the part of the path relative to the base path (the "Documents" folder in this case).
Then when you want to reload the file again, append the persisted relative path to the current value of the "Documents" folder.
So your code needs to be something like this:
Save the file:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
int timestamp = [[NSDate date] timeIntervalSince1970];
NSString *timeTag = [NSString stringWithFormat:#"%d",timestamp];
filePath = [documentsPath stringByAppendingPathComponent:timeTag]; //Add the file name
[pngData writeToFile:filePath atomically:YES]; //Write the file
self.thisTransaction.picPath = timeTag; // not filePath
Load the file:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
NSString *filePath = [documentsPath stringByAppendingPathComponent:thisTransaction.picPath];
UIImage *image = [UIImage imageWithContentsOfFile:filePath];

iPhone - Add UIImage to Folder

I have a folder called PhotoSet in my Xcode iOS App. I want to convert the UIImage to a jpg and put it into the folder. Here is what I have so far (by the way, if it is at all relevant, the UIImage is taken from a photo that the user takes):
NSData * imageData = UIImageJPEGRepresentation(chosenImage, 1.0);
if (imageData != nil) {
[imageData writeToFile:#"/Users/Toly/Desktop/PhotoMap/PhotoMap/PhotoSet/test.jpg" atomically:YES];
}
I get no errors or warnings. However, no picture gets saved to any folder. What should I do?
You need to write to a directory that is actually on the iPhone. Most of the time you'll want to write to the documents directory. You can get the path to it like this:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
This gives you the base documents directory, if you want to place the folder in a sub directory you'll need to create that folder before you do like so.
NSString *folderPath = [documentsDirectory stringByAddingPathComponent:#"myFolder/images"];
NSError *error = nil;
NSFileManager *fm = [[NSFileManager alloc] init]
[fm createDirectoryAtPath:folderPath withIntermediateDirectories:YES attributes:nil error:&error];
Then to save your image data to that folder you'll do something like this
NSString *imageDataPath = [folderPath stringByAppendingPathComponent:#"myImage"];
BOOL success = [imageData writeToFile:imageDataPath];
Also, you can NSLog the imageDataPath it'll give you the exact location that file is saved so you can navigate to the actual file in finder if you're using the iOS simulator.
Your phone does not contain a data structure of files mirroring "/Users/Toly/Desktop/PhotoMap/PhotoMap/PhotoSet/test.jpg"
If you want the image to persist in memory, try using nsuserdefaults, or xcassets or Coredata. If you are absolutely intent on writing to a file, check out the NSCoding and NSFileManager tutorial below:
http://www.raywenderlich.com/1914/nscoding-tutorial-for-ios-how-to-save-your-app-data

How can I get the file path from a UIImage?

Usually it's the other way around, you use the path to display the image. I was wondering if you can get the path if you already have the image.
if you already have the image i.e. have added the file to your resources, you can use this to get the file path;
NSString *string = [[NSBundle mainBundle] pathForResource:#"IMAGE_FILE_NAME" ofType:#"jpg"]; // or ofType:#"png", etc.
I don't believe it is possible to get it directly from UIImage.
Best way is to save the image in a directory, then you will have the file path.
//image is your UIImage;
if (image != nil)
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* path = [documentsDirectory stringByAppendingPathComponent:
#"test.png" ];
NSData* data = UIImagePNGRepresentation(image);
[data writeToFile:path atomically:YES];
}
path will be your filepath.
Once a UIImage is created, the image data is loaded into memory and no longer connected to the file on disk. As such, the file can be deleted or modified without consequence to the UIImage and there is no way of getting the source path from a UIImage.

Creating image thumbnails to be loaded into tableview from files in app directory

I need some help for a problem which I can't solve but I think I am close to the solution. Here is it:
In a version of my app, I was able to populate a tableview (in CellforRowAtIndexPath) with images taken from the Assetlibrary using the following 2 lines:
ALAsset someAsset = [theAssets objectAtIndex:indexPath.row];
[cell.imageView setImage:[UIImage imageWithCGImage:[someAsset thumbnail]]];
Now, I am trying to read image files from the directory and stored in an NSMutableArray. I can see the filenames when I NSLog the NSMutableArray. But how do I now cause the files to be converted into images and displayed in my tableview in the same way I did why using the Assetlibrary? I have tried several times, but the app either crashes or it does not show the image thumbnails in the table view. For example, this statement does not display the image but the app does not crash:
UIImage *anImage = [UIImage imageWithContentsOfFile:[self.listTable objectAtIndex:0]];
When I setImage in the next line, it doesn't work. Someone please help!
UPDATED: The contents of self.listable when I NSLog it is something like this: "19-10-25 276-10-12.jpg",
"19-10-37 276-10-12.jpg",
"19-10-54 276-10-12.jpg",
"19-10-65 276-10-12.mov", etc.
When I NSLog my documents directory, it is: /var/mobile/Applications/8CB1368A-AAE2-4815-BD26-A7B7C8536193/Documents.
Apps can only imageWithContentsOfFile for files located within the app's sandbox (e.g. in Documents, the bundle, etc.) If these files are located in your Documents folder, you get the full path via:
NSString *documentsFolder = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *imageFullPath = [documentsFolder stringByAppendingPathComponent:imageFilename];
You can then use that in imageWithContentsOfFile.
Update:
You asked:
my directoryContents is an NSArray; how do I convert it to NSString and then [documentsFolder stringByAppendingPathComponent ...] and store each fullpath in the NSMutableArray?
You might do something like:
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSArray *filenames = [fileManager contentsOfDirectoryAtPath:documentsDirectory error:nil];
NSMutableArray *paths = [[NSMutableArray alloc] initWithCapacity:[filenames count]];
for (NSString *filename in filenames)
{
[paths addObject:[documentsDirectory stringByAppendingPathComponent:filename]];
}
NSLog(#"%s filenames = %#", __FUNCTION__, filenames);
NSLog(#"%s paths = %#", __FUNCTION__, paths);

Resources