杨锴
2024-10-09 e987bc09f955e01c2835f01e3a6af20723a579f9
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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
//
//  OBSMTLJSONAdapter.h
//  Mantle
//
//  Created by Justin Spahr-Summers on 2013-02-12.
//  Copyright (c) 2013 GitHub. All rights reserved.
//
 
#import <Foundation/Foundation.h>
 
@protocol OBSMTLModel;
@protocol OBSMTLTransformerErrorHandling;
 
/// A OBSMTLModel object that supports being parsed from and serialized to JSON.
@protocol OBSMTLJSONSerializing <OBSMTLModel>
@required
 
/// Specifies how to map property keys to different key paths in JSON.
///
/// Subclasses overriding this method should combine their values with those of
/// `super`.
///
/// Values in the dictionary can either be key paths in the JSON representation
/// of the receiver or an array of such key paths. If an array is used, the
/// deserialized value will be a dictionary containing all of the keys in the
/// array.
///
/// Any keys omitted will not participate in JSON serialization.
///
/// Examples
///
///     + (NSDictionary *)JSONKeyPathsByPropertyKey {
///         return @{
///             @"name": @"POI.name",
///             @"point": @[ @"latitude", @"longitude" ],
///             @"starred": @"starred"
///         };
///     }
///
/// This will map the `starred` property to `JSONDictionary[@"starred"]`, `name`
/// to `JSONDictionary[@"POI"][@"name"]` and `point` to a dictionary equivalent
/// to:
///
///     @{
///         @"latitude": JSONDictionary[@"latitude"],
///         @"longitude": JSONDictionary[@"longitude"]
///     }
///
/// Returns a dictionary mapping property keys to one or multiple JSON key paths
/// (as strings or arrays of strings).
+ (NSDictionary *)JSONKeyPathsByPropertyKey;
 
@optional
 
/// Specifies how to convert a JSON value to the given property key. If
/// reversible, the transformer will also be used to convert the property value
/// back to JSON.
///
/// If the receiver implements a `+<key>JSONTransformer` method, OBSMTLJSONAdapter
/// will use the result of that method instead.
///
/// Returns a value transformer, or nil if no transformation should be performed.
+ (NSValueTransformer *)JSONTransformerForKey:(NSString *)key;
 
/// Overridden to parse the receiver as a different class, based on information
/// in the provided dictionary.
///
/// This is mostly useful for class clusters, where the abstract base class would
/// be passed into -[OBSMTLJSONAdapter initWithJSONDictionary:modelClass:], but
/// a subclass should be instantiated instead.
///
/// JSONDictionary - The JSON dictionary that will be parsed.
///
/// Returns the class that should be parsed (which may be the receiver), or nil
/// to abort parsing (e.g., if the data is invalid).
+ (Class)classForParsingJSONDictionary:(NSDictionary *)JSONDictionary;
 
@end
 
/// The domain for errors originating from OBSMTLJSONAdapter.
extern NSString  *const OBSMTLJSONAdapterErrorDomain;
 
/// +classForParsingJSONDictionary: returned nil for the given dictionary.
extern const NSInteger OBSMTLJSONAdapterErrorNoClassFound;
 
/// The provided JSONDictionary is not valid.
extern const NSInteger OBSMTLJSONAdapterErrorInvalidJSONDictionary;
 
/// The model's implementation of +JSONKeyPathsByPropertyKey included a key which
/// does not actually exist in +propertyKeys.
extern const NSInteger OBSMTLJSONAdapterErrorInvalidJSONMapping;
 
/// An exception was thrown and caught.
extern const NSInteger OBSMTLJSONAdapterErrorExceptionThrown;
 
/// Associated with the NSException that was caught.
extern NSString  *const OBSMTLJSONAdapterThrownExceptionErrorKey;
 
/// Converts a OBSMTLModel object to and from a JSON dictionary.
@interface OBSMTLJSONAdapter : NSObject
 
/// Attempts to parse a JSON dictionary into a model object.
///
/// modelClass     - The OBSMTLModel subclass to attempt to parse from the JSON.
///                  This class must conform to <OBSMTLJSONSerializing>. This
///                  argument must not be nil.
/// JSONDictionary - A dictionary representing JSON data. This should match the
///                  format returned by NSJSONSerialization. If this argument is
///                  nil, the method returns nil.
/// error          - If not NULL, this may be set to an error that occurs during
///                  parsing or initializing an instance of `modelClass`.
///
/// Returns an instance of `modelClass` upon success, or nil if a parsing error
/// occurred.
+ (id)modelOfClass:(Class)modelClass fromJSONDictionary:(NSDictionary *)JSONDictionary error:(NSError **)error;
 
