Хорошие практики для многоязычных данных в Core Data

Мне нужна многоязычная база данных coredata в моем приложении для iphone. Я мог бы создать разные базы данных для каждого языка, но я надеюсь, что в iphone sdk существует автоматический способ управления данными на разных языках с основными данными, такими как ресурсы и строки.

У кого-то есть подсказки?


person Luca Bartoletti    schedule 22.04.2010    source источник


Ответы (3)


Я сделал что-то похожее на Shortseller, но без использования категорий.

альтернативный текст

InternationalBook и LocalizedBook являются настраиваемыми управляемыми объектами с отношением «один ко многим» (одна международная книга ко многим локализованным книгам).

В реализации 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_US, fr_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, и настраиваемый метод доступа возвращает соответствующее значение, зависящее от языкового стандарта пользователя.

person Gordon Hughes    schedule 22.04.2010
comment
Отлично, но как вы справляетесь с ситуацией, когда пользователь меняет локаль? ИМХО, просить пользователя перезапустить приложение - это грубо, но в противном случае необходимо проделать большую работу, чтобы обновить весь извлеченный и отображаемый текст во всех контроллерах представления. - person Centurion; 07.03.2013

Я создал классы моделей для основных сущностей данных.
Затем я определил вспомогательные классы категорий с функциями, которые нужно установить и получить многоязычные свойства (например, имя).
Итак, у меня есть Product (например, код и цена) и ProductLanguage (со свойствами языка и имени) Entity.
Я никогда не обращаюсь к ProductLanguage напрямую, но всегда использую функцию имени, определенную в модели продукта (через категорию). Это хорошо сработало для меня.

person Shortseller    schedule 22.04.2010

Как и Гордон, я использую очень похожий код, но не записываю файлы, сгенерированные моделью. Я использую этот код в своем файле .m, где хочу показать данные.
Когда я начинаю с шаблона Apple, я помещаю этот код точно в ячейку
- (void) configureCell: (UITableViewCell *) по адресуIndexPath :( 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]];
}
person ndman    schedule 03.10.2012