I'm creating a Mac app and I want to localize my Labels. I thought a .strings file would be a better choice. But I have trouble reading .strings file in Objective-C. I'm looking for a simpler method.
This is my .string file content:
"LABEL_001" = "Start MyApp";
"LABEL_002" = "Stop MyApp";
"LABEL_003" = "My AppFolder";
...
I have already looked at http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/LoadingResources/Strings/Strings.html.
This is my code:
NSBundle *bundle = [NSBundle mainBundle];
NSString *strFilePath = [[NSBundle mainBundle] pathForResource:#"Labels" ofType:#"strings"];
NSString *tt =NSLocalizedStringFromTableInBundle(#"LABEL_001",strFilePath,bundle, nil);
NSLog(#"STRING ::: %#",tt);
But the string tt gives "LABEL_001", I want "Start MyApp"
What am I doing wrong?
One. You have to name your file Localizable.strings in the <LANGUAGENAME>.lproj directory in the app bundle.
Two. Use the NSLocalizedString macro:
NSString *loc = NSLocalizedString(#"LABEL_001", nil);
Three. If nothing works, you can initialize an NSDictionary using a strings file, as a strings file is a special type of plist:
NSString *fname = [[NSBundle mainBundle] pathForResource:#"whatever" ofType:#"strings"];
NSDictionary *d = [NSDictionary dictionaryWithContentsOfFile:fname];
NSString *loc = [d objectForKey:#"LABEL_001"];
NSString *path = [[NSBundle mainBundle] pathForResource:#"Labels" ofType:#"strings"];
NSData *plistData = [NSData dataWithContentsOfFile:path];
NSString *error; NSPropertyListFormat format;
NSDictionary *dictionary = [NSPropertyListSerialization propertyListFromData:plistData
mutabilityOption:NSPropertyListImmutable
format:&format
errorDescription:&error];
NSString *stringname = [dictionary objectForKey:#"LABEL_001"];
I think it will be helpful to you.
Here the your code
NSBundle *bundle = [NSBundle mainBundle];
NSString *strFilePath = [[NSBundle mainBundle] pathForResource:#"Labels" ofType:#"strings"];
NSString *tt =NSLocalizedStringFromTableInBundle(#"LABEL_001",strFilePath,bundle, nil);
NSLog(#"STRING ::: %#",tt);
The problem here is the 2nd Param "strFilePath", change it to #"Labels" so the above code would become,
NSString *tt =NSLocalizedStringFromTableInBundle(#"LABEL_001",#"Labels",bundle, nil);
For reference, the following line copied from Apple Docs regarding table name,
"When specifying a value for this parameter, include the filename without the .strings extension."
hope this helps.
Simple Code
Just create a method as follows
- (void)localisationStrings
{
NSString* path = [[NSBundle mainBundle] pathForResource:#"localisation" ofType:#"strings"];
NSDictionary *localisationDict = [NSDictionary dictionaryWithContentsOfFile:path];
NSLog(#"\n %#",[localisationDict objectForKey:#"hello"]);
}
Related
I need to access to the Settings.bundle and get the descriptions and titles with the localized string.
Use NSLocalizedStringFromTableInBundle function. Create an instance of NSBundle with URL of your bundle and use it as bundle argument. Use “Root” as the table name for tbl argument.
For example:
NSBundle *bundle = [[NSBundle alloc] initWithURL: ...];
NSString *string = NSLocalizedStringFromTableInBundle("SOME_KEY", "Root", bundle, "Comment");
In the end I did it this way:
NSString *resourcePath = [[NSBundle mainBundle] pathForResource:#"Settings" ofType:#"bundle"];
NSBundle *settingsBundle = [NSBundle bundleWithPath:resourcePath];
NSURL *url = [settingsBundle URLForResource:#"Root" withExtension:#"plist"];
NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfURL:url];
NSArray *preferences = dictionary[#"PreferenceSpecifiers"];
for (NSDictionary *dic in preferences){
NSString *localizedTitle = NSLocalizedStringWithDefaultValue(dic[#"Title"], #"Root", settingsBundle, dic[#"Title"], #"");
}
how can I edit or change a value string from:
in this plist I need change or Set "NO" in Enabled Value from Item 2, I see a lot examples, but not working, or are deprecated, or don't use ARC, any idea or example code? please help guys
EDIT#1: I try this (not work)
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
path = [path stringByAppendingPathComponent:#"List.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:path]) {
NSString *sourcePath = [[NSBundle mainBundle] pathForResource:CONTENT_DEFAULT ofType:PLIST];
[fileManager copyItemAtPath:sourcePath toPath:path error:nil];
}
NSArray* newContent = [[NSArray alloc]initWithContentsOfFile:path];
NSDictionary *Dict = [[NSDictionary alloc]initWithDictionary:[newContent objectAtIndex:2]];
[Dict setValue:#"NO" forKey:#"Enabled"];
[Dict writeToFile:path atomically:YES];
NOTE: not work, it crashes send me:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSDictionaryI 0x15de7ff0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key Enabled.', or Im wrong in something?
EDIT #2 new Try
NSString *path = [[NSBundle mainBundle] pathForResource:#"List" ofType:#"plist"];
NSString *savingPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSArray* newContent = [[NSArray alloc]initWithContentsOfFile:path];
NSMutableDictionary *Dict = [[NSMutableDictionary alloc]initWithDictionary:[newContent objectAtIndex:2]];
[Dict setValue:#"NO" forKey:#"Enabled"];
savingPath = [savingPath stringByAppendingPathComponent:#"Modified.plist"];
[Dict writeToFile:savingPath atomically:YES];
NSLog(#"newContent:%#",newContent);
NSArray *newnew = [[NSArray alloc]initWithContentsOfFile:savingPath];
NSLog(#"newnew:%#",newnew);
NOTE: now print me a crash:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray objectAtIndex:]: index (3) beyond bounds (2)'
All you have to do is to use NSMutableDictionary instead of a regular dictionary to modify stuff. You have to always check that the object you are editing is there.
To get the right path for the plist you created in Xcode you need to use:
NSString *path = [[NSBundle mainBundle] pathForResource:#"List" ofType:#"plist"];
You might actually want to save that file into the app's document directory. So you would use the following path for saving the content:
NSString *savingPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
savingPath = [savingPath stringByAppendingPathComponent:#"Modified.plist"];
[Dict writeToFile:savingPath atomically:YES];
Well, in your case the solution would be the following (when you have Dictionary as a member of Array):
NSString *path = [[NSBundle mainBundle] pathForResource:#"List" ofType:#"plist"];
NSArray *newContent = [[NSArray alloc]initWithContentsOfFile:path];
//iterating through all members since all of them has the string "YES" which should be replaced, otherwise, you will need to create a separate dictionary for each member
for ((i = 0; i < [newContent count]; i++)){
//here you take the member (dictionary) of the array
NSDictionary *dictOfArray = [newContent objectAtIndex:i];
[dictOfArray objectForKey:#"Enabled"]=#"NO";
}
//if you update the same pList you can use the same path (otherwise use another path)
[newContent writeToFile:path atomically:YES];
So, it works now.
I'm currently making a web browsing program in Xcode 4.5.1 for OS X and I am trying to work on a list of bookmarks. What I hope to do is to have a supporting file called Bookmarks.txt in which I would list bookmarks like this:
Google
http://www.google.com/
Apple
http://www.apple.com/
Microsoft
http://www.microsoft.com/
I have already looked at a lot of pages discussing this, but none of them apply to what I'm doing. What I have now is
NSMutableArray *list;
NSString *contents;
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Bookmarks" ofType:#"txt"];
if (filePath) {
content = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
for (NSString *line in [contents componentsSeparatedByString:#"\n"]) {
[list addObject:line];
}
}
as well as Dave DeLong's method, but I get all kinds of errors with Dave DeLong's and with this one nothing happens. Any help would be great, but I am just starting out at Xcode and know very little.
Thanks!
Your objects aren't initialized.
NSMutableArray *list = [[NSMutableArray alloc] init];
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Bookmarks" ofType:#"txt"];
if (filePath) {
NSString * content = [NSString initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
for (NSString *line in [contents componentsSeparatedByString:#"\n"]) {
[list addObject:line];
}
}
I understand I can for instance write a value to a .plist file as such
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"stored" ofType:#"plist"];
NSString *comment = #"this is a comment";
[comment writeToFile:filePath atomically:YES];
But If i had for say an Array inside my .plist (gameArray) and I'd like to white comment into a particular index of my array i.e. gameArray[4] ; how would I do this ?
allow me to clarify
I have a plist: stored.plist
inside my plist there is an array gameArray
i would like to update specific indexes of gameArray inside the plist
is this possible ?
You cannot update and save data in application's main bundle instead you have to do in document directory or other directory like this:
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *plistFilePath = [documentsDirectory stringByAppendingPathComponent:#"stored.plist"];
if([[NSFileManager defaultManager] fileExistsAtPAth:plistFilePath])
{//already exits
NSMutableArray *data = [NSMutableArray arrayWithContentsOfFile:plistFilePath];
//update your array here
NSString *comment = #"this is a comment";
[data replaceObjectAtIndex:4 withObject:comment];
//write file here
[data writeToFile:plistFilePath atomically:YES];
}
else{ //firstly take content from plist and then write file document directory
NSString *plistPath = [[NSBundle mainBundle] pathForResource:#"stored" ofType:#"plist"];
NSMutableArray *data = [NSMutableArray arrayWithContentsOfFile:plistPath];
//update your array here
NSString *comment = #"this is a comment";
[data replaceObjectAtIndex:4 withObject:comment];
//write file here
[data writeToFile:plistFilePath atomically:YES];
}
Assuming the contents of 'stored.plist' is an array, you need to instantiate a mutable array from the path:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"stored" ofType:#"plist"];
NSMutableArray *array = [NSMutableArray arrayWithContentsOfFile:filePath];
NSString *comment = #"this is a comment";
// inserting a new object:
[array insertObject:comment atIndex:4];
// replacing an existing object:
// classic obj-c syntax
[array replaceObjectAtIndex:4 withObject:4];
// obj-c literal syntax:
array[4] = comment;
// Cannot save to plist inside your document bundle.
// Save a copy inside ~/Library/Application Support
NSURL *documentsURL = [[[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask] objectAtIndex:0];
NSURL *arrayURL = [documentsURL URLByAppendingPathComponent:[filePath lastPathComponent]];
[array writeToURL:arrayURL atomically:NO];
i create a view based application , in this project i want read data from .plist file.
how it is possible,
Pleas help me ?
NSString *path = [[NSBundle mainBundle] pathForResource:#"plistfilename" ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:#"%#", path]];
NSString *body = [dict objectForKey:#"Keyname"];
with the use of this anyone can read data from plist file.
If you are sure the .plist file is a dictionary at root level,
return [NSDictionary dictionaryWithContentsOfFile:#"path/to/your.plist"];
otherwise,
NSData* plist_data = [NSData dataWithContentsOfFile:#"path/to/your.plist"];
return [NSPropertyListSerialization propertyListFromData:plist_data mutabilityOption:NSPropertyListImmutable format:NULL errorDescription:NULL];