I would like to implement a multi language support for my app. So I created the Localizing.strings file and all that stuff and translated my interface. So far so good …
Now I want to duplicate my database in order to have a *.db-file for every single language. So I did and then I clicked via XCode on the "+" under the Localization tab. I now have a *.db-file in my en.lproj and de.lproj folder.
My problem: If I want to copy the db-files to the app's documents directory the *.db file is not available of course because it is in the *.lproj-folder. Is there any command to get the right lproj-folder?
To clarify my needs:
This doesn't work
[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"mydatabase.db"]
… this does:
[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"de.lproj/mydatabase.db"]
… but I don't want to add the "de.lproj" and "en.lproj" etc. manually. Is there any way to fix it dynamically?
just do the following:
NSString *dbpathResource =
[[NSBundle mainBundle] pathForResource:#"databaseName" ofType:#"db"];
and if you have your localized .db file in xx.lproj so the correct database will be taken.
What you want is the current language locale, the following code should return the code:
NSArray *languagesArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"AppleLanguages"];
NSString *currentLanguage = [languagesArray objectAtIndex:0];
You can then do the following
[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.lproj/mydatabase.db", currentLanguage]];
You may want to check if the path exists and is a valid file, if not maybe use some default path like the one for English (en.lproj)
Edit: There is another way you can do this using NSLocale's preferred languages because then you get a list of the preferred languages, so some updated code for the first bit would be:
NSArray *languagesArray = [NSLocale preferredLanguages];
NSString *currentLanguage = [languagesArray objectAtIndex:0];
In the end, you'd end up with something like so:
NSString *pathComponent = [NSString stringWithFormat:#"%#.lproj/mydatabase.db", currentLanguage];
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:pathComponent];
NSString *activePath = nil; // This will store the active language file
// Check if the file exists...
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
activePath = path;
} else {
activePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"en.lproj/mydatabase.db"]; // Fallback
}
Please note, the above code is untested but should suffice. You may need to modify it a little...
Something like this:
NSString * language = [[NSLocale preferredLanguages] objectAtIndex:0];
NSString * rootPath = [[NSBundle mainBundle] resourcePath];
NSString * resourcePath = [[NSBundle mainBundle] pathForResource: #"mydatabase" ofType: #"db" inDirectory: rootPath forLocalization: language];
Related
I want to put the content of my html resource file into an NSString object. Is it possible and advisable to do that? How could it be done?
Possible? - yes
Advisable? - unless it is an extremely large file, why not?
How? - There is already a method to do it for you in NSString - stringWithContentsOfFile:encoding:error:.
See the snippet below:
NSError* error = nil;
NSString *path = [[NSBundle mainBundle] pathForResource: #"foo" ofType: #"html"];
NSString *res = [NSString stringWithContentsOfFile: path encoding:NSUTF8StringEncoding error: &error];
I want create and return a dictionary using the keys and values found in a file specified by a given path. I have my file on my Desktop:ciudades.txt (a human readable file!!! no a xml, just for practice). What method of my NSString i need to use and how? Please can somebody help me filling on my code the XXXXXXX. Thanks in advance
- (NSMutableDictionary)ciudades
{
if (!ciudades) {
NSString *path = [NSString XXXXXXXXX];
ciudades = [NSMutableDictionary dictionaryWithContentsOfFile:path];
}
Define a function.
-(NSMutableDictionary*) ReadFileAsDictionaryForPath:(NSString* ) path
{
return [NSMutableDictionary dictionaryWithContentsOfFile:path];
}
Use it as below
NSString *path = [[NSBundle mainBundle] pathForResource:#"MyFile" ofType:#"txt"];
NSMutableDictionary* myDictionary = [self ReadFileAsDictionaryForPath:path];
if(!myDictionary)
{
NSLog(#"Error while reading data from file at path:%#",path);
}
First add that file to your application bundle By adding a existing file from xcode to your project. Then use this method to get the file path for example I'm getting a image's path.
NSString *path = [[NSBundle mainBundle] pathForResource:imageName ofType:#"png"];
then try the dictionaryWithContentsOfFile method and see if it works or not.
After adding it as a resource, the database file itself is in the project root.
I've only been able to open it by specifying the full path as OS X sees it, i.e., "/Users/Louis/Documents/Test Project/test.db".
But of course there is no such path on an iPhone.
I think I should define the path as "application root/test.db" but I don't know how, or if that would even work anywhere else besides my development machine.
Thanks for any ideas.
To get the path of the file you've added in XCode you would use pathForResource:ofType: with your mainBundle.
NSString *path = [[NSBundle mainBundle] pathForResource:#"yourDb" ofType:#"sqlite"];
But you can't change files in the mainBundle. So you have to copy it to another location. For example to the library of your app.
You could do it like this:
NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
NSString *targetPath = [libraryPath stringByAppendingPathComponent:#"yourDB.sqlite"];
if (![[NSFileManager defaultManager] fileExistsAtPath:targetPath]) {
// database doesn't exist in your library path... copy it from the bundle
NSString *sourcePath = [[NSBundle mainBundle] pathForResource:#"yourDb" ofType:#"sqlite"];
NSError *error = nil;
if (![[NSFileManager defaultManager] copyItemAtPath:sourcePath toPath:targetPath error:&error]) {
NSLog(#"Error: %#", error);
}
}
Don't just use the SQLite API, use this amazing wrapper called FMDB: https://github.com/ccgus/fmdb
Getting Paths to Standard Application Directories
I need in a iPhone app to access files that the app is build with(.plist etc). There's an hardcoded way to do this:
NSString *appDir = [[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
objectAtIndex:0]
stringByDeletingLastPathComponent]
stringByAppendingPathComponent:appFolder];
where appFolder is the name of folder app, like "test.app". After the appDir is known, to access files is simple.
Is there any other, not-hardcoded way to have access to files form the app?
Thanks in Advance!
NSString* pathToFile =
[[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:#"myFile.plist"];
// or, even better (handling localization):
NSString* pathToFile = [[NSBundle mainBundle] pathForResource:#"myFile"
ofType:#"plist"];
Your app folder is the "main bundle". So you can use NSBundle methods such as
NSString* path = [[NSBundle mainBundle] pathForResource:#"test" ofType:#"plist"];
I am trying to get 10 mp3 files in the resources folder and play them when a button is pressed. I have entered name of the mp3 files in a NSMutableArray and read each one after the button is pressed.
The problem is that pathForResource: is not working (returns nil). If i use the file name explicitly -like pathFoResource:#"song1.mp3" ofType:#"mp3"- but if i use pathForResource:valuem whwre valuem is an NSstring with value of song1
Hope you can help
Regards
NSString *cellValue0 = [listOfmp3 objectAtIndex:anumber];
NSString *valuem;
if ( [cellValue0 length] > 0 )
valuem = [cellValue0 substringToIndex:[cellValue0 length] - 4];
NSString *pdfPath2 = [[NSBundle mainBundle] pathForResource:valuem ofType:#"mp3"];
NSURL *url = [NSURL fileURLWithPath:pdfPath2];
Don't put the extension in the resource name, i.e.
[bundle pathForResource:#"song1" ofType:#"mp3"]; // correct
[bundle pathForResource:#"song1.mp3" ofType:#"mp3"]; // wrong — gets song1.mp3.mp3.
Check that valuem does not carry any extensions.
Sorry for my previous post, here is restatement of the problem in more clear terms:
Vladimir:
yes i log the valuem and it is giving the correct string
KennyTM:
Yes, it was a typo , in original code there is only #"song1"
the problem is that
if I use
[[NSBundle mainBundle] pathForResource:"song1" ofType:#"mp3"]; It is working
BUT If i use
[[NSBundle mainBundle] pathForResource:valuem ofType:#"mp3"];
It is NOT working
note that value is a string with #"song1"