I wrote a simple program to help me debug.
#import "UIImage+saveScreenShotOnDisk.h"
#implementation UIImage (saveScreenShotOnDisk)
-(void)saveScreenshot{
NSData * data = UIImagePNGRepresentation(self);
[data writeToFile:#"foo.png" atomically:YES];
}
#end
After it's executed, I want to know where foo.png is located.
I went to
~Library/Application Support
and I can't find foo.png. Where is it?
If I do
BOOL result = [data writeToFile:#"foo.png" atomically:YES];
the result will be NO, which is kind of strange given that the simulator, unlike the iPhone, can write anywhere.
You need to direct the NSData object to the Path you want the data to be saved in:
NSString *docsDir;
NSArray *dirPaths;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
NSString *databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent:#"foo.png"]];
[data writeToFile:databasePath atomically:YES];
This will save your file in your App's Folder on the device (or the simulator).
The default place, where the files are stored, is the folder your executable is stored.
See where your executable is stored via right clicking Products->YourExecutable :
Then open in finder.
Here pawel.plist resource create via
NSArray *a = #[#"mybike", #"klapki", #"clapki", #"ah"];
[a writeToFile:#"pawel.plist" atomically:NO];
For Swift, based on Shachar's answer:
let path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] + "/foo.png"
data?.writeToFile(path, atomically: true)
U forgot to provide location or path where u want to write.Check this writeToFile:options:error:
Writes the bytes in the receiver to the file specified by a given path.
- (BOOL)writeToFile:(NSString *)path options:(NSDataWritingOptions)mask error:(NSError **)errorPtr
Parameters
path
The location to which to write the receiver's bytes.
mask
A mask that specifies options for writing the data. Constant components are described in “NSDataWritingOptions”.
errorPtr
If there is an error writing out the data, upon return contains an NSError object that describes the problem.
You can give a search for "NSDocumentsDirectory", I usually search the path for the documents directory using this method, and then append my file name to it. in the method writeToFile:, this appended path is provided. Then using iTunes>application, scroll to bottom, select your app, and you should be able to see the saved file.
PS: you should have set a valur in plist that specifies that you application uses the phone storage.
Related
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];
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
Now i am retrieving file from document directory by specific name in iOS with following code.
NSMutableArray *arrayToSearch = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSError * error;
arrayToSearch = (NSMutableArray *)[[NSFileManager defaultManager] contentsOfDirectoryAtPath:[NSString stringWithFormat:#"%#/Manual.txt",documentsDirectory] error:&error];
I am sure i have the Manual.txt file in document directory.
However it doesn't show anything in tableView.
I also reload tableView.
Is there anything wrong?
The method is contentsOfDirectoryAtPath:. Read the name of the method. Read the description in the docs. The path you pass must reference a directory, not a file.
What you are trying to do doesn't make sense logically. If you know a specific file, then why search for it? Why create an array?
If you want to see if the file exists, use the fileExistsAtPath: method of NSFileManager.
If you just want the filename in the array then do:
NSString *filename = [documentsDirectory stringByAppendingPathComponent:#"Manual.txt"];
[arrayToSearch addObject:filename]; // since the array was pre-allocated
Please don't use stringWithFormat to create the filename. Use the proper NSString path methods like I did above.
I want to save a file to a folder, and then retrieve all the contents of that folder, so I do:
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:storageFolder];
// StorageFolder is just a string like: "#"/FavoritesFolder"
// Filename is just a title given like "myTune.mp3"
NSString *destinationString = [NSString stringWithFormat:#"%#/%#",dataPath,filename];
BOOL success = [object writeToFile:destinationString atomically:YES];
Then I want to retrieve the object, so I do
NSArray *dirContents = [[NSFileManager defaultManager]contentsOfDirectoryAtPath:dataPath error:nil];
But all I get an array of filename (like myTune.mp3). not the Object which is a NSDictionary. What am I doing wrong?
You aren't strictly 'doing' anything wrong. It's your expectations that are wrong. The method you're using (contentsOfDirectoryAtPath:)
Performs a shallow search of the specified directory and returns the paths of any contained items.
If you want to load the file back into memory you need to:
Decide which file you want
Get the full path to the file (directory path and file name)
Load the file (if it's a dictionary, dictionaryWithContentsOfFile:)
Which is the best way to store the downloaded images? From there I should be able to use them anywhere in my application, and images should not be deleted at any case (like low space). Any help please.
As per the standard, App related files(Data) need to be stored in document directory only. Once image get download store that images in document directory and maintain unique name for image identification.
-(NSString *)writeDataAsFile:(NSData *)imageData
{
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentsDirectory = [paths objectAtIndex:0];
NSString * thumbNailFilename = [NSString stringWithFormat:#"%#.png",[self GetUUID]]; // Create unique iD
NSString * thumbNailAppFile = [documentsDirectory stringByAppendingPathComponent:thumbNailFilename];
if ([imageData writeToFile:thumbNailAppFile atomically:YES])
{
return thumbNailFilename;
}
return nil;
}
use this method to store the image(downloaded NSData) in document directory.
Retrieve image from the document directory like this
UIImage *thumbnailHomeImage = [UIImage imageWithContentsOfFile:[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:#"%#",imageName]];
take a look at this image caching library. ive used it quite a few times, its really useful