Tutorial :iphone - reading from Localizable.strings file as a key-value in a dictionary



Question:

I want to read the text from the localizable.strings file. I am collecting the strings for translation from several directories and file in one .strings file. But then I have several copies of the same translation strings. I want to remove this programmatically. So I need to read the strings only (not the comments) from the .strings file, and - then sort them, - remove repeated strings then create a new .strings file.

Is it possible to read the strings file and keep the key string and translated value in a dictionary. I mean any built-in method to read a .text file, only the "key " = "value" part, avoiding /* ... */ or # comments part. Like reading a config file.


Solution:1

  NSString *path = [[NSBundle mainBundle] pathForResource:@"Localizable"                                                     ofType:@"strings"                                                                                                       inDirectory:nil                                            forLocalization:@"ja"];      // compiled .strings file becomes a "binary property list"    NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];      NSString *jaTranslation = [dict objectForKey:@"hello"];  


Solution:2

I am happy to find an excellent API in NSString class. The code is below.

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {  // Insert code here to initialize your application   NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Localizable" ofType:@"strings"];  NSString *fileText = [NSString stringWithContentsOfFile:filePath encoding: NSUnicodeStringEncoding error:nil];  NSDictionary *stringDictionary = [fileText propertyListFromStringsFileFormat];    NSArray *allKeys = [stringDictionary allKeys];    NSArray *sortedKeys = [allKeys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];    NSString *documentsDirectory;     NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);    if ([paths count] > 0)  {             documentsDirectory = [paths objectAtIndex:0];         }    NSString *outputPath = [documentsDirectory stringByAppendingString:@"/Localizable.strings"];  NSLog(@"Strings contents are writing to: %@",outputPath);  [[NSFileManager defaultManager] createFileAtPath:outputPath contents:nil attributes:nil];  NSFileHandle *outputHandle = [NSFileHandle fileHandleForWritingAtPath:outputPath];  [outputHandle seekToEndOfFile];    for(id key in sortedKeys){      NSString *line = [NSString stringWithFormat:@"\"%@\" = \"%@\";\n", key, [stringDictionary objectForKey:key]];      NSLog(@"%@",line);      [outputHandle writeData:[line dataUsingEncoding:NSUnicodeStringEncoding]];  }  }  


Solution:3

What I was looking for is a way to read a json from a bundle file into a NSDictionary and then print it inside a UITextView. The result was not nicely formatted!

I used a part of Karim's answer from above to create a method that generated a beautified json in a string:

-(void)setText:(NSDictionary *)json  {      NSArray *allKeys = [json allKeys];        _beautyStr = @"";      for(id key in allKeys){         NSString *line = [NSString stringWithFormat:@"\"%@\" = \"%@\";\n", key, [text objectForKey:key]];      _beautyStr = [NSString stringWithFormat:@"%@%@",_beautyStr, line];      }        NSLog(@"%@",_beautyStr);  }  


Solution:4

Solution in Swift

I created a swift code following the Objective-C code answered by @jason-moore above This solution is swift equivalent.

guard let path = Bundle.main.url(forResource: "Localizable", withExtension: "strings", subdirectory: nil, localization: "ja") else {              return nil          }  guard let dict = NSDictionary(contentsOf: path) else {          return nil      }  guard let jaTranslation = dict.value(forKey: "hello") as? String else {          return nil      }  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »