Основные данные - следите за изменениями и регистрируйте локальные уведомления - PullRequest
5 голосов
/ 29 января 2011

Я относительно новичок в Core Data и KVC, но мне бы хотелось несколько советов по регистрации слушателей для изменений в объектах Core Data.Вот ситуация:

У меня есть один NSManagedObject с именем Patient, а другой - MedicationPatient может быть много Medications, а у Medication есть даты startOn и endOn.

Я бы хотел как-то прослушать изменения в свойстве endOn всехMedication объектов.Когда происходит изменение, я хотел бы запланировать локальное уведомление на устройстве iOS.Ранее я работал с локальными уведомлениями, но не знаю, куда поместить код для этого в этом контексте.

Я создаю код планирования в делегате приложения и каким-то образом регистрирую делегата приложения для прослушиванияизменения в Medication объектах?Это нужно прикрепить к NSManagedObjectContext?

Как это сделать?Указатели будут очень признательны!

Спасибо!

Ответы [ 2 ]

7 голосов
/ 29 января 2011

При наблюдении значения ключа вам нужен какой-то экземпляр для наблюдения.Иногда это может быть тот же объект, который вызывает -setEndOn: on Medication;иногда это может быть что-то еще.Давайте предположим, что в вашем приложении есть класс MedicationManager, один экземпляр которого создан.И, кроме того, предположим, что в MedicationManager есть метод экземпляра -createMedicationWithName: startOn: endOn: как здесь:

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

или что-то в этом роде.

Примечаниехотел бы удалитьObserver ... Кроме того, при запуске приложения вам нужно будет установить MedicationManager в качестве наблюдателя для существующих лекарств.Я думаю, что это может быть так же просто, как перебирать все лекарства и вызывать addObserver для каждого.Если у вас много лекарств, вы можете сделать это более «ленивым» образом (например, в -awakeFromFetch).

3 голосов
/ 29 января 2011

Вам придется регистрировать наблюдателей, когда объекты выбираются из магазина в первый раз, а также при их создании. Вместо того, чтобы циклически проходить по всем записям при первом извлечении (что подвержено ошибкам, особенно на iPhone, когда немодифицированные извлеченные объекты могут быть повреждены, если их не сохранять), просто используйте сообщения awakeFromFetch и awakeFromInsert.

Кроме того, в приведенном ниже примере кода вы также можете следить за совокупной информацией пациента, такой как самое быстрое начало и самое ближайшее время, создавая переходные свойства для пациента, в которых хранится эта информация. Следующий код наблюдает за изменениями endOn в лекарстве и предлагает вам возможность обновить вышеупомянутый переходный процесс пациента "скорейшее завершение" или "скорейшее начало"

- (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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...