2010-04-22 16 views
6

Necesito una base de datos multilingüe en mi aplicación de iPhone. Podría crear una base de datos diferente para cada idioma, pero espero que en iphone sdk exista una manera automática de administrar los datos en diferentes datos básicos del idioma, como recursos y cadenas.Buenas prácticas para datos de múltiples idiomas en Core Data

¿Alguien tiene algunas pistas?

+1

Dios o ¿bien? :) –

Respuesta

11

He hecho algo similar a Shortseller, pero sin el uso de categorías.

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

InternationalBook y LocalizedBook son ambos objetos gestionados a medida con una relación uno-a-muchos (un libro internacional para muchos libros localizados).

En la implementación de InternationalBook, he añadido un descriptor de acceso personalizado para 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] es un método de clase que devuelve el lenguaje y el código del país del usuario: en_US, fr_FR, etc. Consulte la documentación de NSLocale para más detalles.

Consulte la sección "Métodos del atributo personalizado y métodos de acceso a la relación uno a uno" de la Guía de programación de datos básicos para obtener una explicación de willAccessValueForKey: y didAccessValueForKey:.

Al rellenar los datos, tomo una cadena que representa la configuración regional actual del usuario ([DataManager localeString]) y la guardo junto con el título del libro localizado en un nuevo objeto LocalizedBook. Cada instancia de LocalizedBook se agrega a NSMutableSet, que representa la relación de uno a muchos.

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

Desde los títulos localizados están siendo almacenados en el objeto LocalizedBook administrado, puede hacer que la atribuyen title un transitorio, pero si lo que no se puede utilizar title en un predicado.

Lo bueno de este enfoque es que la implementación de la relación de muchos es transparente para cualquier consumidor. Simplemente solicite internationalBook.title y el acceso personalizado o devuelve el valor apropiado según la configuración regional del usuario detrás de las escenas.

+0

Realmente útil gracias Gordon, lo estoy usando. –

+0

Excelente, pero ¿cómo manejas la situación cuando un usuario cambia la configuración regional? En mi humilde opinión, pedirle a un usuario que reinicie la aplicación es descortés, pero de lo contrario se debe hacer mucho trabajo para actualizar todo el texto que se muestra y se muestra en todos los controladores de vista. – Centurion

0

He generado clases de modelo para las entidades de datos centrales.
Luego definí clases de ayuda de categoría con funciones para establecer y obtener las propiedades de varios idiomas (por ejemplo, nombre).
Tengo un Producto (con un código y un precio, por ejemplo) y una Entidad de idioma del producto (con propiedades de idioma y nombre).
Nunca accedo directamente a ProductLanguage, pero siempre utilizo la función de nombre definida en el modelo del Producto (por categoría). Esto funcionó bien para mí.

0

Como Gordon, uso un código bastante similar, pero no archivos escritos generados por el modelo. Uso este código en mi archivo .m donde quiero mostrar los datos.
Mientras comienzo de la plantilla de Apple, pongo este código exactamente en
- (void) configureCell: (UITableViewCell *) atIndexPath celular: (NSIndexPath *) indexPath
de mi TableViewController.m

P.S: Para entenderlo, utilizo estos prefijos: tbl_ para tablas (entidades), rel_ para relaciones, fld_ para campos (atributos).

Espero que esto ayude.

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