MTLManagedObjectAdapter.h
9.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
//
// MTLManagedObjectAdapter.h
// Mantle
//
// Created by Justin Spahr-Summers on 2013-03-29.
// Copyright (c) 2013 GitHub. All rights reserved.
//
#import <CoreData/CoreData.h>
@class MTLModel;
// A MTLModel object that supports being serialized to and from Core Data as an
// NSManagedObject.
@protocol MTLManagedObjectSerializing
@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 MTLManagedObjectAdapterErrorDomain;
// +classForDeserializingManagedObject: returned nil for the given object.
extern const NSInteger MTLManagedObjectAdapterErrorNoClassFound;
// An NSManagedObject failed to initialize.
extern const NSInteger MTLManagedObjectAdapterErrorInitializationFailed;
// The managed object key specified by +managedObjectKeysByPropertyKey does not
// exist in the NSEntityDescription.
extern const NSInteger MTLManagedObjectAdapterErrorInvalidManagedObjectKey;
// The managed object property specified has a type that isn't supported by
// MTLManagedObjectAdapter.
extern const NSInteger MTLManagedObjectAdapterErrorUnsupportedManagedObjectPropertyType;
// The fetch request to find an existing managed object based on
// `+propertyKeysForManagedObjectUniquing` failed.
extern const NSInteger MTLManagedObjectAdapterErrorUniqueFetchRequestFailed;
// 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 MTLManagedObjectAdapterErrorUnsupportedRelationshipClass;
// The model's implementation of +managedObjectKeysByPropertyKey included a key
// which does not actually exist in +propertyKeys.
extern const NSInteger MTLManagedObjectAdapterErrorInvalidManagedObjectMapping;
// Converts a MTLModel object to and from an NSManagedObject.
@interface MTLManagedObjectAdapter : 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:(MTLModel<MTLManagedObjectSerializing> *)model insertingIntoContext:(NSManagedObjectContext *)context error:(NSError **)error;
@end