2012-03-11 19 views
9

Me he encontrado con un problema.¿Cómo evitar que Core Data haga duplicados en iOS 5?

Durante el fin de semana he estado trabajando en un proyecto donde estoy sacando un gran xml de un servicio web.

Básicamente tiene 3 niveles - Clientes, Administradores, Personal todo jerárquico. Por lo tanto, la primera vez que se ejecuta la aplicación, extrae este xml, lo analiza y crea todas las entradas en las 3 entidades relatadas: clientes, gerentes y personal.

Cada vez que la aplicación se inicia necesito retirar el mismo XML, pero esta vez solo necesito 'actualizar' cualquiera de los registros existentes que han cambiado, o agregar nuevos para nuevos clientes, gerentes o personal que han aparecido desde la última vez.

Así que, por el momento, como ya he dicho, está tirando de todo, analizándolo correctamente y creando las entidades correctas y completando todos los atributos.

Sin embargo, sin ningún cambio de datos, en el segundo lanzamiento está duplicación de todos los datos - lo que en lugar de 15 clientes (el número correcto) tengo 30 y así sucesivamente ...

¿Realmente tienen que agregar muchos códigos en mi análisis para verificar que en lugar de crear un NSManagedObject nuevo, verifique si ya está allí?

Y si lo es - ¿Tengo que comprobar manualmente cada atributo?

Eso es terriblemente doloroso y de larga duración, ¿no hay una forma de hacer que Core Data haga este tipo de cosas para mí automáticamente?

Gracias por cualquier ayuda o sugerencia.

Respuesta

3

como se indica en Manzana Docs https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdImporting.html

Se necesitan lazo del modelo de datos y manejar desde allí como esto

Ejemplo :

// loop over employeeIDs 
// anID = ... each employeeID in turn 
// within body of loop 

NSString *predicateString = [NSString stringWithFormat: @"employeeID == %@", anID]; 

NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString]; 

Personalmente no lo hago Ke este método y escribí este fragmento de código que maneja esto en una mansión proeficiente y que es sencillo. Me di cuenta que con el método de Apple me encontré con problemas con cadenas que tienen diferentes caracteres, como mayúsculas y espacios. A continuación, el código se prueba y funciona si se renombre correctamente todos sus objetos correspondientes. Sinceramente, creo que esta es la forma más eficiente de lograr no agregar duplicados en los datos centrales.

-(void)AvoidDuplicatesinDataModel 
{ 
    // Define our table/entity to use 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Users" 
               inManagedObjectContext:managedObjectContext]; 

    // Setup the fetch request 
    NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    [request setEntity:entity]; 

    // Define how we will sort the records 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"users" 
                    ascending:NO]; 
    NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; 

    [request setSortDescriptors:sortDescriptors]; 
    [sortDescriptor release]; 

    // Fetch the records and handle an error 
    NSError *Fetcherror; 
    NSMutableArray *mutableFetchResults = [[managedObjectContext 
              executeFetchRequest:request error:&Fetcherror] mutableCopy]; 

    if (!mutableFetchResults) { 
     // Handle the error. 
     // This is a serious error 
    } 

    //here usersNameTextField.text can be any (id) string that you are searching for 
    if ([[mutableFetchResults valueForKey:@"users"] 
     containsObject:usernameTextField.text]) { 
     //Alert user or handle your duplicate methods from here 
     return; 
    } 
} 
+0

¿por qué resulta la copia mutable para la obtención? – dmur

12

Me temo que tiene que mantener su DB limpio por su cuenta ... La forma más fácil sería usar NSFetchRequest: Al importar sus datos actualizados, puede ejecutar una consulta contra los datos existentes y decidir qué desea hacer.

Como Marcus S. Zarra mencionado en another thread sobre este tema:

Al importar una nueva fila puede ejecutar una consulta contra los filas existentes para ver si ya está en su lugar. Para ello se crea un NSFetchRequest en contra de su entidad, establecer el predicado para buscar la propiedad GUID y establecer las filas max volvieron a 1.

Yo recomendaría mantener este NSFetchRequest alrededor durante su importación , para que pueda reutilízalo mientras realizas la importación. Si el NSFetchRequest devuelve una fila, puede actualizar esa fila. Si no se devuelve una fila, puede insertar una nueva fila.

Cuando se hace correctamente, encontrará el rendimiento más que aceptable.

Otra fuente de buena información son las manzanas guías de programación: Core Data Programming Guide

+0

Sí, pensé. – iOSProgrammingIsFun

+0

@iOSProgrammingIsFun Si mi publicación fue útil, puede aceptarla :) – dom

+1

El enlace está muerto – Besi