in my iPhone app I'm using file manager to check size of file,code is working fine on simulator, but when I run the same app on iphone it is saying file size is zero even though file size is greater than zero, I am using following code:
NSArray *paths1 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory1 = [paths1 objectAtIndex:0];
documentsDirectory1 = [documentsDirectory1 stringByAppendingPathComponent:#"XML"];
NSString * szDestPath1 = [documentsDirectory1 stringByAppendingPathComponent:#"Extras"];
NSString *URL2 = [szDestPath1 stringByAppendingPathComponent:#"config.xml"];
NSLog(#"%#",URL2);
NSError *attributesError = nil;
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:URL2 error:&attributesError];
int _fileSize = [fileAttributes fileSize];
NSLog(#"_fileSize:%U",_fileSize); //0 if empty
How can I solve this, can anyone help me? thanx in advance.
Are you sure that the file exists?
Usually if a piece of code that involves files works fine on the simulator but not on the device it is because of wrong filenames. Most simulators run on a case-insensitive filesystem, but the device has a case-sensitive filesystem.
So please check again if you use the correct file path.
You could add something like this to make sure that the file exists:
if (![[NSFileManager defaultManager] fileExistsAtPath:URL2]) {
NSLog(#"File does not exist");
}
Related
Scroll down to EDIT 1. This top bit is irrelevant now.
This is my code:
NSMutableDictionary *dictionary = [self.media objectAtIndex:index];
NSLog(#"dictionary: %#", dictionary);
NSString *originalImagePath = [dictionary objectForKey:#"OriginalImage"];
NSLog(#"path: %#", originalImagePath);
UIImage *originalImage = [UIImage imageWithContentsOfFile:originalImagePath];
NSLog(#"original image: %#", originalImage);
return originalImage;
And my NSLog:
dictionary: {
IsInPhotoLibrary = 1;
MediaType = 0;
OriginalImage = "/var/mobile/Applications/5E25F369-9E05-4345-A0A2-381EDB3321B8/Documents/Images/E9904811-B463-4374-BD95-4AD472DC71A6.jpg";
}
path: /var/mobile/Applications/5E25F369-9E05-4345-A0A2-381EDB3321B8/Documents/Images/E9904811-B463-4374-BD95-4AD472DC71A6.jpg
original image: (null)
Any ideas why this might be coming out as null, despite everything appearing to be in place?
EDIT:
This is the code to write the image to file:
+(NSString *)writeImageToFile:(UIImage *)image {
NSData *fullImageData = UIImageJPEGRepresentation(image, 1.0f);
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/Images/"];
NSString *name = [NSString stringWithFormat:#"%#.jpg", [JEntry generateUuidString]];
NSString *filePath = [path stringByAppendingPathComponent:name];
[fullImageData writeToFile:filePath atomically:YES];
NSLog(#"original image 2: %#", [UIImage imageWithContentsOfFile:filePath]);
}
This NSLog also comes out as null. So the problem lies here, most likely. Any ideas?
EDIT 2:
So, back-tracing even more now, and I've realised that it's because this fails:
[fullImageData writeToFile:filePath atomically:YES];
You can return a bool on that line, telling if it was successful or not, and it's returning NO for me. Any ideas why this might be?
EDIT 3:
The image that gets passed in is NULL. Trying to figure out where that's gone wrong now.
Almost certainly your file does not exist. Modify your code as follows to log if a file exists or not:
NSString *originalImagePath = [dictionary objectForKey:#"OriginalImage"];
NSLog(#"path: %#", originalImagePath);
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:originalImagePath];
NSLog(#"file exists: %d", fileExists);
Possible Reasons:
The file at originalImagePath does not exist.
UIImage can not initialize an image from the specified file, because the data is corrupted (maybe the data is empty or incomplete)
the file can not be accessed because of iOS file permissions (i.e. when accessing files beyond the app sandbox)
Have you checked that the image file is really placed on path in dictionary? You may use the iExplorer utility for that.
Also pay attention to the file name case, so it's extension is 'jpg' not 'JPG'.
Finally you should check, whether it's a valid image file, by opening it with some image viewer.
are you sure that the jpg file "E9904811-B463-4374-BD95-4AD472DC71A6.jpg" is there in that folder?
try to open the app file installed in the iPhone/ipad simulator clicking on yourFile.app
with ctrl key and choose to open package contents the open your folder images...
to get a fast link to your documents folder:
NSArray *dirPaths;
NSString *docsDir;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
NSLog(#"doc:%#",docsDir);
your app should be in its parent folder
In the Simulator I can save an NSMutableArray to a file and read it back with the following code:
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:#"RiskValues"]){ // If file exists open into table
NSLog(#"Risk Values File Exists");
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullFileName = [NSString stringWithFormat:#"RiskValues", documentsDirectory];
gRiskValues = [[NSMutableArray alloc] initWithContentsOfFile:fullFileName];
gRiskValuesAlreadyInitialised = YES;
} else {
NSLog(#"Can't find RiskValues file, so initialising gRiskValues table");
Do something else .......
}
This doesn't work on the device. I have tried to locate the file using the following but it still doesn't work:
NSString *fullFileName = [documentsDirectory stringByAppendingPathComponent#"RiskValues"];
What am I doing wrong?
Great answers from everyone. I have resolved the file path and existence issues at a stroke. Many, many thanks.
You have to provide absolute path here:
if ([fileManager fileExistsAtPath:#"RiskValues"])
So it must look like this:
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullFileName = [documentsDirectory stringByAppendingPathComponent:#"RiskValues"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath: fullFileName]){ // If file exists open into table
NSLog(#"Risk Values File Exists");
gRiskValues = [[NSMutableArray alloc] initWithContentsOfFile:fullFileName];
gRiskValuesAlreadyInitialised = YES;
} else {
NSLog(#"Can't find RiskValues file, so initialising gRiskValues table");
Do something else .......
}
NSString *fullFileName = [NSString stringWithFormat:#"RiskValues", documentsDirectory];
this line, you're not creating your full path string right. what you should do is
NSString *fullFileName = [documentsDirectory stringByAppendingPathComponent:#"RiskValues"];
also this check
if ([fileManager fileExistsAtPath:#"RiskValues"])
Will never pass on iOS as it is not a full path to any place you are allowed to write at in your sandbox. I suppose it works on the simulator because on the mac it's looking up relatively to the HD root (or something, not sure how the mac file system works :) ), but on the iOS you're going to have to give it a path to a file/directory in your documents (maybe by appending #"RiskValues" to it or whatever)
1) [NSString stringWithFormat:#"RiskValues", documentsDirectory] is just #"RiskValues". So this name points to file in application's directory.
2) [fileManager fileExistsAtPath:#"RiskValues"] searches for file in application directory. It's available for read/write in simulator (it's in your computer file system after all) but it's read-only on device.
BTW (NSFileManager Class Reference)
Attempting to predicate behavior based
on the current state of the file
system or a particular file on the
file system is not recommended. Doing
so can cause odd behavior in the case
of file system race conditions. It's
far better to attempt an operation
(such as loading a file or creating a
directory), check for errors, and
handle any error gracefully than it is
to try to figure out ahead of time
whether the operation will succeed.
Solution:
1) Do not check file presence. Just try to make dictionary with initWithContentsOfFile:encoding:error:
2) You want it to be in documents directory so construct path like this
[documentsDirectory stringByAppendingPathComponent:#"RiskValues"];
I'm writing an app that copies some contents of the bundle into the applications Document's directory, mainly images and media. I then access this media throughout the app from the Document's directory.
This works totally fine in the Simulator, but not on the device. The assets just come up as null. I've done NSLog's and the paths to the files look correct, and I've confirmed that the files exist in the directory by dumping a file listing in the console.
Any ideas? Thank you!
EDIT
Here's the code that copies to the Document's directory
NSString *pathToPublicationDirectory = [NSString stringWithFormat:#"install/%d",[[[manifest objectAtIndex:i] valueForKey:#"publicationID"] intValue]];
NSString *manifestPath = [[NSBundle mainBundle] pathForResource:#"content" ofType:#"xml" inDirectory:pathToPublicationDirectory];
[self parsePublicationAt:manifestPath];
// Get actual bundle path to publication folder
NSString *bundlePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:pathToPublicationDirectory];
// Then build the destination path
NSString *destinationPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%d", [[[manifest objectAtIndex:i] valueForKey:#"publicationID"] intValue]]];
NSError *error = nil;
// If it already exists in the documents directory, delete it
if ([fileManager fileExistsAtPath:destinationPath]) {
[fileManager removeItemAtPath:destinationPath error:&error];
}
// Copy publication folder to documents directory
[fileManager copyItemAtPath:bundlePath toPath:destinationPath error:&error];
I am figuring out the path to the docs directory with this method:
- (NSString *)applicationDocumentsDirectory {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
}
And here's an example of how I'm building a path to an image
path = [NSString stringWithFormat:#"%#/%d/%#", [self applicationDocumentsDirectory], [[thisItem valueForKey:#"publicationID"] intValue], [thisItem valueForKey:#"coverImage"]];
It turned out to be an issue where the bundle was not being updated on the device and apparently didn't have the same set of files that the Simulator had. This blog post helped a bit: http://majicjungle.com/blog/?p=123
Basically, I cleaned the build and delete the app and installed directly to the device first instead of the simulator. Interesting stuff.
I don't see where documentsDirectory is defined.
NSString *destinationPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%d", [[[manifest objectAtIndex:i] valueForKey:#"publicationID"] intValue]]];
Perhaps the following will do the trick
NSString *destinationPath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:[NSString stringWithFormat:#"%d", [[[manifest objectAtIndex:i] valueForKey:#"publicationID"] intValue]]];
Your copy code looks fine, and you say you're getting no errors.
But I'm intrigued by "The assets just come up as null." Are you sure you're accessing the file name later with the exact same name?
Unlike the simulator, a real iPhone has a case sensitive file system.
I am developing an iPhone app with someone else. The app works fine for me, but he is running into a bug. We think this bug is related to the fact that he is getting multiple Application directories for this same app. In my ~/Library/Application Support/iPhone Simulator/User/Applications, I only have one folder at all times.
He says that he will get 3 or 4 directories when he is only working on this one app. We think this is our problem because our bug has to do with displaying images that are stored in the app's Documents folder. Does anyone know why he is ending up with multiple directories or how to stop it?
Edit:
Here is the code for writing the image to a file:
NSData *image = [NSData dataWithContentsOfURL:[NSURL URLWithString:[currentArticle articleImage]]];
NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *imagePath = [array objectAtIndex:0];
NSFileManager *NSFM = [NSFileManager defaultManager];
BOOL isDir = YES;
if(![NSFM fileExistsAtPath:imagePath isDirectory:&isDir])
if(![NSFM createDirectoryAtPath:imagePath attributes:nil])
NSLog(#"error");
imagePath = [imagePath stringByAppendingFormat:#"/images"];
if(![NSFM fileExistsAtPath:imagePath isDirectory:&isDir])
if(![NSFM createDirectoryAtPath:imagePath attributes:nil])
NSLog(#"error");
imagePath = [imagePath stringByAppendingFormat:#"/%#.jpg", [currentArticle uniqueID]];
[image writeToFile:imagePath atomically:NO];
And here is the code for getting the path when I need the image:
- (NSString *)imagePath
{
NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *imagePath = [array objectAtIndex:0];
return [imagePath stringByAppendingFormat:#"/images/%#.jpg", [self uniqueID]];
}
The app works great for me, but my partner says that the images don't show up intermittently, and he notices that he gets multiple directories in his Applications folder.
I had this problem (I was saving photos in the apps documents directory) and after every new build the directory get's renamed, so my paths were no longer valid. I cooked up these 2 functions (in my app delegate) that will give me a path for the file I want to save or load from the documents or temp directory. Even if the app directory changes, as long as you only store the file name and not the full path, and then use your helper functions to get the path when you need it later you will be ok. Here's my functions for this:
+ (NSString*)fullPathToFile:(NSString*)file {
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:file];
}
+ (NSString*)fullPathToTemporaryFile:(NSString*)file {
return [NSTemporaryDirectory() stringByAppendingPathComponent:file];
}
Works like a charm.
In my iphone application,i have used sqlite3 for storing the data.
how to get the size of the database using the iphone functionality?
if anybody has any code or any useful link or any other resolution,which would be appreciated.
Thanks,
Mishal Shah
You can use the following code (drawn from my answer to this question) to determine both your database's size and the free space on the filesystem:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *persistentStorePath = [documentsDirectory stringByAppendingPathComponent:#"database.sqlite"];
NSError *error = nil;
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:persistentStorePath error:&error];
NSLog(#"Persistent store size: %# bytes", [fileAttributes objectForKey:NSFileSize]);
NSDictionary *fileSystemAttributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath:persistentStorePath error:&error];
NSLog(#"Free space on file system: %# bytes", [fileSystemAttributes objectForKey:NSFileSystemFreeSize]);
This assumes that your database is called "database.sqlite" and is stored at the root of your application's documents directory.
Try the following, this could help you
- (NSString *)applicationDocumentsDirectory {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}
- (void) logSqlliteStoreSize
{
NSString *yourSqlLiteFileName = #"YOURDATABASE_NAME.sqlite";
NSString *yourSqlLitePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: yourSqlLiteFileName];
NSError *error;
NSDictionary *storeAttributesOfItemAtPath = [[NSFileManager defaultManager] attributesOfItemAtPath:yourSqlLitePath error:&error];
// here you should test for errors, this is a simplified version
// the next log will show much information about your sqlite file
// including the filesize
NSLog(#"storeAttributesOfItemAtPath=%#", storeAttributesOfItemAtPath);
}
You can find the database file, of the application in the iPhone simulator, in
~/Library/Application Support/iPhone Simulator/User/Applications/*a long number*/Documents/
If you have a jail broken phone you can SSH into it and find the applications folder where it will also be in a /Applications/*<a long number>*/Documents/ folder.