/// Attempts to parse an array of JSON dictionary objects into a model objects
/// of a specific class.
///
/// modelClass - The OBSMTLModel subclass to attempt to parse from the JSON. This
///              class must conform to <OBSMTLJSONSerializing>. This argument must
///              not be nil.
/// JSONArray  - A array of dictionaries representing JSON data. This should
///              match the format returned by NSJSONSerialization. If this
///              argument is nil, the method returns nil.
/// error      - If not NULL, this may be set to an error that occurs during
///              parsing or initializing an any of the instances of
///              `modelClass`.
///
/// Returns an array of `modelClass` instances upon success, or nil if a parsing
/// error occurred.
+ (NSArray *)modelsOfClass:(Class)modelClass fromJSONArray:(NSArray *)JSONArray error:(NSError **)error;
 
/// Converts a model into a JSON representation.
///
/// model - The model to use for JSON serialization. This argument must not be
///         nil.
/// error - If not NULL, this may be set to an error that occurs during
///         serializing.
///
/// Returns a JSON dictionary, or nil if a serialization error occurred.
+ (NSDictionary *)JSONDictionaryFromModel:(id<OBSMTLJSONSerializing>)model error:(NSError **)error;
 
/// Converts a array of models into a JSON representation.
///
/// models - The array of models to use for JSON serialization. This argument
///          must not be nil.
/// error  - If not NULL, this may be set to an error that occurs during
///          serializing.
///
/// Returns a JSON array, or nil if a serialization error occurred for any
/// model.
+ (NSArray *)JSONArrayFromModels:(NSArray *)models error:(NSError **)error;
 
/// Initializes the receiver with a given model class.
///
/// modelClass - The OBSMTLModel subclass to attempt to parse from the JSON and
///              back. This class must conform to <OBSMTLJSONSerializing>. This
///              argument must not be nil.
///
/// Returns an initialized adapter.
- (id)initWithModelClass:(Class)modelClass;
 
/// Deserializes a model from a JSON dictionary.
///
/// The adapter will call -validate: on the model and consider it an error if the
/// validation fails.
///
/// JSONDictionary - A dictionary representing JSON data. This should match the
///                  format returned by NSJSONSerialization. This argument must
///                  not be nil.
/// error          - If not NULL, this may be set to an error that occurs during
///                  deserializing or validation.
///
/// Returns a model object, or nil if a deserialization error occurred or the
/// model did not validate successfully.
- (id)modelFromJSONDictionary:(NSDictionary *)JSONDictionary error:(NSError **)error;
 
/// Serializes a model into JSON.
///
/// model - The model to use for JSON serialization. This argument must not be
///         nil.
/// error - If not NULL, this may be set to an error that occurs during
///         serializing.
///
/// Returns a model object, or nil if a serialization error occurred.
- (NSDictionary *)JSONDictionaryFromModel:(id<OBSMTLJSONSerializing>)model error:(NSError **)error;
 
/// Filters the property keys used to serialize a given model.
///
/// propertyKeys - The property keys for which `model` provides a mapping.
/// model        - The model being serialized.
///
/// Subclasses may override this method to determine which property keys should
/// be used when serializing `model`. For instance, this method can be used to
/// create more efficient updates of server-side resources.
///
/// The default implementation simply returns `propertyKeys`.
///
/// Returns a subset of propertyKeys that should be serialized for a given
/// model.
- (NSSet *)serializablePropertyKeys:(NSSet *)propertyKeys forModel:(id<OBSMTLJSONSerializing>)model;
 
/// An optional value transformer that should be used for properties of the given
/// class.
///
/// A value transformer returned by the model's +JSONTransformerForKey: method
/// is given precedence over the one returned by this method.
///
/// The default implementation invokes `+<class>JSONTransformer` on the
/// receiver if it's implemented. It supports NSURL conversion through
/// +NSURLJSONTransformer.
///
/// modelClass - The class of the property to serialize. This property must not be
///              nil.
///
/// Returns a value transformer or nil if no transformation should be used.
+ (NSValueTransformer *)transformerForModelPropertiesOfClass:(Class)modelClass;
 
