MTLModel.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. //
  2. // MTLModel.h
  3. // Mantle
  4. //
  5. // Created by Justin Spahr-Summers on 2012-09-11.
  6. // Copyright (c) 2012 GitHub. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. /// Defines a property's storage behavior, which affects how it will be copied,
  10. /// compared, and persisted.
  11. ///
  12. /// MTLPropertyStorageNone - This property is not included in -description,
  13. /// -hash, or anything else.
  14. /// MTLPropertyStorageTransitory - This property is included in one-off
  15. /// operations like -copy and -dictionaryValue but
  16. /// does not affect -isEqual: or -hash.
  17. /// It may disappear at any time.
  18. /// MTLPropertyStoragePermanent - The property is included in serialization
  19. /// (like `NSCoding`) and equality, since it can
  20. /// be expected to stick around.
  21. typedef enum : NSUInteger {
  22. MTLPropertyStorageNone,
  23. MTLPropertyStorageTransitory,
  24. MTLPropertyStoragePermanent,
  25. } MTLPropertyStorage;
  26. /// This protocol defines the minimal interface that classes need to implement to
  27. /// interact with Mantle adapters.
  28. ///
  29. /// It is intended for scenarios where inheriting from MTLModel is not feasible.
  30. /// However, clients are encouraged to subclass the MTLModel class if they can.
  31. ///
  32. /// Clients that wish to implement their own adapters should target classes
  33. /// conforming to this protocol rather than subclasses of MTLModel to ensure
  34. /// maximum compatibility.
  35. @protocol MTLModel <NSObject, NSCopying>
  36. /// Initializes a new instance of the receiver using key-value coding, setting
  37. /// the keys and values in the given dictionary.
  38. ///
  39. /// dictionaryValue - Property keys and values to set on the instance. Any NSNull
  40. /// values will be converted to nil before being used. KVC
  41. /// validation methods will automatically be invoked for all of
  42. /// the properties given.
  43. /// error - If not NULL, this may be set to any error that occurs
  44. /// (like a KVC validation error).
  45. ///
  46. /// Returns an initialized model object, or nil if validation failed.
  47. + (instancetype)modelWithDictionary:(NSDictionary *)dictionaryValue error:(NSError **)error;
  48. /// A dictionary representing the properties of the receiver.
  49. ///
  50. /// Combines the values corresponding to all +propertyKeys into a dictionary,
  51. /// with any nil values represented by NSNull.
  52. ///
  53. /// This property must never be nil.
  54. @property (nonatomic, copy, readonly) NSDictionary *dictionaryValue;
  55. /// Initializes the receiver using key-value coding, setting the keys and values
  56. /// in the given dictionary.
  57. ///
  58. /// Subclass implementations may override this method, calling the super
  59. /// implementation, in order to perform further processing and initialization
  60. /// after deserialization.
  61. ///
  62. /// dictionaryValue - Property keys and values to set on the receiver. Any NSNull
  63. /// values will be converted to nil before being used. KVC
  64. /// validation methods will automatically be invoked for all of
  65. /// the properties given. If nil, this method is equivalent to
  66. /// -init.
  67. /// error - If not NULL, this may be set to any error that occurs
  68. /// (like a KVC validation error).
  69. ///
  70. /// Returns an initialized model object, or nil if validation failed.
  71. - (instancetype)initWithDictionary:(NSDictionary *)dictionaryValue error:(NSError **)error;
  72. /// Merges the value of the given key on the receiver with the value of the same
  73. /// key from the given model object, giving precedence to the other model object.
  74. - (void)mergeValueForKey:(NSString *)key fromModel:(id<MTLModel>)model;
  75. /// Returns the keys for all @property declarations, except for `readonly`
  76. /// properties without ivars, or properties on MTLModel itself.
  77. + (NSSet *)propertyKeys;
  78. /// Validates the model.
  79. ///
  80. /// error - If not NULL, this may be set to any error that occurs during
  81. /// validation
  82. ///
  83. /// Returns YES if the model is valid, or NO if the validation failed.
  84. - (BOOL)validate:(NSError **)error;
  85. @end
  86. /// An abstract base class for model objects, using reflection to provide
  87. /// sensible default behaviors.
  88. ///
  89. /// The default implementations of <NSCopying>, -hash, and -isEqual: make use of
  90. /// the +propertyKeys method.
  91. @interface MTLModel : NSObject <MTLModel>
  92. /// Initializes the receiver using key-value coding, setting the keys and values
  93. /// in the given dictionary.
  94. ///
  95. /// dictionaryValue - Property keys and values to set on the receiver. Any NSNull
  96. /// values will be converted to nil before being used. KVC
  97. /// validation methods will automatically be invoked for all of
  98. /// the properties given. If nil, this method is equivalent to
  99. /// -init.
  100. /// error - If not NULL, this may be set to any error that occurs
  101. /// (like a KVC validation error).
  102. ///
  103. /// Returns an initialized model object, or nil if validation failed.
  104. - (instancetype)initWithDictionary:(NSDictionary *)dictionaryValue error:(NSError **)error;
  105. /// Initializes the receiver with default values.
  106. ///
  107. /// This is the designated initializer for this class.
  108. - (instancetype)init;
  109. /// By default, this method looks for a `-merge<Key>FromModel:` method on the
  110. /// receiver, and invokes it if found. If not found, and `model` is not nil, the
  111. /// value for the given key is taken from `model`.
  112. - (void)mergeValueForKey:(NSString *)key fromModel:(id<MTLModel>)model;
  113. /// Merges the values of the given model object into the receiver, using
  114. /// -mergeValueForKey:fromModel: for each key in +propertyKeys.
  115. ///
  116. /// `model` must be an instance of the receiver's class or a subclass thereof.
  117. - (void)mergeValuesForKeysFromModel:(id<MTLModel>)model;
  118. /// The storage behavior of a given key.
  119. ///
  120. /// The default implementation returns MTLPropertyStorageNone for properties that
  121. /// are readonly and not backed by an instance variable and
  122. /// MTLPropertyStoragePermanent otherwise.
  123. ///
  124. /// Subclasses can use this method to prevent MTLModel from resolving circular
  125. /// references by returning MTLPropertyStorageTransitory.
  126. ///
  127. /// Returns the storage behavior for a given key on the receiver.
  128. + (MTLPropertyStorage)storageBehaviorForPropertyWithKey:(NSString *)propertyKey;
  129. /// Compares the receiver with another object for equality.
  130. ///
  131. /// The default implementation is equivalent to comparing all properties of both
  132. /// models for which +storageBehaviorForPropertyWithKey: returns
  133. /// MTLPropertyStoragePermanent.
  134. ///
  135. /// Returns YES if the two models are considered equal, NO otherwise.
  136. - (BOOL)isEqual:(id)object;
  137. /// A string that describes the contents of the receiver.
  138. ///
  139. /// The default implementation is based on the receiver's class and all its
  140. /// properties for which +storageBehaviorForPropertyWithKey: returns
  141. /// MTLPropertyStoragePermanent.
  142. - (NSString *)description;
  143. @end
  144. /// Implements validation logic for MTLModel.
  145. @interface MTLModel (Validation)
  146. /// Validates the model.
  147. ///
  148. /// The default implementation simply invokes -validateValue:forKey:error: with
  149. /// all +propertyKeys and their current value. If -validateValue:forKey:error:
  150. /// returns a new value, the property is set to that new value.
  151. ///
  152. /// error - If not NULL, this may be set to any error that occurs during
  153. /// validation
  154. ///
  155. /// Returns YES if the model is valid, or NO if the validation failed.
  156. - (BOOL)validate:(NSError **)error;
  157. @end