2011-01-28 18 views
5

Soy relativamente nuevo en Core Data y KVC, pero me gustaría obtener algunos consejos para registrar los escuchas en busca de cambios en los objetos de Core Data. Aquí está la situación:Datos principales: observe los cambios y registre las notificaciones locales

Tengo un NSManagedObject llamado Patient y otro llamado . Un Patient puede tener muchos Medications, y un Medication tiene un startOn y endOn fechas.

Me gustaría escuchar de alguna manera los cambios en la propiedad endOn de todos los objetos Medication. Cuando ocurre un cambio, me gustaría programar una notificación local en el dispositivo iOS. He trabajado con notificaciones locales anteriormente, pero no sé dónde colocar el código en este contexto.

¿Creó el código de programación en el delegado de la aplicación y de alguna manera registré el delegado de la aplicación para escuchar los cambios en los objetos Medication? ¿Es necesario adjuntar esto al NSManagedObjectContext?

¿Cómo se hace esto? ¡Los punteros serán muy apreciados!

Gracias!

Respuesta

7

Con Observación del valor clave, necesita alguna instancia para realizar la observación. Algunas veces ese puede ser el mismo objeto que llama -setEndOn: en Medication; a veces podría ser otra cosa. Supongamos que su aplicación tiene una clase MedicationManager, de la cual se crea una instancia. Y, además, que asumirá MedicationManager tiene un método de instancia -createMedicationWithName: Starton: endon: de esta manera:

- (Medication*) createMedicationWithName:(NSString*)medName startOn:(NSDate*)startDate endOn:(NSDate*)endDate 
    { 
    // Create and configure a new instance of the Compound entity 
    Medication *newMedication = (Medication *)[NSEntityDescription insertNewObjectForEntityForName:@"Medication" 
               inManagedObjectContext:[self managedObjectContext]]; 
    [newMedication setName:medName]; 
    [newMedication setStartOn:startDate]; 
    [newMedication setEndOn:endDate]; 

    // Set up KVO 
    [newMedication addObserver:self 
        forKeyPath:@"endOn" 
        options:NSKeyValueObservingOptionNew 
        context:nil]; 

    return newCompound; 
    } 


- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
                change:(NSDictionary *)change 
                context:(void *)context 
    { 
    if ([keyPath isEqualToString:@"endOn"]) 
     { 
     // ... schedule local notification on the iOS device for (Medication*)object. 
     return; 
     } 
    } 

O algo por el estilo.

Tenga en cuenta que cuando elimine un medicamento, querrá eliminarlo. Además, al iniciar su aplicación, deberá establecer MedicationManager como observador de los medicamentos existentes. Creo que esto podría ser tan simple como iterar sobre todos los medicamentos y llamar a addObserver para cada uno. Si tiene muchos medicamentos, puede hacer esto de una manera más "floja" (es decir, en -awakeFromFetch).

+0

¿cómo obtener el valor de 'endOn' el interior' observeValueForKeyPath ¿? – daidai

+0

usando 'id newValue = [change objectForKey: NSKeyValueChangeNewKey];' returns 'null' – daidai

+1

" O algo así. "- ¡Esa es una buena idea! ;) –

3

Deberá registrar observadores cuando los objetos se obtienen de la tienda por primera vez, así como cuando se crean. En lugar de tener que pasar por todas las entradas la primera vez que busca (que es propenso a errores, especialmente en el iPhone cuando los objetos recuperados no modificados pueden fallar cuando no se conservan) simplemente use los mensajes awakeFromFetch y awakeFromInsert.

Además, en el siguiente código de ejemplo, también puede mantenerse al día con la información agregada del paciente, como el inicio más temprano y el final más cercano al hacer propiedades transitorias en el paciente que almacenan esta información. El siguiente código observa cambios en el endon en la medicación y le ofrece la posibilidad de actualizar la del paciente antes mencionado transitoria "lo más pronto posible endon" o "lo más pronto posible Starton"

- (void)addMyObservers 
{ 
    registeredObservers_ = YES; 
    [self addObserver:self forKeyPath:@"endOn" options:NSKeyValueObservingOptionNew context:nil]; 
} 

- (void)awakeFromInsert 
{ 
    // called when you create this object 
    [super awakeFromInsert]; 
    [self addMyObservers]; 
} 

- (void)awakeFromFetch 
{ 
    // called when you fetch this old object from the store 
    [super awakeFromFetch]; 
    [self addMyObservers]; 
} 

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    if([keyPath isEqualToString:@"endOn"]) 
    { 
     id newValue = [change objectForKey:NSKeyValueChangeNewKey]; 
     // someone changed endOn so do something with this "newValue" 
     // check to see if the Patient needs the transient property for the soonest medication updated 
     // update any local notification schedule 
    } 
} 

// this is only required if you want to update the Patient's transient property for the soonest endOn or 
- (void)setPatient:(Patient *)patient 
{ 
    [self willChangeValueForKey:@"patient"]; 
    [self setPrimitivePatient:patient]; 
    [self didChangeValueForKey:@"patient"]; 

    // check to see if the Patient needs the transient property for the soonest medication updated 
} 
+0

utilizando 'id newValue = [change objectForKey: NSKeyValueChangeNewKey];' returns 'null' - ¿cómo puedo obtener el resultado? – daidai

+0

Sin ver todo su otro código, no podría teorizar, intente publicar una nueva pregunta con el código fuente. En mi versión de la respuesta anterior, no obtengo nada para newValue –

Cuestiones relacionadas