/// A value transformer that should be used for a properties of the given
/// primitive type.
///
/// If `objCType` matches @encode(id), the value transformer returned by
/// +transformerForModelPropertiesOfClass: is used instead.
///
/// The default implementation transforms properties that match @encode(BOOL)
/// using the OBSMTLBooleanValueTransformerName transformer.
///
/// objCType - The type encoding for the value of this property. This is the type
///            as it would be returned by the @encode() directive.
///
/// Returns a value transformer or nil if no transformation should be used.
+ (NSValueTransformer *)transformerForModelPropertiesOfObjCType:(const char *)objCType;
 
@end
 
@interface OBSMTLJSONAdapter (ValueTransformers)
 
/// Creates a reversible transformer to convert a JSON dictionary into a OBSMTLModel
/// object, and vice-versa.
///
/// modelClass - The OBSMTLModel subclass to attempt to parse from the JSON. This
///              class must conform to <OBSMTLJSONSerializing>. This argument must
///              not be nil.
///
/// Returns a reversible transformer which uses the class of the receiver for
/// transforming values back and forth.
+ (NSValueTransformer<OBSMTLTransformerErrorHandling> *)dictionaryTransformerWithModelClass:(Class)modelClass;
 
/// Creates a reversible transformer to convert an array of JSON dictionaries
/// into an array of OBSMTLModel objects, and vice-versa.
///
/// modelClass - The OBSMTLModel subclass to attempt to parse from each JSON
///              dictionary. This class must conform to <OBSMTLJSONSerializing>.
///              This argument must not be nil.
///
/// Returns a reversible transformer which uses the class of the receiver for
/// transforming array elements back and forth.
+ (NSValueTransformer<OBSMTLTransformerErrorHandling> *)arrayTransformerWithModelClass:(Class)modelClass;
 
/// This value transformer is used by OBSMTLJSONAdapter to automatically convert
/// NSURL properties to JSON strings and vice versa.
+ (NSValueTransformer *)NSURLJSONTransformer;
 
/// This value transformer is used by OBSMTLJSONAdapter to automatically convert
/// NSUUID properties to JSON strings and vice versa.
+ (NSValueTransformer *)NSUUIDJSONTransformer;
 
@end
 
@class OBSMTLModel;
 
@interface OBSMTLJSONAdapter (Deprecated)
 
@property (nonatomic, strong, readonly) id<OBSMTLJSONSerializing> model __attribute__((unavailable("Replaced by -modelFromJSONDictionary:error:")));
 
+ (NSArray *)JSONArrayFromModels:(NSArray *)models __attribute__((deprecated("Replaced by +JSONArrayFromModels:error:"))) NS_SWIFT_UNAVAILABLE("Replaced by +JSONArrayFromModels:error:");
 
+ (NSDictionary *)JSONDictionaryFromModel:(OBSMTLModel<OBSMTLJSONSerializing> *)model __attribute__((deprecated("Replaced by +JSONDictionaryFromModel:error:"))) NS_SWIFT_UNAVAILABLE("Replaced by +JSONDictionaryFromModel:error:");
 
- (NSDictionary *)JSONDictionary __attribute__((unavailable("Replaced by -JSONDictionaryFromModel:error:"))) NS_SWIFT_UNAVAILABLE("Replaced by -JSONDictionaryFromModel:error:");
- (NSString *)JSONKeyPathForPropertyKey:(NSString *)key __attribute__((unavailable("Replaced by -serializablePropertyKeys:forModel:")));
- (id)initWithJSONDictionary:(NSDictionary *)JSONDictionary modelClass:(Class)modelClass error:(NSError **)error __attribute__((unavailable("Replaced by -initWithModelClass:")));
- (id)initWithModel:(id<OBSMTLJSONSerializing>)model __attribute__((unavailable("Replaced by -initWithModelClass:"))) NS_SWIFT_UNAVAILABLE("Replaced by -initWithModelClass:");
- (NSDictionary *)serializeToJSONDictionary:(NSError **)error __attribute__((unavailable("Replaced by -JSONDictionaryFromModel:error:"))) NS_SWIFT_UNAVAILABLE("Replaced by -JSONDictionaryFromModel:error:");
 
@end