Are these two ways of getting the filepath equivalent? - iphone

NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return [[pathArray objectAtIndex:0] stringByAppendingPathComponent:#"data.plist"];
and
return [[NSBundle mainBundle] pathForResource:#"data" ofType:#"plist"];
the file is stored in my documents folder.

No, they are not. The former returns a path to the file named data.plist in the app's Documents directory, the latter returns a path to the file named data.plist in the app's bundle, where all the app's resources, executable, etc are located.

From the documentation for NSSearchPathForDirectoriesInDomains
Creates a list of path strings for the
specified directories in the specified
domains. The list is in the order in
which you should search the
directories. If expandTilde is YES,
tildes are expanded as described in
stringByExpandingTildeInPath.
From the documentation for the NSBundle method pathForResource:ofType:
The method first looks for a matching
resource file in the non-localized
resource directory of the specified
bundle. (In Mac OS X, this directory
is typically called Resources but in
iOS, it is the main bundle directory.)
If a matching resource file is not
found, it then looks in the top level
of any available language-specific
“.lproj” directories. (The search
order for the language-specific
directories corresponds to the user’s
preferences.) It does not recurse
through other subdirectories at any of
these locations.
Therefore the former looks for files in a directory, and the latter looks in the bundle. These may not coincide.

Related

How to get the file name in iPhone sdk?

I stored a pdf file using NSData in my application memory. Now i want that file name each time to add those names into an array. How can i get the pdf file's name from my application memory to use in my app.
You can't since you only stored the file as a data object and not it's file name.
You could try to read the PDF meta data to check if there's a file name.
The answer here should help:
Getting a list of files in the Resources folder - iOS
It will list all the files in the Documents dir.
I suppose by "Application Memory" you mean one of the App's directories like Documents or Library.
You can just use NSFileManager to access the directory and get a list of all files, like if you stored it in your app's library folder:
NSArray* directoryPaths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUSerDomainMask, YES];
NSString* path = [directoryPaths objectAtIndex:0];
NSArray* files = [NSFileManager defaultManager] contentsOfDirectoryAtPath:path];
On top of that you can use a filter predicate to only get files with a .pdf ending.

finding the path beyond the bundle

i want to find the path of the file which is not in my bundle..
NSString *path = [[NSBundle allBundle] pathForResource:nm ofType:#"jpg" inDirectory:nil];
but it gives warning that NSArray may not respond..
is there any way to find the path of file any other folder.
allBundle returns an NSArray of all the bundles. You mean to use the method mainBundle.
If you can't find your resource then this is most likely a problem with the name of the resource you're looking for (have you checked the value of nm is correct?) Also check in your Target under the "Copy resources" section that your .jpg file is listed there. If it's not then you should drag it there to ensure that the file is copied into your bundle when you build it.
If you really want to search through all the available bundles for your resource, then you can loop through the array of bundles that allBundle returns as follows:
NSString* pathForResource = nil;
for (NSBundle currentBundle in [NSBundle allBundle])
{
pathForResource = [currentBundle pathForResource:nm ofType:#"jpg"];
if (pathForResource)
{
break; // Found resource, no longer need to search through bundles.
}
}
Note: You also don't need to use the "inDirectory:" part of the method (see the docs).

How do I add files to the resources folder in XCode?

I want to add a sqlite database to XCode 4 (applies to XCode 3 too). Tutorials state adding the .db file to the resources folder, and I suppose this gets copied to ~/Library/Application Support/iPhone Simulator/4.2/Applications/{some-id}/Documents/ during build where you can find the file with NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
etc.
However, XCode 4 doesn't have a visible resources folder.
I've tried adding a file with the Add File... command, and then it appears in Targets > AppName > Copy Bundle Resources, but always an empty .db file appears in the above documents folder (which I then manually replace - obviously not the correct approach!)
(due to the nature of the data I'm sticking with sqlite over CoreData)
you have to start adding your db in your project-xcode, so it will be added in your bundle folder, where you can find it via code:
[NSBundle mainBundle]
It's the only folder where you can add files via xcode when you "build" your app (eventually with subfolders, but not "system" folders as "documents") now you just need to keep in mind that the main bundle folder is just "read only", so you cant use your db there with write privileges.
So the normal way is:
1) when you wanna use your db, check via code if it exists in the app:documents folder.
Of course the first time it doesn't, so
2) copy it from the main bundle
- (BOOL)transferDb {
NSError **error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"yourData.db"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path])
{
NSString *bundle = [[ NSBundle mainBundle] pathForResource:#"preferenze" ofType:#"plist"];
[fileManager copyItemAtPath:bundle toPath:path error:error];
return YES;
}
return NO;
}
3) use it (r/w) in the documents folder
ps:
and (of course) keep in mind that when you use/edit/write the db in iPhone/simulator, maybe adding records, the one in the main bundle and of course the one in your mac/project won't be updated, no records will be added to it, so if for any reason you delete your app on iPhone/simulator (or "clean all targets" by the xCode "build" menu) the check/copy method will copy the "virgin" db in the documents folder again, so you will loose all your changes...
Be careful with the amount of data you are putting into the Documents folder, this is meant for user data and since this data will be backed up using iCloud Apple have limited the amount of data an app can store and use in the Documents folder.
My app was rejected for using a 6MB SQLite database in this way. Instead copy it to the caches directory: NSCachesDirectory.
Or prevent the file from being backed up: https://developer.apple.com/library/ios/#qa/qa1719/_index.html

