dataWithContentsOfFile return null - ios

NSString *path = dict[#"fileURL"];
NSData *imageData = [NSData dataWithContentsOfFile:path];
imageData is null
dict[#"fileURL"] =
/var/mobile/Containers/Data/Application/0906AB53-CE1F-45EF-8E00-9D0B7C98956C/Documents/ccc/image/1446625127.png
I download the device container and the image did exist.
What's wrong?

It's failed to retrieve your file. Use -dataWithContentsOfFile:options:error: to find why it is failed.
NSError* error = nil;
NSString *path = dict[#"fileURL"];
NSData *data = [NSData dataWithContentsOfFile:path options: 0 error: &error];
if (data == nil)
{
NSLog(#"Failed to read file, error %#", error);
}
else
{
// parse the value
}

I thing you should need to use [NSFileManager defaultManager] to store and fetch the image in your application storage instead of writing static path.
Static path is ok withing the simulator but in the real environment you should need to have the actual path. So [NSFileManager defaultManager] will help you.
if([[NSFileManager defaultManager] fileExistsAtPath:filepath)
{
NSData *data = [[NSFileManager defaultManager] contentsAtPath:filepath];
}
else
{
NSLog(#"File not exits");
}
In filepath you need to pass only your folder and file name. not full path like yours.
IE.
filepath = "Documents/ccc/image/1446625127.png";
NOTE:
This is not a actual answer. This will help you to manage the image into your application storage.

Related

Downloaded images has zero bytes in document directory

I am trying to download and store image from webURL to Document Directory.
Here is my code for that.
-(void)downloadPersonPhoto:(NSDictionary *)dict
{
NSString *imageUrlStr=[dict objectForKey:#"personPhoto"];
if ([[dict valueForKey:#"personAvatarStore"] isEqualToString:#"AMAZON"])
{
imageUrlStr = [imageUrlStr stringByReplacingOccurrencesOfString:#"original" withString:#"100x100"];
}
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *documentsDirectory = [self getDocumentDirectory];
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"personPhoto"];
if (![fileManager fileExistsAtPath:dataPath]) {
[fileManager createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:nil]; //Create folder
}
NSString *fullPath = [dataPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.png",[dict valueForKey:#"personId"]]];
if (![fileManager fileExistsAtPath:fullPath]) {
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrlStr]];
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil];
NSLog(#"Avatar Photo stored at: %#", fullPath);
}
}
Every time "Avatar photo stored at : ..." is going to print in console. But if I go to that path and check image then it has zero bytes of size and no any preview available.
webURL of image is correct I can also check from web Browser.
I don't know where is mistake in my code.
Can you please help me to solve this??
Thanks in advance.
dataWithContentsOfURL is not download image asynchronously from server. now if imagesize is big enough then it takes some time for downloading. and you are directly trying to store image to document directory. I think that create problem. you should use NSUrlSession for getting image and you should write data to local storage like documents directory from completion handler of NSUrlSession method call. you can use AFNetworking also to manage this kind od stuff.
Second thing use
[data writeToFile:path atomically:NO];
to store data to document directory and path is final path and should be unique for different data.
[NSData dataWithContentsOfURL] is not a asynchronously method
if you Debug you code you will find imagedata will be nil
you should first get imagedata then store it
you can use AFNetworing , SDWebImage framework or just use NSURLSession download it
here's one solution of my own
[[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError * error) {
//error
if (error) {
//handle error
return;
}
if (data) {
//store imagedata
[data writeToFile:filepath atomically:NO];
}
}];
good day :)

writeToFile fails with error = null

I have an app running in the XCode simulator (v6.4); this is the pertinent code:
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
// read the file back into databuffer...
NSFileHandle *readFile = [NSFileHandle fileHandleForReadingAtPath:[documentsPath stringByAppendingPathComponent: #"Backup.txt"]];
NSData *databuffer = [readFile readDataToEndOfFile];
[readFile closeFile];
// compress the file
NSData *compressedData = [databuffer gzippedData] ;
// Write to disk
NSString *outputPath = [NSString stringWithFormat:#"%#/%#%#.zip", documentsPath, venueName, strDate];
_BackupFilename = fileName; // save for upload
NSFileHandle *outputFile = [NSFileHandle fileHandleForWritingAtPath:outputPath];
NSError *error = nil;
// write the data for the backup file
BOOL success = [compressedData writeToFile: outputPath options: NSDataWritingAtomic error: &error];
if (error == nil && success == YES) {
NSLog(#"Success at: %#",outputPath);
}
else {
NSLog(#"Failed to store. Error: %#",error);
}
[outputFile closeFile];
I'm trying to create a backup of a file by taking the file, compressing it and then writing it out. I get an error Failed to store. Error: (null)); why is it failing without returning the error code?
There are quite a few things wrong here. To start. change your if statement to:
if (success) {
Never explicitly compare a BOOL value to YES or NO.
You also never use outputFile so remove that code. It may interfere with the call to writeToFile:.
And there's no point in using the file handle to read the data. Just use NSData dataWithContentsOfFile:.
And don't build paths using stringWithFormat:.
Overall, I would write your code as:
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
// read the file back into databuffer...
NSString *dataPath = [documentsPath stringByAppendingPathComponent:#"Backup.txt"]];
NSData *databuffer = [NSData dataWithContentsOfFile:dataPath];
// compress the file
NSData *compressedData = [databuffer gzippedData];
// Write to disk
NSString *outputName = [NSString stringWithFormat:#"%#%#.zip", venueName, strDate];
NSString *outputPath = [documentsPath stringByAppendingPathComponent:outputName];
// write the data for the backup file
NSError *error = nil;
BOOL success = [compressedData writeToFile:outputPath options:NSDataWritingAtomic error:&error];
if (success) {
NSLog(#"Success at: %#",outputPath);
} else {
NSLog(#"Failed to store. Error: %#",error);
}
Since success is still NO and error is still nil, then most likely this means that compressedData is nil. This probably means that databuffer is nil which means that there is no file named Backup.txt (case matters) in the Documents folder.

Get NSData from a file

I am trying get NSData of an own file.
My code is as follow, but NSData returned is always nil… (As you can see, I check if the file exists previously)
if ([[NSFileManager defaultManager] fileExistsAtPath:path]){
NSData * data = [[NSFileManager defaultManager] contentsAtPath:path];
}
Any idea? Thanks!
It's possible that path is a folder, in which case fileExistsAtPath will return YES, but no data can be read.
You can add some extra debugging by reading the data as follows:
NSError* error = nil;
NSData* data = [NSData dataWithContentsOfFile:path options:0 error:&error];
NSLog(#"Data read from %# with error: %#", path, error);
The log output will display the actual error that occurred.
Use This code it works
NSString *path = [pathURL filePath];
if([[NSFileManager defaultManager] fileExistsAtPath:path)
{
NSData *data = [[NSFileManager defaultManager] contentsAtPath:path];
}
else
{
NSLog(#"File not exits");
}

iOS can write or read from image data from disk

I'm trying to load images using the following method.
I first check if I already have the images on the disk, if I do then I will just get the image data from the disk and load it otherwise I will get the image from the server and write to disk so that the second time that I need the image I won't have to access the server.
The problem is it doesn't seem to write or read from the disk. Everytime that I want to load images for the second time it's still reads them from the server and the NSLog(#"disk"); never gets called.
I don't know what I'm doing wrong if anyone has any idea?
-(UIImage *)imageWith:(NSString *)imageName isPreview:(BOOL)preview
{
//imageName is something like "56.jpg"
NSString *mainOrPreview = #"Preview";
if (!preview) {
mainOrPreview = #"Main";
}
NSString *pathSuffix = [[#"Images" stringByAppendingPathComponent:mainOrPreview] stringByAppendingPathComponent:imageName];
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:pathSuffix];
NSData *imageData = [NSData dataWithContentsOfFile:path];
if (imageData) {
NSLog(#"disk");
}
if (!imageData && [self connected]) {
imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[serverURL stringByAppendingPathComponent: pathSuffix]]];
if (imageData) {
[imageData writeToFile:path atomically:YES];
}
NSLog(#"server");
}
return [UIImage imageWithData:imageData];
}
The problem is that the directories don't exist beyond Documents. Therefore the attempts to write the files are failing. It's always a good idea to use the file methods that have the NSError parameters so you can check the result.
You need to update only the code that actually writes the image from the server.
if (!imageData && [self connected]) {
// This needs to be done in on a background thread!
imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[serverURL stringByAppendingPathComponent: pathSuffix]]];
if (imageData) {
[[NSFileManager defaultManager] createDirectoryAtPath:[path stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:nil];
[imageData writeToFile:path atomically:YES];
}
NSLog(#"server");
}

NSFileManager Not Saving

I've been trying to use NSFileManager to cache images to the Cache directory of my sandboxed app. Unfortunately, my code doesn't seem to work.
- (BOOL)saveImageToCacheFolder
{
NSFileManager *filemgr = [NSFileManager defaultManager];
NSString *cachePath = [[[filemgr URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] lastObject] absoluteString];
NSString *fullpath = [cachePath stringByAppendingPathComponent:#"test.jpg"];
NSURL *imageURL = [FlickrFetcher urlForPhoto:self.photoData format:FlickrPhotoFormatLarge];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
BOOL success = false;
if (imageData != nil) {
success = [imageData writeToURL:[NSURL URLWithString:fullpath] atomically:true];
if (!success) NSLog(#"Did Not Managed to save the image");
}
return success;
}
Here is what I am trying to do. First, get the default NSFileManager. Second, get the relative path to the cache directory of my app. Third, append the name of my file (here i just wrote test for now). Fourth, convert my image to NSData. Fourth, write the NSData object to the specified path.
edit: added if statement for checking if the imageData is nil
Try this:
NSArray *myPathList = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachePath = [myPathList objectAtIndex:0];
NSString *fullpath = [cachePath stringByAppendingPathComponent:#"test.jpg"];
NSURL *imageURL = [FlickrFetcher urlForPhoto:self.photoData format:FlickrPhotoFormatLarge];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
if (imageData != nil) {
success = [imageData writeToURL:[NSURL fileURLWithPath:fullpath] atomically:YES];
if (!success) NSLog(#"Did Not Managed to save the image");
}

Resources