Error in internationalization iPhone - iphone

I am using iOS 5, XCODE 4.2
In my loginViewController:
-(IBAction)loginButton:(id)sender{
textClass=[[MainScreenController alloc ] init];
NSLog(#"ShowText called");
textClass.selectedLanguage=currentLanguage;
[self.view addSubview:textClass.view] ;
NSLog(#"txtclaslan=%d",textClass.selectedLanguage);
}
In my MainViewController viewDidLoad: method:
mainScreenTitle.text=[self languageSelectedStringForKey:#"screenTitle"];
And in languageSelectedStringForKey:
-(NSString*) languageSelectedStringForKey:(NSString*) key{
NSString *path;
if(selectedLanguage==ENGLSIH_LANGUAGE)
path = [[NSBundle mainBundle] pathForResource:#"en" ofType:#"lproj"];
else if(selectedLanguage==TURKISH_LANGUAGE)
path = [[NSBundle mainBundle] pathForResource:#"tr" ofType:#"lproj"];
else
path = [[NSBundle mainBundle] pathForResource:#"en" ofType:#"lproj"];
NSBundle* languageBundle = [NSBundle bundleWithPath:path];
NSString* str = [languageBundle localizedStringForKey:key value:#"" table:nil];
return str;
}
Here in this method languageSelectedStringForKey when I load the MainViewController I my application crashes. I don't get any error just this line is highlighted
NSBundle* languageBundle = [NSBundle bundleWithPath:path]; < Thread 1
What can be the issue with this?
Thanks in advance

As suggested:
Looking at your code it seems that if the language is not English and not Turkish then path is not set.
You may also want to follow this advice from the [NSBundle localizedStringForKey:value:table:] method description:
"Using the user default NSShowNonLocalizedStrings, you can alter the behavior of localizedStringForKey:value:table: to log a message when the method can’t find a localized string. If you set this default to YES (in the global domain or in the application’s domain), then when the method can’t find a localized string in the table, it logs a message to the console and capitalizes key before returning it."

Related

Get name of Xcode Project in actual code

So you know the part of the project that is "MyNameGoesHere.app" or "MyNameGoesHere.xcodeproj" - is there a way to get the MyNameGoesHere part via objective-c code?
I can get all kind of device info from UIDevice messages but I can't figure out how to get project/app name.
CFBundleDisplayName doesn't work anymore. Use:
NSString *bundleName = [[NSBundle mainBundle]
objectForInfoDictionaryKey:#"CFBundleName"];
You're probably looking at the bundle's InfoDictionary. You can get the app's name via the following code:
NSDictionary *info = [[NSBundle mainBundle] infoDictionary];
NSString *bundleName = [NSString stringWithFormat:#"%#", [info objectForKey:#"CFBundleDisplayName"]];

Multilanguage Application in Iphone

How do I change my applications default language within my application? I am trying to change my applications language to Arabic, and I'm not sure how to accomplish this.
There is a way:
First make a different folder named as ar.lproj and put localizable.String
May following sample code help you. You can call this function in viewWillAppear with the key for which you need to get value.
-(NSString*) languageSelectedStringForKey:(NSString*) key
{
NSString *path;
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
if([[userDefault valueForKey:#"language_Selected"] intValue] == 0)
path = [[NSBundle mainBundle] pathForResource:#"en" ofType:#"lproj"];
else if([[userDefault valueForKey:#"language_Selected"] intValue] == 1)
path = [[NSBundle mainBundle] pathForResource:#"ar" ofType:#"lproj"];
NSBundle* languageBundle = [NSBundle bundleWithPath:path];
NSString* str=[[languageBundle localizedStringForKey:key value:#"" table:nil] retain];
return str;
}
Hope you will understand the concept.

Multiple SQLite Databases for Multiple Languages?

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];

How to create a NSMutableDictionary using dictionaryWithContentsOfFile: method

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.

iPhone sdk 4.1: Application CRASHES when i try to access a .plist file third time

I have a menu scene, help scene, settings scene and game scene. When i enter into game scene, it loads some data string from a .plist file into a NSMutableArray. I am doing this reading and loading procedure as follows-
+ (void) addObjectsToArray:(NSMutableArray*) mutableArray fromFile:(NSString*) filePath
{
NSString *bundle = [[NSBundle mainBundle] bundlePath];
NSString *path = [bundle stringByAppendingPathComponent:filePath];
[mutableArray addObjectsFromArray: [NSMutableArray arrayWithContentsOfFile:path]];
[bundle release];
}
I can get into the game scene and can back to menu scene from there.
But when I try to get into the game scene forth time(menu scene to game then back to menu scene and go to game scene again and do), the app just crashes.
I have found the crash point(using NSLog)-
+ (void) addObjectsToArray:(NSMutableArray*) mutableArray fromFile:(NSString*) filePath
{
NSString *bundle = [[NSBundle mainBundle] bundlePath];
**NSLog(#"always reach here");**
NSString *path = [bundle stringByAppendingPathComponent:filePath];**// CRASH POINT**
**NSLog(#"Forth time, doesnt reach here");**
[mutableArray addObjectsFromArray: [NSMutableArray arrayWithContentsOfFile:path]];
[bundle release];
}
But why crashing i dont understand and found no solution yet.
I think you should not release bundle
"[[NSBundle mainBundle] bundlePath]" should return an autorelease object.
Then as you release it, its relain count should reached 0 at the 4rd time and crash the app
You must not release an object if you don't own it.
You are responsible for (auto)releasing an object only if you increased its retain-count. Either by calling retain explicitly or by calling methods with alloc, copy or new in the name.
Please read the Memory Managment Guide again
Btw, if you run the analyzer (you can find it in the Build menu) it will point you at the exact line where you did something wrong.
Any stack trace?
Anyway try to wrap it into a try-catch. I always do this when handling files whether they are from bundle or downloaded.
#try {
NSString *bundle = [[NSBundle mainBundle] bundlePath];
NSString *path = [bundle stringByAppendingPathComponent:filePath];
[mutableArray addObjectsFromArray: [NSMutableArray arrayWithContentsOfFile:path]];
[bundle release];
}
#catch (NSException * e) {
NSLog (#"exception: %#", exception);
}
My guess is that filePath is nil.
Maybe try to NSLog(#"filePath: %#", filePath); in the beginning of (void) addObjectsToArray:(NSMutableArray*) mutableArray fromFile:(NSString*) filePath
Cheers mate.