When would NSSearchPathForDirectoriesInDomains on iOS ever return 0 paths if I have the following:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(#"paths: %d", [paths count]);
if ([paths count] > 0)
{
// path exists and is the 1st item in the array
}
else
{
// path doesn't exist. Under what conditions would it not exist?
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
Add the "s"
I suspect this is just defensive coding. I can't see why that exact call would ever return 0 paths, but the NSSearchPathForDirectoriesInDomains() method might do with different params passed to it.
Also, even if the path exists, the docs say that doesn't guarantee that the actual dir exists, so ideally you'd need to do another check there too, although for NSDocumentDirectory I suspect most people, myself included, just assume it will be there - can't see why it wouldn't be..
I think it is not crash at there. just compiler stop at the wrong postion.
Related
I have an app that is supposed to save to a file and later on load it. Now, I have not had ANY problems what so ever on ios 4, so this is perplexing. This has happened on all my apps saving and loading.
Heres the code:
- (NSString *)pathOfFile{
NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsFolder = [paths objectAtIndex:0];
return [documentsFolder stringByAppendingFormat:#"awesome.plist"];
}
Later in in the app...
[array writeToFile:[self pathOfFile] atomically:YES];
And then when I attempt to load it...
if ([[NSFileManager defaultManager] fileExistsAtPath:[self pathOfFile]]) {
NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:filepath];
achi.text = [array objectAtIndex:0];
}
My app actually just skips over the if statement (Meaning that it can't find the file I think).
Please help, and if you have different methods of saving files, I would be glad to hear to hear them.
Your - (NSString *)pathOfFile method is wrong. It should be:
- (NSString *)pathOfFile
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsFolder = [paths objectAtIndex:0];
return [documentsFolder stringByAppendingPathComponent:#"awesome.plist"];
}
In your -(NSString *)pathOfFile method, don't use stringByAppendingFormat:. When working with file paths, you should instead use stringByAppendingPathComponent:, as it will ensure that the appropriate slash characters are added (or removed, if there are too many):
return [documentsFolder stringByAppendingPathComponent:#"awesome.plist"];
The comment to my question was what solved the problem, but as I can't give him the correct answer, I'll just write paste his answer here:
Did you make sure the directory is there? Sometimes that Documents directory must be created.
I have interesting thing here, I'm using xcode 4 for my project and I want to create simple .plist file to save several values which will be used for different purposes during code execution. This is the code I use to create plist:
- (NSString *)dataFilePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:#"somelist.plist];
}
last line of code which should append plist name to path do not do its job. Plist is never created. Now, strange thing, i manage to create one few days ago using same code. After that, I only move this piece of code in AppDelegate because, I call this code from different places. I discovered that isn't working when I switch to 4.3 emulator and then also try it on iphone device. When I switch to 4.2 emulator it works because there is already a plist, however when I change its name (to create new one) nothing happens - meaning, list is not created. I also try moving code back to original place, but that didn't gave desired result.
Your code should not create a plist anyway, only return a path. In order to actually save a plist at the chosen path, you could choose several approaches, for example use the following method on NSDictionary:
- (void)saveDictionary
{
NSDictionary *dictionary = [NSDictionary dictionaryWithObject:#"bla" forKey:#"test"];
NSString *path = [self datafilePath];
[dictionary writeToFile:path atomically:YES];
}
- (NSString *)dataFilePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:#"somelist.plist];
}
I am fairly new to archiving an object I have. I have a dictionary that I want to archive.. so first I got the path by doing:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
dictionaryPath = [paths objectAtIndex:0];
so is the next step to append this dictionaryPath with a .txt? Or should I create something first at this directory? What is then the data type?
I want to be able to use it for:
[NSKeyedArchiver archiveRootObject:locationDic toFile:dictionaryPath];
Where dictionaryPath is the path to store this NSDictionary
NSSearchPathForDirectoriesInDomains will give you an array of directory paths. So if you take the first one, you need to append a filename (whatever filename you'd like, with whatever extension you'd like), and then use that path as the location to write out to.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dictionaryFilePath = [documentsDirectory stringByAppendingPathComponent:#"Filename.extension"];
[NSKeyedArchiver archiveRootObject:locationDic toFile:dictionaryFilePath];
I have an iPhone app that searches a folder, collates an an array of all the audio files, and lets them be played back. The problem is that if there is a subfolder within the folder I am searching, it will just skip over it/not go into its contents.
My code is as follows:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSDirectoryEnumerator *direnum = [[NSFileManager defaultManager] enumeratorAtPath:documentsDirectory];
NSString *pname;
while (pname = [direnum nextObject])
{
[musicArray addObject:[pname stringByDeletingPathExtension]];
}
What I want to do is continue to search its subfolders, how would I go about doing that?
It does it automatically. From the documentation:
An enumeration is recursive, including the files of all subdirectories, and crosses device boundaries. An enumeration does not resolve symbolic links, or attempt to traverse symbolic links that point to directories.
I am trying to work directories. Unfortunately i get a non-writeable directory when I run NSSearchPathForDirectoriesInDomains. What I get is:
/Users/me/Library/Application Support/iPhone Simulator/User/Documents
When I run other people's examples I get:
/Users/me/Library/Application Support/iPhone Simulator/User/Applications/6958D21C-C94B-4843-9EF1-70406D0CA3A3/Documents
which is writeable.
The snippet of the code used is
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSLog(documentsDirectory);
What do I need to do allow me to get the same long directory structure?
That long path with the GUID is the documents path for your app, and is expected behavior.
Not sure what your code looks like, but getting the path to your app's document directory should be something like:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
(From Mark/LaMarche p. 331)
since it searches for the "object at index:0"
NSString *documentsDirectory = [paths objectAtIndex:0];
there could be a directory starting with a letter smaller than "d" for documents. Which becomes the "object at index:0". I know this might not be possible but It could be true as well.