2011-01-28 14 views
5

コアデータとKVCは比較的新しいですが、コアデータオブジェクトの変更についてリスナーを登録する際の参考にしたいと思います。状況は次のとおりです。コアデータ - 変更を監視してローカル通知を登録する

NSManagedObjectPatientと、もう1つはMedicationと呼ばれています。 Patientは、多くはMedicationsであり、MedicationstartOnendOnの日付を持つことがあります。

MedicationすべてのオブジェクトのendOnプロパティの変更を何とか聞きたいのですが。変更が発生すると、iOSデバイスに関するローカル通知をスケジュールしたいと思います。以前は地元の通知で作業しましたが、このコンテキストでコードをどこに置くべきかはわかりません。

私はApp Delegateでスケジューリングコードを作成し、何らかの方法でApp Delegateを登録してMedicationオブジェクトの変更をリッスンしますか?これはNSManagedObjectContextに添付する必要がありますか?

これはどのように行われますか?ポインタは非常に高く評価されるだろう!

ありがとうございます!

答えて

7

キー値を観測すると、観測を行うためのインスタンスが必要です。時にはそれは、Medicationの-setEndOn:を呼び出すのと同じオブジェクトになることがあります。時にはそれは別のものでなければならないかもしれません。アプリケーションにMedicationManagerクラスがあるとしましょう。そのインスタンスのインスタンスは1つ作成されています。 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; 
     } 
    } 

か何か:このようなそして、さらにMedicationManagerはインスタンスメソッド-createMedicationWithNameを持っていることを前提としています。

Medicationを削除すると、Observer ...を削除したいと考えています。また、アプリを起動するときにMedicationManagerを既存のMedicationsのオブザーバーとして確立する必要があります。私は、これがすべての医薬品を反復し、それぞれのaddObserverを呼び出すのと同じくらいシンプルになると考えています。多くの医薬品をお持ちの場合は、もっと「怠惰な」方法で(つまり、-awakeFromFetchで)これを行うことができます。

+0

を更新する機能を提供しています'? – daidai

+0

'id newValue = [change objectForKey:NSKeyValueChangeNewKey];' 'ヌル 'を返します – daidai

+1

"またはそれのようなものです。 " - それは良いことです! ;) –

3

初めてオブジェクトをストアからフェッチしたとき、およびオブジェクトを作成したときにオブザーバを登録する必要があります。最初にフェッチするときに(すべてのエントリをループする必要はありません(特に、変更されていないフェッチされたオブジェクトにフォールトが発生した場合にiPhoneでエラーが発生する可能性があります)、awakeFromFetchとawakeFromInsertメッセージを使用してください。

また、下記のコード例では、この情報を保存している患者の一時的なプロパティを作成することで、最も早いstartOnや最も早いendOnなどの患者の集約情報に追いつくこともできます。次のコードは、薬でendOnへの変更を観察し、あなたの患者の前述の過渡「endOn最も早い」または「至急startOn」あなたはobserveValueForKeyPath `内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 
} 
+0

'id newValue = [change objectForKey:NSKeyValueChangeNewKey];' 'ヌル 'を返します - どうすれば結果を得ることができますか? – daidai

+0

私は理論化することができないあなたの他のコードをすべて見ずに、新しい質問をソースコードで投稿してみてください。上記の答えの私のバージョンでは、newValueのnilを取得しません –

関連する問題