CoreData - to-many relationships - observing
General implementation solving the problem of properties dependent on the properties of another entity in a to-many relationship
Xcode4 Workspace now working with both iOS and Mac version, codesharing should be simplified
Added a warning for users building a 10.5 deployment target. Future development will focus on iOS/Mac
Context merges now supported, unfortunately observings need to be deactivated during merge. Take a look at testInvalidContextMergeSituation in TestCoreDataDependentPropertiesContextMerge.m
Added several unittests for context merges and undo/redo handling
Created a new project in Xcode 4, the old Xcode 3 projects currently do not work and will be removed soon
Added support for merging contexts, ATTENTION: See Person.m how to handle incremental udpates while merging! If the propery is modeled in your Core Data datamodel ignore change processing while merging!
awakeFromSnapshotEvents: needs more testing, will add testcases soon
Added the customer sum property to the datamodel for performance reasons
Implemented the update of customer sum without unfaulting all related invoices if an invoice sum changes
All changes were made for iOS performance optimization
Optimizations for relation changes will be added soon
Many thanks to Fahad Gilani for the interesting discussion about changes to the current version.
Modified to work across to-one and to-many relations
extended Sample and unit tests
Important: (from developer.apple.com)
Note that you cannot set up dependencies on to-many relationships. For example, suppose you have an Order object with a to-many relationship (orderItems) to a collection of OrderItem objects, and OrderItem objects have a price attribute. You might want the Order object have a totalPrice attribute that is dependent upon the prices of all the OrderItem objects in the relationship. You can not do this by implementing keyPathsForValuesAffectingValueForKey: and returning orderItems.price as the keypath for totalPrice. You must observe the price attribute of each of the OrderItem objects in the orderItems collection and respond to changes in their values by updating totalPrice yourself.
Demonstrated with an example modelling Customers and Invoices
The total sum of a customer has to be calculated from all invoices Undo&Redo is fully functional with this implementation.
HOWTO use the stuff:
write more tests!
Add LPManagedObjectContext, LPManagedObjectContextObservationInfo, LPManagedObject_ObservationInfo and LPManagedObject to your project
Exchange the current NSManagedObjectContext with a LPManagedObjectContext (LPAutomatedObserving_AppDelegate.m:113) after the CoreData stack is fully initialized send -(void) prepareDependentProperties; to the context
inherit each Class with dependent properties from LPManagedObject (Customer.m) implement the following two methods in each relevant class:
-(void) updateDerived<Key>ForChange:(NSDictionary *)change Use the change information to create incremental updates, be carful with multiple observings across relations which trigger multiple updates. Take a look at Person.m for detailed information about this issue.
The source is published under a BSD License, so feel free to use it wherever you want.
Inspired by the solution presented at macoun09 - CoreData session http://macoun.de/?page_id=2266