Following is my code I need check whether file present in document directory ,But following API does not return true at any condition but file is get created in document directory. Please check any thing wrong I am doing. I have searched on this other says this API "fileExistsAtPath" should work but it is not working in my case. Please do help me.
NSString *recordFile=[NSString stringWithFormat:#"MyFile.acc",data.uid];
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentDr = [documentPaths objectAtIndex:0]; // WHY 0 ?
NSString *uniquePath = [documentDr stringByAppendingPathComponent:recordFile];
if([[NSFileManager defaultManager] fileExistsAtPath: uniquePath])
{
NSLog(#"File found")
}
else {
NSLog(#"No File to play");
}
Thanks,
Sony
Probably your path is incorrect. What should be the name of the files you are trying to find? If you have #"MyFile1.acc", #"MyFile2.acc" etc (where 1, 2 is the data.uid value) then try to use this:
NSString *recordFile=[NSString stringWithFormat:#"MyFile%i.acc",data.uid];
Try to append a "/" after documentDr when define uniquePath, or
NSString *recordFile = [NSString stringWithFormat:#"MyFile%#", data.uid];
...
if([NSBundle pathForResource:recordFile ofType:#"acc" inDirectory:documentDr])
the first wrong thing i note is the first instruction.
Why do you pass 'data.uid' as an argument to the format string ? Assuming 'data.uid' is some kind of integer, there should be at least '%d' in...
I had a look to Apple Documentation, in particular, that statement which says
The directory returned by this method may not exist.
You could try getting the current directory path using NSFileManager methods, and then testing for file existence (or create a directory at a place you can easily retrieve later).
What about the others paths ? You wrote 'WHY 0 ?', i'm asking the same question as you.Try looping over the array elements, testing each time for file existence.
The code should work. Your file most likely doesn't exist. Did you use capitalisation in your file name right when saving it?
Also right now, I still don't know what the file name is since, as already said, the first line in your initial post doesn't give the format string right.
Before checking try for existance try:
[[NSString stringWithString:#"test"] writeToFile: uniquePath atomically:YES];
That should create a file at the path and you see, that fileExists works.
I tried many things but ended up that I had to delete the app, clean all targets, and then rebuild again. It's weird that somehow my new resources doesn't get copied to the app. It usually happens to files that when I added them I selected "Create folder references for any added folders".
Related
ok i've been going round in circles for 1.5 hours, now i need some help. below is the code i'm using to create a list of files in my Documents Directory, all works fine unless the directory is empty.
fileList = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:&error];
what can i do directly before this to check if the directory has contents?
ive tried
if ([[[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:&error] objectAtIndex:0]){
fileList = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:&error];
}
but that also crashes the app
/////////////////////NOOB MISTAKE ALERT////////////////////
ok my problem was my next line of code
NSLog(#"fileList: %#",[fileList objectAtIndex:fileList.count-1]);
that's what was crashing my app, my own fault i admit lol. [fileList objectAtIndex:fileList.count-1] is out of bounds, i'm confused as to why the debugger didn't tell me that much.
Thanks for your help guys
The method should not crash even if there is no files. According to the doc,
... Returns an empty array if the directory exists but has no contents.
I would check
If the documentsDirectory variable is properly set as a NSString instance
If the documentsDirectory variable is not deallocated already
NSLogging documentsDirectory just before the call would be the right first step.
The method you are using returns an empty array if the directory has no content.
Before attempting to access anything from the array, check its count to make sure that something is present:
if ([fileList count] == 0)
// You have an empty directory
I've read up Apple's documentation of plist: http://developer.apple.com/library/mac/documentation/cocoa/Conceptual/PropertyLists/PropertyLists.pdf
However I've got a few questions about it:
1) When we use the [dict writeToFile:plistPath atomically:YES] API, does it overwrite the current content of the plist? It doesn't say anything in the documentation.
2) Are we supposed to actually make the plist manually in Xcode by new file->resources->property list? Or are we supposed to have this:
NSFileManager *fileManager = [NSFileManager defaultManager];
NSData *xmlData = [NSPropertyListSerialization //... a very long line here
if([fileManager fileExistsAtPath:plistPath]) {
[xmlData writeToFile:plistPath atomically:YES];
}
else {
[fileManager createFileAtPath:plistPath contents:xmlData attributes:nil];
}
3) How do we check if we've actually written data to property list? I tried products -> myapp.app -> "reveal in finder" -> right click -> show package contents, and there are some plists there, but I can't see the data being written! Is that mean I'm failed writing data to plist?
EDIT: Thanks everyone! Sorry for being silly today!
From the description of writeToFile:atomically:
If flag is YES, the dictionary is written to an auxiliary file, and then the auxiliary file is renamed to path. If flag is NO, the dictionary is written directly to path. The YES option guarantees that path, if it exists at all, won’t be corrupted even if the system should crash during writing.
Since it is written to an auxiliary file and then renamed to the specified path, I would assume that it overwrites the current content of the file.
You should use the NSFileManager to find the application's documents directory and write the plist there. You should not use a resource, as you are going to write to it during the course of executing the app.
Add some logging (e.g., NSLog(#"plist path: %#", plistPath);) to show where the plist is getting written.
1) It will overwrite the current content. If you want to append some more data to your current plist file, first read it to a dictionary and add the data and write it back.
2) You can add it manually or create it programmatically.
3) Just log the contents of the plist file after writing.
Here is the code that i save audio file in string. After that i add in array. But still not work here..
Is there any options here to store audio file in array after that storing documentdictionary.
fileArray = [[NSMutableArray alloc] initWithContentsOfURL:recordedTmpFile];
fileArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [fileArray objectAtIndex:0];
NSMutableDictionary *recordDictionary = [NSDictionary dictionaryWithContentsOfFile:documentsDirectory];
NSFileManager *fileManager = [NSFileManager defaultManager];
for(int i= 0; i<fileArray.count;i++)
{
NSString *recorded = [fileArray objectAtIndex:i];
NSString *filePath = [recordDictionary stringByAppendingPathComponent:recorded];
newArray = [fileManager fileExistsAtPath:filePath];
}
If any code missing by me than suggest me some specific idea about.
Plz give some response..
I don't want to sound like a dick, but just throwing code at an editor isn't going to work. I don't often write answers like this, but sometimes it needs to be done;
Here's a line-by-line breakdown of what you have written and maybe that will give you an idea of what this snippet is doing:
You create an NSMutableArray called fileArray initialised with the contents of a file. I don't know whether this file is in the correct format or not. documentation
You then overwrite this array with an array of search paths. Incidentally, you've now leaked the memory of the initial array.
You get a string to the Documents directory.
You try to create an NSDictionary from a string rather than in the specific format required by the message. As this is an invalid file recordDictionary is nil documentation
You create a reference to the FileManager
You start a for loop to iterate the contents of fileArray
You get each item in fileArray but this is only a list of directories, not files (see point 2)
You try and create a filePath by appending what you think of as a file to a directory except you are appending a directory (see point 7) to nil (see point 4)
You declare an undimensioned variable and try to assign a BOOL to it documentation
So you've written a lot of code that doesn't do anything. It doesn't work because I doubt you have tried to compile it.
Looking at your question history it seems you ask the same question over and over again. You would be better off starting with a basic introduction to Cocoa and working through that until you understand why your code snippet is so wrong.
All you need to do is to get the location of the file you want to save, and move it to the correct place. Somebody else may just write your code for you, but I won't - I'm not that desperate for the points and I'll just be doing you a disservice. Go back to basics, ask specific questions with some idea of what you've tried and you'll get a far better response
Hi all i am trying to save image in the bundle which i have currently on my view,but the problem is that i can only save one image,if i want to save the another image it replaces the old.I am not getting how to save the multiple images in the bundle then.
Here is my code.
- (void)writeImageToDocuments:(UIImage*)image
{
NSData *png = UIImagePNGRepresentation(image);
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSError *error = nil;
[png writeToFile:[documentsDirectory stringByAppendingPathComponent:#"image.png"] options:NSAtomicWrite error:&error];
}
Please Help me out, how to save multiple images, files e.t.c in bundle
Thanks in advance
You're not saving into a bundle, you're saving into your app's documents directory. There's no bundle aspect to it.
You're using the filename #"image.png" for every file that you save. Hence each new write overwrites the old one. In fact, you write each file twice. To save multiple files, use different file names.
It's also bad form to pass a numeric constant as the 'options:' parameter of NSData writeToFile:options:error: (or indeed, any similar case). The value '3' includes an undefined flag, so you should expect undefined behaviour and Apple can legitimately decline to approve your application. Probably you want to keep the NSAtomicWrite line and kill the one after it.
If you're just looking to find the first unused image.png filename, the simplest solution would be something like:
int imageNumber = 0;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *pathToFile;
do
{
// increment the image we're considering
imageNumber++;
// get the new path to the file
pathToFile = [documentsDirectory stringByAppendingPathComponent:
[NSString stringWithFormat:
#"image%d.png", imageNumber]];
}
while([fileManager fileExistsAtPath:pathToFile]);
/* so, we loop for as long as we keep coming up with names that already exist */
[png writeToFile:pathToFile options:NSAtomicWrite error:&error];
There's one potential downside to that; all the filenames you try are in the autorelease pool. So they'll remain in memory at least until this particular method exits. If you end up trying thousands of them, that could become a problem — but it's not directly relevant to the answer.
Assuming you always add new files but never remove files then this problem is something you could better solve with a binary search.
File names searched will be image1.png, image2.png, etc.
I need to copy a few sample files from my app's resource folder and place them in my app's document folder. I came up with the attached code, it compiles fine but it doesn't work. All the directories I refer to do exist. I'm not quite sure what I am doing wrong, could someone point me in the right direction please?
NSFileManager*manager = [NSFileManager defaultManager];
NSString*dirToCopyTo = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
NSString*path = [[NSBundle mainBundle] resourcePath];
NSString*dirToCopyFrom = [path stringByAppendingPathComponent:#"Samples"];
NSError*error;
NSArray*files = [manager contentsOfDirectoryAtPath:dirToCopyFrom error:nil];
for (NSString *file in files)
{
[manager copyItemAtPath:[dirToCopyFrom stringByAppendingPathComponent:file] toPath:dirToCopyTo error:&error];
if (error)
{
NSLog(#"%#",[error localizedDescription]);
}
}
EDIT: I just edited the code the way it should be. Now however there's another problem:
2010-05-15 13:31:31.787 WriteIt
Mobile[4587:207] DAMutableDictionary.h
2010-05-15 13:31:31.795 WriteIt
Mobile[4587:207] FileManager
Error:Operation could not be
completed. File exists
EDIT : I have fixed the issue by telling NSFileManager the names of the copied files's destinations.
[manager copyItemAtPath:[dirToCopyFrom stringByAppendingPathComponent:file] toPath:[dirToCopyTo stringByAppendingPathComponent:file] error:&error];
I think the problem is in this line:
NSArray*files = [manager contentsOfDirectoryAtPath:dirToCopyTo error:nil];
You are listing files in a destination directory instead of the source. Change it to something like:
NSArray*files = [manager contentsOfDirectoryAtPath:dirToCopyFrom error:nil];
And you should be fine.
I think the problem is that yo are reading the files to copy from dirToCopyTo and I think you meant dirToCopyFrom
Also to get the documents directory you should be using NSDocumentDirectory with - (NSArray *)URLsForDirectory:(NSSearchPathDirectory)directory inDomains:(NSSearchPathDomainMask)domainMask
Please note that lengthy operation on startup must be avoided:
Not a good User Experience (delay and croppy behavior)
Watchdog in iOS can kill your app as if it were stuck.
So perform copy in a secondary thread (or operation... or whatever uses a different execution path).
Another problem will arise if You need data to populate your UI: in that case:
Disable UI elements
Start an async / threaded operation
In the completion call back of copying (via a notification, a protocol.. or other means)
notify to the UI interface it can start fetching data.
For example we copy a ZIP file and decompress it, but it takes some time so we had to put it in a timer procedure that will trigger UI when done.
If You need an example, ket me know.
PS:
Copying using ZIP file is MORE efficient as:
Only call to file system
Far less bytes to copy
The bad news: you must use a routine do decompress zip file, but you can find them on the web.
Decompressing Zip files should be more efficient as these calls are written in straight C, and not in Cocoa with all the overhead.
[manager copyItemAtPath:[dirToCopyFrom stringByAppendingPathComponent:file] toPath:dirToCopyTo error:&error];
The destination path is the path you want the copy to have, including its filename. You cannot pass the path to a directory expecting NSFileManager to fill in the name of the source file; it will not do this.
The documentation says that the destination path must not describe anything that exists:
… dstPath must not exist prior to the operation.
In your case, it's the path to the destination directory, so it does exist, which is why the copy fails.
You need to make it a path to the destination file by appending the desired filename to it. Then it will not exist (if not previously copied), so the copy will succeed.