核心数据中多语言数据的良好实践

时间:2010-04-22 09:23:49

标签: iphone database core-data

我需要在我的iphone应用程序中使用多语言coredata数据库。我可以为每种语言创建不同的数据库,但我希望在iphone sdk中存在一种自动方式来管理不同语言核心数据中的数据,如资源和字符串。

有人有一些提示吗?

3 个答案:

答案 0 :(得分:11)

我做过类似Shortseller的事情,但没有使用类别。

alt text http://i40.tinypic.com/x3ryp.png

InternationalBookLocalizedBook都是具有一对多关系的自定义管理对象(一本国际图书与许多本地化图书)。

InternationalBook的实施中,我为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]是一种类方法,它返回用户的语言和国家/地区代码:en_USfr_FR等。有关详细信息,请参阅NSLocale上的文档。

有关willAccessValueForKey:didAccessValueForKey:的说明,请参阅“核心数据编程指南”的“自定义属性和一对一关系访问器方法”部分。

填充数据时,我会抓取一个表示用户当前区域设置([DataManager localeString])的字符串,并将其与本地化的书籍标题一起存储在新的LocalizedBook对象中。每个LocalizedBook实例都会添加到NSMutableSet,代表一对多关系。

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

由于本地化的标题存储在LocalizedBook托管对象中,因此您可以使title属性成为瞬态,但如果您这样做,则无法在title中使用internationalBook.title谓词。

这种方法的好处在于,对多个关系的实现对任何消费者都是透明的。您只需请求{{1}},自定义访问器将根据用户在幕后的区域设置返回适当的值。

答案 1 :(得分:0)

我已经为核心数据实体生成了模型类。
然后我定义了类别辅助类,其中包含用于设置和获取多语言属性(例如名称)的函数。
所以我有一个产品(例如代码和价格)和ProductLanguage(具有语言和名称属性)实体。
我从不直接访问ProductLanguage,但总是使用Product model上定义的name函数(通过类别)。这对我来说很有用。

答案 2 :(得分:0)

和Gordon一样,我使用的代码非常相似,但不是由模型生成的文件。我在我的.m文件中使用此代码,我想在其中显示数据 当我从Apple模板开始时,我将此代码完全放在了中   - (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
我的TableViewController.m

P.S:只是要理解,我使用这些前缀:tbl_用于表(实体),rel_用于关系,fld_用于字段(属性)。

希望这有帮助。

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