i18n in iOS Core Data

612 Views Asked by At

I'm working on a localized schema for iOS. I have different Entities that can have translated fields, so for each one I create a Translation entity. There is always a one-many relation between the two entities, allowing me to add new languages in the future, and I can access the translations via Entity.translations. So far so good.

Entity
EntityTranslation

1) First of all, I would like to know if an approach like that sounds good. Is the solution I will use in a pure SQL environment so I suppose I can follow that path.

2) Then... I would like to just use Entity.text for showing the appropriate text for the user (via NSLocale preferredLanguages). As translations returns a NSSet then one option will be to manually add the attribute to the Entity model, and change the getter:

// Entity.h
@property (nonatomic, retain) NSString * text;

// Entity.m
@synthesize text;

- (NSString *) text
{
  NSString *locale = [[NSLocale preferredLanguages] objectAtIndex:0];

  NSSet *filteredTranslations = [self.translations filteredSetUsingPredicate: [NSPredicate predicateWithFormat:@"locale = %@", locale]];
  EntityTranslation *translation = [[filteredTranslations allObjects] objectAtIndex:0];

  return translation.text;
}

It works, but does it make sense? Can I have performance issues? Is it possible to do something similar using Fetched properties? Something tells me that it should be possible but I can't make it work using the Xcode Core Data editor...

Thanks.

1

There are 1 best solutions below

8
On

Whether or not you will have perfomance problems depends how big your database is and how often you're fetching the values. You should run your code through Instruments to check what percentage of CPU time it's costing you, and cache things as necessary.

One tweak I would do is store that NSPredicate object in a static variable, since it will not change often.

If you don't have many records in the table it would be best to fetch the entire record set once then save it to an NDDictionary, which you can lookup any time.

However, I think you are making the mistake of using a big complicated system (relational database with an object oriented wrapper) to solve a very simple problem (key value lookup). And complex solutions are almost always slower and more memory hungry than simple ones.

The recommended way to do localization is with a .strings file, and I can't think of any benefits to using core data instead. Do you have 200MB of localized text? If not, then I think it's better to use a .strings file instead of core data.