Navigating folder references in iOS - ios

My project has a folder (not group) named "data" which contains many subfolders, each of which contains a set of files.
My question is, how do I grab a URL (or path) reference to the "data" folder? How about to its subfolders? I'm sure it's a fairly simple task, so forgive my ignorance, but I've never used folder refs in a project so I'm not familiar with the code. I did look over the NSFileManager ref but I'm fuzzy on how to make use of it.
Thanks in advance.

NSBundle can give you your absolute path in the system.
NSString (or NSURL) has methods for working with paths.
NSFileManager allows you to move, copy, delete (…) files.
This is how you get path to your Data directory:
NSString *dataDir = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:#"Data"];
// "/var/private/Application/.../YourApp.app/Data"
Now you just append multiple directory names to dataDir using the same method above and you should get any path you want.
In case you don't know the exact path and you want to scan the directory, you will have to use
:
NSArray *dataDirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:dataDir error:nil]
// "file1.data", "file2.data", ...
Then it's all about appending path components.

Related

How to get a shorter path to a file of my Xcode project

I have to share my OS X app, all the paths I have used for files used by project are linked to my username and the structure of my computer.
Is there a way to have paths related to my project so that once my project is shared the user may not get in troubles caused by 'file not found'.
I would move the used files of the project, into the project but then I don't know how to let this happen:
actual paths, what I use now:
/Users/???username???/XCode/projectName/fileName.txt
what I would like to use in my code:
function(path: fileName.txt)
how don't know how to make the paths this short, not caring about the users directories since the files I'm going to use are all inside my project.
I am very confused. Thank you.
There is actually an easy way to read files from your project directory:
NSError *error = nil;
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"filename" ofType:#"txt"];
NSString *dataContent = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&error];
So in dataContent you have the content of the file as an NSString instance.

pathForDirectory method for NSBundle?

