BTJSON.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. #import <Foundation/Foundation.h>
  2. NS_ASSUME_NONNULL_BEGIN
  3. /**
  4. Domain for JSON errors.
  5. */
  6. extern NSString * const BTJSONErrorDomain;
  7. /**
  8. Error codes associated with `BTJSON`.
  9. */
  10. typedef NS_ENUM(NSInteger, BTJSONErrorCode) {
  11. /// Unknown value
  12. BTJSONErrorValueUnknown = 0,
  13. /// Invalid value
  14. BTJSONErrorValueInvalid = 1,
  15. /// Invalid access
  16. BTJSONErrorAccessInvalid = 2,
  17. };
  18. /**
  19. A type-safe wrapper around JSON
  20. @see http://www.json.org/
  21. The primary goal of this class is to two-fold: (1) prevent bugs by staying true to JSON (json.org)
  22. rather than interpreting it in mysterious ways; (2) prevent bugs by making JSON interpretation
  23. as un-surprising as possible.
  24. Most notably, type casting occurs via the as* nullable methods; errors are deferred and can be checked explicitly using isError and asError.
  25. ## Example Data:
  26. ```
  27. {
  28. "foo": "bar",
  29. "baz": [1, 2, 3]
  30. }
  31. ```
  32. ## Example Usage:
  33. ```
  34. let json : BTJSON = BTJSON(data:data);
  35. json.isError // false
  36. json.isObject // true
  37. json.isNumber // false
  38. json.asObject // self
  39. json["foo"] // JSON(@"bar")
  40. json["foo"].isString // true
  41. json["foo"].asString // @"bar"
  42. json["baz"].asString // null
  43. json["baz"]["quux"].isError // true
  44. json["baz"]["quux"].asError // NSError(domain: BTJSONErrorDomain, code: BTJSONErrorCodeTypeInvalid)
  45. json["baz"][0].asError // null
  46. json["baz"][0].asInteger //
  47. json["random"]["nested"]["things"][3].isError // true
  48. let json : BTJSON = BTJSON() // json.asJson => {}
  49. json["foo"][0] = "bar" // json.asJSON => { "foo": ["bar"] }
  50. json["baz"] = [ 1, 2, 3 ] // json.asJSON => { "foo": ["bar"], "baz": [1,2,3] }
  51. json["quux"] = NSSet() // json.isError => true, json.asJSON => throws NSError(domain: BTJSONErrorDomain, code: BTJSONErrorInvalidData)
  52. ```
  53. */
  54. @interface BTJSON : NSObject
  55. /**
  56. Designated initializer.
  57. */
  58. - (instancetype)init NS_DESIGNATED_INITIALIZER;
  59. /**
  60. Initialize with a value.
  61. @param value The value to initialize with.
  62. */
  63. - (instancetype)initWithValue:(id)value;
  64. /**
  65. Initialize with a data.
  66. @param data The `NSData` to initialize with.
  67. */
  68. - (instancetype)initWithData:(NSData *)data;
  69. /// Subscripting
  70. /**
  71. Indexes into the JSON as if the current value is an object
  72. Notably, this method will always return successfully; however, if the value is not an object, the JSON will wrap an error.
  73. */
  74. - (id)objectForKeyedSubscript:(NSString *)key;
  75. /**
  76. Indexes into the JSON as if the current value is an array
  77. Notably, this method will always return successfully; however, if the value is not an array, the JSON will wrap an error.
  78. */
  79. - (BTJSON *)objectAtIndexedSubscript:(NSUInteger)idx;
  80. /// Validity Checks
  81. /**
  82. True if this instance of BTJSON is not valid.
  83. */
  84. @property (nonatomic, assign, readonly) BOOL isError;
  85. /**
  86. The BTJSON as `NSError`.
  87. @return An `NSError` representing the BTJSON instance.
  88. */
  89. - (nullable NSError *)asError;
  90. /// Generating JSON
  91. /**
  92. The BTJSON as `NSData`.
  93. @param error Used if there is an issue parsing.
  94. @return An `NSData` representing the BTJSON instance.
  95. */
  96. - (nullable NSData *)asJSONAndReturnError:(NSError **)error;
  97. /**
  98. The BTJSON as a pretty string.
  99. @param error Used if there is an issue parsing.
  100. @return An `NSString` representing the BTJSON instance.
  101. */
  102. - (nullable NSString *)asPrettyJSONAndReturnError:(NSError **)error;
  103. /// JSON Type Casts
  104. /**
  105. The BTJSON as `NSString`.
  106. @return An `NSString` representing the BTJSON instance.
  107. */
  108. - (nullable NSString *)asString;
  109. /**
  110. The BTJSON as `NSArray<BTJSON *>`.
  111. @return An `NSArray<BTJSON *>` representing the BTJSON instance.
  112. */
  113. - (nullable NSArray<BTJSON *> *)asArray;
  114. /**
  115. The BTJSON as `NSDecimalNumber`.
  116. @return An `NSDecimalNumber` representing the BTJSON instance.
  117. */
  118. - (nullable NSDecimalNumber *)asNumber;
  119. /// JSON Extension Type Casts
  120. /**
  121. The BTJSON as `NSURL`.
  122. @return An `NSURL` representing the BTJSON instance.
  123. */
  124. - (nullable NSURL *)asURL;
  125. /**
  126. The BTJSON as `NSArray<NSString *>`.
  127. @return An `NSArray<NSString *>` representing the BTJSON instance.
  128. */
  129. - (nullable NSArray<NSString *> *)asStringArray;
  130. /**
  131. The BTJSON as `NSDictionary`.
  132. @return An `NSDictionary` representing the BTJSON instance.
  133. */
  134. - (nullable NSDictionary *)asDictionary;
  135. /**
  136. The BTJSON as `NSInteger`. Zero will be returned if not a valid number.
  137. @return An `NSInteger` representing the BTJSON instance.
  138. */
  139. - (NSInteger)asIntegerOrZero;
  140. /**
  141. The BTJSON as Enum.
  142. @param mapping The mapping dictionary to used to convert the value.
  143. @param defaultValue The default value if conversion fails.
  144. @return An Enum representing the BTJSON instance.
  145. */
  146. - (NSInteger)asEnum:(NSDictionary *)mapping orDefault:(NSInteger)defaultValue;
  147. /// JSON Type Checks
  148. /**
  149. True if this instance of BTJSON is a valid string.
  150. */
  151. @property (nonatomic, assign, readonly) BOOL isString;
  152. /**
  153. True if this instance of BTJSON is a valid number.
  154. */
  155. @property (nonatomic, assign, readonly) BOOL isNumber;
  156. /**
  157. True if this instance of BTJSON is a valid array.
  158. */
  159. @property (nonatomic, assign, readonly) BOOL isArray;
  160. /**
  161. True if this instance of BTJSON is a valid object.
  162. */
  163. @property (nonatomic, assign, readonly) BOOL isObject;
  164. /**
  165. True if this instance of BTJSON is a boolean.
  166. */
  167. @property (nonatomic, assign, readonly) BOOL isBool;
  168. /**
  169. True if this instance of BTJSON is a value representing `true`.
  170. */
  171. @property (nonatomic, assign, readonly) BOOL isTrue;
  172. /**
  173. True if this instance of BTJSON is a value representing `false`.
  174. */
  175. @property (nonatomic, assign, readonly) BOOL isFalse;
  176. /**
  177. True if this instance of BTJSON is `null`.
  178. */
  179. @property (nonatomic, assign, readonly) BOOL isNull;
  180. @end
  181. NS_ASSUME_NONNULL_END