Is possible to read plist from application bundle and documents folder at the same time?

Is it possible?to read from my local bundle and at the same time also read from documents folder into UItableview?
thanks thanks
yes.simultaneously
No — as in the iPhone isn't multicore, you can't have "simultaneous" :p
Yes — as in you can open multiple files in the same period of time. There's no conflicts as long as the files are different (if the files are the same then it depends on how others are using and locking the file etc.)
on viewDidLoad or some similar event when you would be populating your table data, you would simply just aggregate the two files together... that is you are are likely populating an array or dictionary with the contents of the file in question... so use the mutable version of array/dictionary, initialize it empty, then read in the first file from whatever location you choose, populating into your mutable array/dictionary, then do the the same for the next file. after you are done, reloadData as you normally would as if you had read form one file.
As far as simultaneous goes, technically no. However, one could have two different active threads each one reading required files and parsing the data.
Regarding the files you want to access...
Here is a quick and dirty method I use in one project (which I just happen to be working on at the moment):
NSFileManager* fileManager = [NSFileManager defaultManager];
NSError* error;
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
self.documentsDirectory = [paths objectAtIndex:0];
self.blahDBPath = [self.documentsDirectory stringByAppendingPathComponent: #"blah.db"];
NSLog(#"Mainbundle Resourcepath: %#", [[NSBundle mainBundle] resourcePath]);
NSString* defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"blah.db"];
NSLog(#"Default DB Path: %#", defaultDBPath);
success = [fileManager copyItemAtPath:defaultDBPath toPath:self.blahDBPath error:&error];
if (!success) {
NSAssert1(0, #"blah blah blah '%#'.", [error localizedDescription]);
}
It is ugly but effective. I'll rewrite it when I refactor the application.
The point here is that I ask the operating system for the path to certain directories. Then I add file names or subdirectories as required. This allows the operating system to manage paths (like in the simulator where each successive build gets a new unique id as part of its path) and I just worry about the final directories and file names in the application.
One I have the paths, I copy the required file from the bundle directory and put them somewhere, the Documents directory in this case. Then I can do whatever I need to with them.
If I just wanted to access them as they are in the bundle directory, then I I just refer to them by using [[NSBundle mainBundle] resourcePath].
I think something along the lines of the above snippet is what you are looking for.
-isdi-

When installing an App to the iPhone, is there a way to install files to the App's Documents folder?

When installing an App to the iPhone, is there a way to install files to the App's Documents folder?
To say it another way: When the user downloads an App and installs it on their iPhone, I want to automatically install some files to the App's Documents directory.
For example: I have a file foo.txt that I create at development time for my App SeeFooRun. When the App installs, I want foo.txt to appear in the Documents directory so that when I run the App for the first time I access foo.txt from the Documents directory instead of from the App Bundle.
Thanks!
In the example I said "runs for the first time" when I meant to say "installs" and I changed the rest of the sentence to fit. Sorry for the mix up!
I would do it using this method:
Create a property in the root plist set the initial value to "NO" When the app is run, check this value.
If the value is "NO", create the document in the document directory, change the value to "YES" and save the value.
The next time the app is run, the value will be "YES" and the file won't be rebuilt.
Hope this helps.....
You can do something like this:
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *pathLocal = [documentsDir stringByAppendingPathComponent:#"foo.txt"];
NSString *pathBundle = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"foo.txt"];
NSError *error;
BOOL success = [fileManager copyItemAtPath:pathBundle toPath:pathLocal error:&error];
One slight variation on the copying into Documents answers - put everything you copy into a folder in Documents that you create, then at startup you simply check for the presence of that one folder and do all the copying then.
Checking per file is more robust though, especially if you add a new file in an update then the copy logic will copy in the single new file without overwriting the older ones.