Good practices for multiple language data in Core

2020-02-23 04:30发布

i need a multilingual coredata db in my iphone app. I could create different database for each language but i hope that in iphone sdk exist an automatically way to manage data in different language core data like for resources and string.

Someone have some hints?

3条回答
Emotional °昔
2楼-- · 2020-02-23 04:45

Like Gordon, I use quite similar code, but not written files generated by model. I use this code in my .m file where I want to show the data.
As I start from Apple template, I put this code exactly in
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
of my TableViewController.m

P.S: Just to understand, I use these prefixes: tbl_ for tables (entities), rel_ for relationships, fld_ for fields (attributes).

Hope this helps.

NSSet *sourceSet = [NSSet setWithArray:[[tbl_MainTable rel_Localization]allObjects]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"fld_Locale == %@", [[NSLocale preferredLanguages] objectAtIndex:0]];
NSSet *filteredSet = [sourceSet filteredSetUsingPredicate:predicate];
//NSLog(@"%@", filteredSet); NSLog(@"%@", [[filteredSet valueForKey:@"fld_Name"] anyObject]);
if ([filteredSet count] > 0)
{
    [cell.detailTextLabel setText:[[filteredSet valueForKey:@"fld_Name"] anyObject]];
}
查看更多
我命由我不由天
3楼-- · 2020-02-23 04:57

I've done something similar to Shortseller, but without the use of categories.

alt text

InternationalBook and LocalizedBook are both custom managed objects with a one-to-many relationship (one international book to many localised books).

In the implementation of InternationalBook, I've added a custom accessor for title:

- (NSString *)title {
    [self willAccessValueForKey:@"title"];
    NSString *locTitle = nil;
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"locale==%@", [DataManager localeString]];
    NSSet *localizedSet = [self.localizedBook filteredSetUsingPredicate:predicate];
    if ([localizedSet count] > 0) {
        locTitle = [[localizedSet valueForKey:@"localizedTitle"] anyObject];
    }
    [self didAccessValueForKey:@"title"];
    return locTitle;
}

[DataManager localeString] is a class method which returns the user's language and country code: en_US, fr_FR, etc. See documentation on NSLocale for details.

See the "Custom Attribute and To-One Relationship Accessor Methods" section of the Core Data Programming Guide for an explanation of willAccessValueForKey: and didAccessValueForKey:.

When populating the data, I grab a string representing the user's current locale ([DataManager localeString]), and store that along the with localised book title in a new LocalizedBook object. Each LocalizedBook instance is added to an NSMutableSet, which represents the one-to-many relationship.

NSMutableSet *bookLocalizations = [internationalBook mutableSetValueForKey:@"localizedBook"]; // internationalBook is an instance of InternationalBook
// set the values for locale and localizedTitle
LocalizedBook *localizedBook = (LocalizedBook *)[NSEntityDescription insertnNewObjectEntityForName:@"LocalizedBook" inManagedObjectContext:self.bookMOC];
localizedBook.locale = [DataManager localeString];
localizedBook.localizedTitle = theLocalizedTitle; // assume theLocalizedTitle has been defined.
[bookLocalizations addObject:localizedBook];
[bookLocalizations setValue:localizedBook forKey:@"localizedBook"];

Since the localised titles are being stored in the LocalizedBook managed object, you can make the title attribute a transient, but if you do that you can't use title in a predicate.

The nice thing about this approach is that the implementation of the to-many relationship is transparent to any consumers. You simply request internationalBook.title and the custom accessor returns the appropriate value based on the user's locale behind the scenes.

查看更多
一夜七次
4楼-- · 2020-02-23 05:06

I have generated model classes for the core data entities.
Then I defined category helper classes with functions to set and get the multilanguage properties (e.g. name).
So I have a Product (with e.g. code and price) and a ProductLanguage (with language and name properties) Entity.
I never directly access ProductLanguage, but always use the name function defined on the the Product model (via category). This has worked well for me sofar.

查看更多
登录 后发表回答