If I include a folder in my bundle (a real folder, the blue ones, not the yellow groups), how can I get the path for that folder from my bundle? The method I would usually use is...
[[NSBundle mainBundle] pathForResource:fileName ofType:______];
...but what "type" is a directory? Is there a "type" to use, or is there another method for accessing the paths of directories within the bundle?
Or am I going about this all wrong, and there's some other way for including folders of accessible documents in the bundle?
Directories can have extensions too. If yours doesn't have one, just pass #"" for the type parameter, -[NSBundle pathForResource:ofType:] works for directories too, not only files. At the end, a directory is also a resource :)
As per a suggestion in the comments, it turns out you can use an empty string to refer to folders. So a folder called "myFolder" would be accessible using...
[[NSBundle mainBundle] pathForResource:#"myFolder" ofType:#""];
Hope this helps anyone else who wasn't expecting it to be so easy...
As you're adding a folder by your own, you know the name of the folder, so you can get the path like this:
NSString *myDirectoryName = #"myDirectory";
NSString *absolutePathToMyDirectory = [[NSBundle mainBundle].resourcePath stringByAppendingPathComponent:myDirectoryName];
You'll have to test if this path exist with NSFileManager.
Otherwise you can still use the method you're using, the type can be nil, so you can call it like this
NSString *absolutePathToMyDirectory = [[NSBundle mainBundle] pathForResource:myDirectoryName ofType:nil];
and then testing if the result is nil or not.
if(absolutePathToMyDirectory) {
// do stuff related to this path
}

NSbundle pathforresource not finding file

I have images.xcassets listed ounder copy bundle resources, and I did try to just state the file name by itself: MSB_big_icon , before trying to add the path within images.xcassets.
Can anybody tell me what I'm doing wrong?
NSString *path = [[NSBundle mainBundle]pathForResource:#"/Raymio_android_images/MSB_big_icon.imageset/MSB_big_icon" ofType:#"png"];
NSLog(#"path: %#", path);
MSBIcon *tilecon = [MSBIcon iconWithUIImage:[UIImage imageWithContentsOfFile:path] error:&error];
David Ansermot is right that xcassets is a much better approach and strongly preferred. If you can't use that (running on older versions of iOS for instance), still put everything in one directory and use imageNamed:. This has significant caching benefits over hand-loading the file.
An asset catalog (xcassets) is a (relatively) new, unified way of managing image resources. The images are no longer accessible as separate files on the disk. Instead, imageNamed: consults the asset catalog and fetches the correct asset.
Prior to asset catalogs (and still, for non-images), assets were stored in localized directories. All of your unlocalized assets would be put into a directory called Resources (no matter where those files might appear to be in your source tree, and no matter how those files might be arranged in your Xcode folders). Localized files would be stored in directories like English.lproj or French.lproj. When you make NSBundle calls to load MyImage, it looks at each localized directory in the order the user has configured, and if it cannot find it in any of those directories, it looks in Resources.
Now it is possible to store full directories as "a resource" by marking them as directory references in Xcode. In that case, the whole directory would be copied into Resources or the appropriate localized directory. In order to find files inside such a directory you can use the ...inDirectory: version of the NSBundle methods.
So most of the time, you want to just use imageNamed:, which is going to fetch things out of the asset catalog if available, and then search localized directories, and then look in Resources. If you need to find a non-image, or if for some reason you want the real path to the file, you can compute it like this:
NSString *path = [[NSBundle mainBundle] pathForResource:#"MSB_big_icon" ofType:#"png"];
And if that resource were in a directory tree (because it was a directory reference in Xcode), you can access it like this:
NSString *path = [[NSBundle mainBundle] pathForResource:#"MSB_big_icon"
ofType:#"png"
inDirectory:#"Raymio_android_images/MSB_big_icon.imageset"];
Here's a code exemple from one of my apps :
NSString *appKey = #"Applications__GENERIC";
NSString *path = [[NSBundle mainBundle] pathForResource:appKey ofType:#"plist"];
appData = [NSDictionary dictionaryWithContentsOfFile:path];
The "Applications__GENERIC.plist" is stored like this :
Other solutions :
Use the images.xcassets.
Then in your code to load an image, use the code :
UIImage *image = [UIImage imageNamed:#"MyImageWithoutExtension"];
Don't put any path or extension, only the image's name
Try using this:
NSString *path = [[NSBundle mainBundle] pathForResource:#"MSB_big_icon" ofType:#"png" inDirectory:#"Raymio_android_images/MSB_big_icon.imageset"];
What you can also do to debug is to print out
[[NSBundle mainBundle] bundleURL]
Then navigate to that folder and see if the folder structure corresponds to the path you use.
I just struggled with this today, hope it works out for you too.

Why isn't the temporary directory being created in the caches directory?

I'm probably missing something really obvious here, but:
NSError *error;
NSURL *cachesDirectory = [[NSFileManager defaultManager] URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask][0];
NSLog(#"Caches directory: %#", cachesDirectory);
NSURL *tmpDirectory = [[NSFileManager defaultManager] URLForDirectory:NSItemReplacementDirectory inDomain:NSUserDomainMask appropriateForURL:cachesDirectory create:YES error:&error];
NSLog(#"TMP directory: %#", tmpDirectory);
// Result:
// 2013-10-28 13:37:47.972 MyApp[220:907] Caches directory: file://localhost/var/mobile/Applications/029A4948-A67A-48E5-A35F-1BBCC744E9B0/Library/Caches/
// 2013-10-28 13:37:47.976 MyApp[220:907] TMP directory: file://localhost/var/mobile/Applications/029A4948-A67A-48E5-A35F-1BBCC744E9B0/Library/(A%20Document%20Being%20Saved%20By%20MyApp%2011)/
I was expecting my temporary directory to be created inside the caches directory. From the docs:
You can also use this method to create a new temporary directory for storing things like autosave files; to do so, specify NSItemReplacementDirectory for the directory parameter, NSUserDomainMask for the domain parameter, and a valid parent directory for the url parameter. After locating (or creating) the desired directory, this method returns the URL for that directory.
Also, the definition of url:
The name of a directory inside of which you want to create a unique temporary directory for autosaving documents or some other use. This parameter is ignored unless the directory parameter contains the value NSItemReplacementDirectory and the domain parameter contains the value NSUserDomainMask. When creating a temporary directory, the shouldCreate parameter is ignored and the directory is always created.
You can see that my temporary directory is being created inside Library. What am I doing wrong?
Looks like you are not doing anything wrong. I just tested it and found it behaving the way you described. Either the behavior does not comply with the doc or the docs are incorrect. I also happen to find the following link where people were discussing the exact same issue:
http://lists.apple.com/archives/cocoa-dev/2012/Feb/msg00197.html

How can I get full path of a directory (not a file) in developing ios

I am using cocos2d-x and I found it used pathForResource to get full path for a existing file. But I need to get the full path of a directory. If I simply pass "" to pathForResource, it will search and return the first file in that directory.
I cannot just take application directory and put it in front of relative path since I don't know if it's a relative one or already a full one.
I can trim the filename but I think that's a weird solution.
So is there any function in objective-c that works like pathForResource but don't really search for files... just return the directory name
BTW, I am using opendir functions in dirent.h. I found it won't work if I just pass a relative path, which was fine under windows.
NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"DirectoryName"];
NSLog(#"%#", sourcePath);

Resources