RCTConvert.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /*
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. */
  7. #import <QuartzCore/QuartzCore.h>
  8. #import <UIKit/UIKit.h>
  9. #import <React/RCTAnimationType.h>
  10. #import <React/RCTBorderStyle.h>
  11. #import <React/RCTDefines.h>
  12. #import <React/RCTLog.h>
  13. #import <React/RCTPointerEvents.h>
  14. #import <React/RCTTextDecorationLineType.h>
  15. #import <yoga/Yoga.h>
  16. #if TARGET_OS_IPHONE && WEBKIT_IOS_10_APIS_AVAILABLE
  17. #import <WebKit/WebKit.h>
  18. #endif
  19. /**
  20. * This class provides a collection of conversion functions for mapping
  21. * JSON objects to native types and classes. These are useful when writing
  22. * custom RCTViewManager setter methods.
  23. */
  24. @interface RCTConvert : NSObject
  25. + (id)id:(id)json;
  26. + (BOOL)BOOL:(id)json;
  27. + (double)double:(id)json;
  28. + (float)float:(id)json;
  29. + (int)int:(id)json;
  30. + (int64_t)int64_t:(id)json;
  31. + (uint64_t)uint64_t:(id)json;
  32. + (NSInteger)NSInteger:(id)json;
  33. + (NSUInteger)NSUInteger:(id)json;
  34. + (NSArray *)NSArray:(id)json;
  35. + (NSDictionary *)NSDictionary:(id)json;
  36. + (NSString *)NSString:(id)json;
  37. + (NSNumber *)NSNumber:(id)json;
  38. + (NSSet *)NSSet:(id)json;
  39. + (NSData *)NSData:(id)json;
  40. + (NSIndexSet *)NSIndexSet:(id)json;
  41. + (NSURLRequestCachePolicy)NSURLRequestCachePolicy:(id)json;
  42. + (NSURL *)NSURL:(id)json;
  43. + (NSURLRequest *)NSURLRequest:(id)json;
  44. typedef NSURL RCTFileURL;
  45. + (RCTFileURL *)RCTFileURL:(id)json;
  46. + (NSDate *)NSDate:(id)json;
  47. + (NSLocale *)NSLocale:(id)json;
  48. + (NSTimeZone *)NSTimeZone:(id)json;
  49. + (NSTimeInterval)NSTimeInterval:(id)json;
  50. + (NSLineBreakMode)NSLineBreakMode:(id)json;
  51. + (NSTextAlignment)NSTextAlignment:(id)json;
  52. + (NSUnderlineStyle)NSUnderlineStyle:(id)json;
  53. + (NSWritingDirection)NSWritingDirection:(id)json;
  54. + (UITextAutocapitalizationType)UITextAutocapitalizationType:(id)json;
  55. + (UITextFieldViewMode)UITextFieldViewMode:(id)json;
  56. + (UIKeyboardType)UIKeyboardType:(id)json;
  57. + (UIKeyboardAppearance)UIKeyboardAppearance:(id)json;
  58. + (UIReturnKeyType)UIReturnKeyType:(id)json;
  59. #if !TARGET_OS_TV
  60. + (UIDataDetectorTypes)UIDataDetectorTypes:(id)json;
  61. #endif
  62. #if TARGET_OS_IPHONE && WEBKIT_IOS_10_APIS_AVAILABLE
  63. + (WKDataDetectorTypes)WKDataDetectorTypes:(id)json;
  64. #endif
  65. + (UIViewContentMode)UIViewContentMode:(id)json;
  66. #if !TARGET_OS_TV
  67. + (UIBarStyle)UIBarStyle:(id)json;
  68. #endif
  69. + (CGFloat)CGFloat:(id)json;
  70. + (CGPoint)CGPoint:(id)json;
  71. + (CGSize)CGSize:(id)json;
  72. + (CGRect)CGRect:(id)json;
  73. + (UIEdgeInsets)UIEdgeInsets:(id)json;
  74. + (CGLineCap)CGLineCap:(id)json;
  75. + (CGLineJoin)CGLineJoin:(id)json;
  76. + (CGAffineTransform)CGAffineTransform:(id)json;
  77. + (UIColor *)UIColor:(id)json;
  78. + (CGColorRef)CGColor:(id)json CF_RETURNS_NOT_RETAINED;
  79. + (YGValue)YGValue:(id)json;
  80. + (NSArray<NSArray *> *)NSArrayArray:(id)json;
  81. + (NSArray<NSString *> *)NSStringArray:(id)json;
  82. + (NSArray<NSArray<NSString *> *> *)NSStringArrayArray:(id)json;
  83. + (NSArray<NSDictionary *> *)NSDictionaryArray:(id)json;
  84. + (NSArray<NSURL *> *)NSURLArray:(id)json;
  85. + (NSArray<RCTFileURL *> *)RCTFileURLArray:(id)json;
  86. + (NSArray<NSNumber *> *)NSNumberArray:(id)json;
  87. + (NSArray<UIColor *> *)UIColorArray:(id)json;
  88. typedef NSArray CGColorArray;
  89. + (CGColorArray *)CGColorArray:(id)json;
  90. /**
  91. * Convert a JSON object to a Plist-safe equivalent by stripping null values.
  92. */
  93. typedef id NSPropertyList;
  94. + (NSPropertyList)NSPropertyList:(id)json;
  95. typedef BOOL css_backface_visibility_t;
  96. + (YGOverflow)YGOverflow:(id)json;
  97. + (YGDisplay)YGDisplay:(id)json;
  98. + (css_backface_visibility_t)css_backface_visibility_t:(id)json;
  99. + (YGFlexDirection)YGFlexDirection:(id)json;
  100. + (YGJustify)YGJustify:(id)json;
  101. + (YGAlign)YGAlign:(id)json;
  102. + (YGPositionType)YGPositionType:(id)json;
  103. + (YGWrap)YGWrap:(id)json;
  104. + (YGDirection)YGDirection:(id)json;
  105. + (RCTPointerEvents)RCTPointerEvents:(id)json;
  106. + (RCTAnimationType)RCTAnimationType:(id)json;
  107. + (RCTBorderStyle)RCTBorderStyle:(id)json;
  108. + (RCTTextDecorationLineType)RCTTextDecorationLineType:(id)json;
  109. @end
  110. @interface RCTConvert (Deprecated)
  111. /**
  112. * Use lightweight generics syntax instead, e.g. NSArray<NSString *>
  113. */
  114. typedef NSArray NSArrayArray __deprecated_msg("Use NSArray<NSArray *>");
  115. typedef NSArray NSStringArray __deprecated_msg("Use NSArray<NSString *>");
  116. typedef NSArray NSStringArrayArray __deprecated_msg("Use NSArray<NSArray<NSString *> *>");
  117. typedef NSArray NSDictionaryArray __deprecated_msg("Use NSArray<NSDictionary *>");
  118. typedef NSArray NSURLArray __deprecated_msg("Use NSArray<NSURL *>");
  119. typedef NSArray RCTFileURLArray __deprecated_msg("Use NSArray<RCTFileURL *>");
  120. typedef NSArray NSNumberArray __deprecated_msg("Use NSArray<NSNumber *>");
  121. typedef NSArray UIColorArray __deprecated_msg("Use NSArray<UIColor *>");
  122. /**
  123. * Synchronous image loading is generally a bad idea for performance reasons.
  124. * If you need to pass image references, try to use `RCTImageSource` and then
  125. * `RCTImageLoader` instead of converting directly to a UIImage.
  126. */
  127. + (UIImage *)UIImage:(id)json;
  128. + (CGImageRef)CGImage:(id)json CF_RETURNS_NOT_RETAINED;
  129. @end
  130. /**
  131. * Underlying implementations of RCT_XXX_CONVERTER macros. Ignore these.
  132. */
  133. RCT_EXTERN NSNumber *RCTConvertEnumValue(const char *, NSDictionary *, NSNumber *, id);
  134. RCT_EXTERN NSNumber *RCTConvertMultiEnumValue(const char *, NSDictionary *, NSNumber *, id);
  135. RCT_EXTERN NSArray *RCTConvertArrayValue(SEL, id);
  136. /**
  137. * This macro is used for logging conversion errors. This is just used to
  138. * avoid repeating the same boilerplate for every error message.
  139. */
  140. #define RCTLogConvertError(json, typeName) \
  141. RCTLogError(@"JSON value '%@' of type %@ cannot be converted to %@", json, [json classForCoder], typeName)
  142. /**
  143. * This macro is used for creating simple converter functions that just call
  144. * the specified getter method on the json value.
  145. */
  146. #define RCT_CONVERTER(type, name, getter) RCT_CUSTOM_CONVERTER(type, name, [json getter])
  147. /**
  148. * This macro is used for creating converter functions with arbitrary logic.
  149. */
  150. #define RCT_CUSTOM_CONVERTER(type, name, code) \
  151. +(type)name : (id)json RCT_DYNAMIC \
  152. { \
  153. if (!RCT_DEBUG) { \
  154. return code; \
  155. } else { \
  156. @try { \
  157. return code; \
  158. } @catch (__unused NSException * e) { \
  159. RCTLogConvertError(json, @ #type); \
  160. json = nil; \
  161. return code; \
  162. } \
  163. } \
  164. }
  165. /**
  166. * This macro is similar to RCT_CONVERTER, but specifically geared towards
  167. * numeric types. It will handle string input correctly, and provides more
  168. * detailed error reporting if an invalid value is passed in.
  169. */
  170. #define RCT_NUMBER_CONVERTER(type, getter) \
  171. RCT_CUSTOM_CONVERTER(type, type, [RCT_DEBUG ? [self NSNumber:json] : json getter])
  172. /**
  173. * When using RCT_ENUM_CONVERTER in ObjC, the compiler is OK with us returning
  174. * the underlying NSInteger/NSUInteger. In ObjC++, this is a type mismatch and
  175. * we need to explicitly cast the return value to expected enum return type.
  176. */
  177. #ifdef __cplusplus
  178. #define _RCT_CAST(type, expr) static_cast<type>(expr)
  179. #else
  180. #define _RCT_CAST(type, expr) expr
  181. #endif
  182. /**
  183. * This macro is used for creating converters for enum types.
  184. */
  185. #define RCT_ENUM_CONVERTER(type, values, default, getter) \
  186. +(type)type : (id)json RCT_DYNAMIC \
  187. { \
  188. static NSDictionary *mapping; \
  189. static dispatch_once_t onceToken; \
  190. dispatch_once(&onceToken, ^{ \
  191. mapping = values; \
  192. }); \
  193. return _RCT_CAST(type, [RCTConvertEnumValue(#type, mapping, @(default), json) getter]); \
  194. }
  195. /**
  196. * This macro is used for creating converters for enum types for
  197. * multiple enum values combined with | operator
  198. */
  199. #define RCT_MULTI_ENUM_CONVERTER(type, values, default, getter) \
  200. +(type)type : (id)json RCT_DYNAMIC \
  201. { \
  202. static NSDictionary *mapping; \
  203. static dispatch_once_t onceToken; \
  204. dispatch_once(&onceToken, ^{ \
  205. mapping = values; \
  206. }); \
  207. return _RCT_CAST(type, [RCTConvertMultiEnumValue(#type, mapping, @(default), json) getter]); \
  208. }
  209. /**
  210. * This macro is used for creating explicitly-named converter functions
  211. * for typed arrays.
  212. */
  213. #define RCT_ARRAY_CONVERTER_NAMED(type, name) \
  214. +(NSArray<type *> *)name##Array : (id)json RCT_DYNAMIC \
  215. { \
  216. return RCTConvertArrayValue(@selector(name:), json); \
  217. }
  218. /**
  219. * This macro is used for creating converter functions for typed arrays.
  220. * RCT_ARRAY_CONVERTER_NAMED may be used when type contains characters
  221. * which are disallowed in selector names.
  222. */
  223. #define RCT_ARRAY_CONVERTER(type) RCT_ARRAY_CONVERTER_NAMED(type, type)