123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- //
- // MTLManagedObjectAdapter.h
- // Mantle
- //
- // Created by Justin Spahr-Summers on 2013-03-29.
- // Copyright (c) 2013 GitHub. All rights reserved.
- //
-
- #import <CoreData/CoreData.h>
-
- @class AWSMTLModel;
-
- // A MTLModel object that supports being serialized to and from Core Data as an
- // NSManagedObject.
- @protocol AWSMTLManagedObjectSerializing
- @required
-
- // The name of the Core Data entity that the receiver serializes to and
- // deserializes from.
- //
- // This method must not return nil.
- + (NSString *)managedObjectEntityName;
-
- // Specifies how to map property keys to different keys on the receiver's
- // +managedObjectEntity.
- //
- // Entity attributes will be mapped to and from the receiver's properties using
- // +entityAttributeTransformerForKey:. Entity relationships will be mapped to
- // and from MTLModel objects using +relationshipModelClassesByPropertyKey.
- // Fetched properties are not supported.
- //
- // Subclasses overriding this method should combine their values with those of
- // `super`.
- //
- // Any property keys not present in the dictionary are assumed to match the
- // entity key that should be used. Any keys associated with NSNull will not
- // participate in managed object serialization.
- //
- // Returns a dictionary mapping property keys to entity keys (as strings) or
- // NSNull values.
- + (NSDictionary *)managedObjectKeysByPropertyKey;
-
- @optional
-
- // Specifies a set of property keys used by the adapter to check for an already
- // existing managed object when converting the MTLModel to its related
- // NSManagedObject.
- //
- // The adapter will first map any keys provided by this method to the correct
- // keys in managedObjectKeysByPropertyKey.
- //
- // The adapter will then perform a fetch request in the provided context for a
- // managed object that matches the MTLModel's managedObjectEntityName and has
- // equal values set for the property keys on the MTLModel.
- //
- // The managed object returned by the fetch request will then be set with all
- // values from the MTLModel that the managed object is being converted from.
- //
- // If a property value of our MTLModel is yet another MTLModel which needs to be
- // converted to a managed object, the class for that MTLModel can also implement
- // this method to perform its own uniqing.
- //
- // For example:
- // 1. An MTLModel subclass has id_number = 10.
- // 2. An NSManagedObject accessible to the adapter's context has idnumber = 10.
- // 3. managedObjectKeysByPropertyKey returns @{@"id_number" : @"idnumber"}
- // 4. propertyKeysForManagedObjectUniquing returns
- // [NSSet setWithObject:@"id_number"];
- // 5. Then our fetch request may return this managed object (or another managed
- // object with idnumber = 10).
- //
- // NOTE: If multiple managed objects follow the same uniquing criteria only one
- // of them will be set with our MTLModel's values.
- + (NSSet *)propertyKeysForManagedObjectUniquing;
-
- // Specifies how to convert the given property key to a managed object
- // attribute. If reversible, the transformer will also be used to convert the
- // managed object attribute back to the property.
- //
- // If the receiver implements a `+<key>EntityAttributeTransformer` method,
- // MTLManagedObjectAdapter will use the result of that method instead.
- //
- // Returns a value transformer, or nil if no transformation should be performed.
- + (NSValueTransformer *)entityAttributeTransformerForKey:(NSString *)key;
-
- // Specifies the MTLModel subclasses that should be deserialized to the
- // receiver's property keys when a property key corresponds to an entity
- // relationship.
- //
- // In other words, the dictionary returned by this method is used to decode
- // managed object relationships into MTLModels (or NSArrays or NSSets thereof)
- // set on the receiver.
- //
- // If a property key is omitted from the returned dictionary, but present in
- // +managedObjectKeysByPropertyKey, and the receiver's +managedObjectEntity has
- // a relationship at the corresponding key, an exception will be thrown during
- // deserialization.
- //
- // Subclasses overriding this method should combine their values with those of
- // `super`.
- //
- // Returns a dictionary mapping property keys to the Class objects that should
- // be used.
- + (NSDictionary *)relationshipModelClassesByPropertyKey;
-
- // Overridden to deserialize a different class instead of the receiver, based on
- // information in the provided object.
- //
- // This is mostly useful for class clusters, where the abstract base class would
- // be passed into +[MTLManagedObjectAdapter
- // modelOfClass:fromManagedObject:error:], but a subclass should be instantiated
- // instead.
- //
- // managedObject - The object that will be deserialized.
- //
- // Returns the class that should be instantiated (which may be the receiver), or
- // nil to abort parsing (e.g., if the data is invalid).
- + (Class)classForDeserializingManagedObject:(NSManagedObject *)managedObject;
-
- // Overriden when merging the value of the given key on the receiver with the
- // value of the same key from the given `NSManagedObject` requires custom
- // handling.
- //
- // By default, this method is not implemented, and precedence will be given to
- // the value of the receiving model implicitly.
- //
- // When implemented, this method is called when an existing `NSManagedObject`
- // is found for the receiving model, before updating the `NSManagedObject`'s
- // properties.
- //
- // When implementing, you should use `+managedObjectKeysByPropertyKey` to map
- // the given `key` to the appropriate `NSManagedObject` property.
- - (void)mergeValueForKey:(NSString *)key fromManagedObject:(NSManagedObject *)managedObject;
-
- // Overriden when merging values on the receiver with the given
- // `NSManagedObject` requires custom handling.
- //
- // By default, this method is not implemented, and precedence will be given to
- // the values of the receiving model implicitly.
- //
- // When implemented, this method is called when an existing `NSManagedObject`
- // is found for the receiving model, before updating the `NSManagedObject`'s
- // properties.
- //
- // When implementing, you should use `+managedObjectKeysByPropertyKey` to map
- // the given `key` to the appropriate `NSManagedObject` property.
- //
- // If you have also implemented `mergeValueForKey:fromManagedObject:` you have
- // to make sure to call `mergeValueForKey:fromManagedObject:` from this method
- // when appropriate.
- - (void)mergeValuesForKeysFromManagedObject:(NSManagedObject *)managedObject;
-
- @end
-
- // The domain for errors originating from MTLManagedObjectAdapter.
- extern NSString * const AWSMTLManagedObjectAdapterErrorDomain;
-
- // +classForDeserializingManagedObject: returned nil for the given object.
- extern const NSInteger AWSMTLManagedObjectAdapterErrorNoClassFound;
-
- // An NSManagedObject failed to initialize.
- extern const NSInteger AWSMTLManagedObjectAdapterErrorInitializationFailed;
-
- // The managed object key specified by +managedObjectKeysByPropertyKey does not
- // exist in the NSEntityDescription.
- extern const NSInteger AWSMTLManagedObjectAdapterErrorInvalidManagedObjectKey;
-
- // The managed object property specified has a type that isn't supported by
- // MTLManagedObjectAdapter.
- extern const NSInteger AWSMTLManagedObjectAdapterErrorUnsupportedManagedObjectPropertyType;
-
- // The fetch request to find an existing managed object based on
- // `+propertyKeysForManagedObjectUniquing` failed.
- extern const NSInteger AWSMTLManagedObjectAdapterErrorUniqueFetchRequestFailed;
-
- // A MTLModel property cannot be serialized to or deserialized from an
- // NSManagedObject relationship.
- //
- // For a to-one relationship, this means that the property does not contain
- // a MTLModel, or the MTLModel does not conform to <MTLManagedObjectSerializing>.
- //
- // For a to-many relationship, this means that the property does not contain an
- // NSArray or NSSet of MTLModel<MTLManagedObjectSerializing> instances.
- extern const NSInteger AWSMTLManagedObjectAdapterErrorUnsupportedRelationshipClass;
-
- // The model's implementation of +managedObjectKeysByPropertyKey included a key
- // which does not actually exist in +propertyKeys.
- extern const NSInteger AWSMTLManagedObjectAdapterErrorInvalidManagedObjectMapping;
-
- // Converts a MTLModel object to and from an NSManagedObject.
- @interface AWSMTLManagedObjectAdapter : NSObject
-
- // Attempts to deserialize an NSManagedObject into a MTLModel object.
- //
- // modelClass - The MTLModel subclass to return. This class must conform to
- // <MTLManagedObjectSerializing>. This argument must not be nil.
- // managedObject - The managed object to deserialize. If this argument is nil,
- // the method returns nil.
- // error - If not NULL, this may be set to an error that occurs during
- // deserialization or initializing an instance of `modelClass`.
- //
- // Returns an instance of `modelClass` upon success, or nil if an error
- // occurred.
- + (id)modelOfClass:(Class)modelClass fromManagedObject:(NSManagedObject *)managedObject error:(NSError **)error;
-
- // Serializes a MTLModel into an NSManagedObject.
- //
- // model - The model object to serialize. This argument must not be nil.
- // context - The context into which to insert the created managed object. This
- // argument must not be nil.
- // error - If not NULL, this may be set to an error that occurs during
- // serialization or insertion.
- + (id)managedObjectFromModel:(AWSMTLModel<AWSMTLManagedObjectSerializing> *)model insertingIntoContext:(NSManagedObjectContext *)context error:(NSError **)error;
-
- @end
|