1 /*
2  * Copyright (c) Meta Platforms, Inc. and 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 
8 #import <QuartzCore/QuartzCore.h>
9 #import <UIKit/UIKit.h>
10 
11 #import <ABI49_0_0React/ABI49_0_0RCTAnimationType.h>
12 #import <ABI49_0_0React/ABI49_0_0RCTBorderCurve.h>
13 #import <ABI49_0_0React/ABI49_0_0RCTBorderStyle.h>
14 #import <ABI49_0_0React/ABI49_0_0RCTDefines.h>
15 #import <ABI49_0_0React/ABI49_0_0RCTLog.h>
16 #import <ABI49_0_0React/ABI49_0_0RCTPointerEvents.h>
17 #import <ABI49_0_0React/ABI49_0_0RCTTextDecorationLineType.h>
18 #import <ABI49_0_0yoga/ABI49_0_0Yoga.h>
19 #if TARGET_OS_IPHONE
20 #import <WebKit/WebKit.h>
21 #endif
22 
23 /**
24  * This class provides a collection of conversion functions for mapping
25  * JSON objects to native types and classes. These are useful when writing
26  * custom ABI49_0_0RCTViewManager setter methods.
27  */
28 @interface ABI49_0_0RCTConvert : NSObject
29 
30 + (id)id:(id)json;
31 
32 + (BOOL)BOOL:(id)json;
33 + (double)double:(id)json;
34 + (float)float:(id)json;
35 + (int)int:(id)json;
36 
37 + (int64_t)int64_t:(id)json;
38 + (uint64_t)uint64_t:(id)json;
39 
40 + (NSInteger)NSInteger:(id)json;
41 + (NSUInteger)NSUInteger:(id)json;
42 
43 + (NSArray *)NSArray:(id)json;
44 + (NSDictionary *)NSDictionary:(id)json;
45 + (NSString *)NSString:(id)json;
46 + (NSNumber *)NSNumber:(id)json;
47 
48 + (NSSet *)NSSet:(id)json;
49 + (NSData *)NSData:(id)json;
50 + (NSIndexSet *)NSIndexSet:(id)json;
51 
52 + (NSURLRequestCachePolicy)NSURLRequestCachePolicy:(id)json;
53 + (NSURL *)NSURL:(id)json;
54 + (NSURLRequest *)NSURLRequest:(id)json;
55 
56 typedef NSURL ABI49_0_0RCTFileURL;
57 + (ABI49_0_0RCTFileURL *)ABI49_0_0RCTFileURL:(id)json;
58 
59 + (NSDate *)NSDate:(id)json;
60 + (NSLocale *)NSLocale:(id)json;
61 + (NSTimeZone *)NSTimeZone:(id)json;
62 + (NSTimeInterval)NSTimeInterval:(id)json;
63 
64 + (NSLineBreakMode)NSLineBreakMode:(id)json;
65 + (NSTextAlignment)NSTextAlignment:(id)json;
66 + (NSUnderlineStyle)NSUnderlineStyle:(id)json;
67 + (NSWritingDirection)NSWritingDirection:(id)json;
68 + (NSLineBreakStrategy)NSLineBreakStrategy:(id)json;
69 + (UITextAutocapitalizationType)UITextAutocapitalizationType:(id)json;
70 + (UITextFieldViewMode)UITextFieldViewMode:(id)json;
71 + (UIKeyboardType)UIKeyboardType:(id)json;
72 + (UIKeyboardAppearance)UIKeyboardAppearance:(id)json;
73 + (UIReturnKeyType)UIReturnKeyType:(id)json;
74 + (UIUserInterfaceStyle)UIUserInterfaceStyle:(id)json API_AVAILABLE(ios(12));
75 #if !TARGET_OS_TV
76 + (UIDataDetectorTypes)UIDataDetectorTypes:(id)json;
77 #endif
78 
79 #if TARGET_OS_IPHONE
80 + (WKDataDetectorTypes)WKDataDetectorTypes:(id)json;
81 #endif
82 
83 + (UIViewContentMode)UIViewContentMode:(id)json;
84 #if !TARGET_OS_TV
85 + (UIBarStyle)UIBarStyle:(id)json;
86 #endif
87 
88 + (CGFloat)CGFloat:(id)json;
89 + (CGPoint)CGPoint:(id)json;
90 + (CGSize)CGSize:(id)json;
91 + (CGRect)CGRect:(id)json;
92 + (UIEdgeInsets)UIEdgeInsets:(id)json;
93 
94 + (CGLineCap)CGLineCap:(id)json;
95 + (CGLineJoin)CGLineJoin:(id)json;
96 
97 + (CGAffineTransform)CGAffineTransform:(id)json;
98 
99 + (UIColor *)UIColor:(id)json;
100 + (CGColorRef)CGColor:(id)json CF_RETURNS_NOT_RETAINED;
101 
102 + (ABI49_0_0YGValue)ABI49_0_0YGValue:(id)json;
103 
104 + (NSArray<NSArray *> *)NSArrayArray:(id)json;
105 + (NSArray<NSString *> *)NSStringArray:(id)json;
106 + (NSArray<NSArray<NSString *> *> *)NSStringArrayArray:(id)json;
107 + (NSArray<NSDictionary *> *)NSDictionaryArray:(id)json;
108 + (NSArray<NSURL *> *)NSURLArray:(id)json;
109 + (NSArray<ABI49_0_0RCTFileURL *> *)ABI49_0_0RCTFileURLArray:(id)json;
110 + (NSArray<NSNumber *> *)NSNumberArray:(id)json;
111 + (NSArray<UIColor *> *)UIColorArray:(id)json;
112 
113 typedef NSArray CGColorArray;
114 + (CGColorArray *)CGColorArray:(id)json;
115 
116 /**
117  * Convert a JSON object to a Plist-safe equivalent by stripping null values.
118  */
119 typedef id NSPropertyList;
120 + (NSPropertyList)NSPropertyList:(id)json;
121 
122 typedef BOOL css_backface_visibility_t;
123 + (ABI49_0_0YGOverflow)ABI49_0_0YGOverflow:(id)json;
124 + (ABI49_0_0YGDisplay)ABI49_0_0YGDisplay:(id)json;
125 + (css_backface_visibility_t)css_backface_visibility_t:(id)json;
126 + (ABI49_0_0YGFlexDirection)ABI49_0_0YGFlexDirection:(id)json;
127 + (ABI49_0_0YGJustify)ABI49_0_0YGJustify:(id)json;
128 + (ABI49_0_0YGAlign)ABI49_0_0YGAlign:(id)json;
129 + (ABI49_0_0YGPositionType)ABI49_0_0YGPositionType:(id)json;
130 + (ABI49_0_0YGWrap)ABI49_0_0YGWrap:(id)json;
131 + (ABI49_0_0YGDirection)ABI49_0_0YGDirection:(id)json;
132 
133 + (ABI49_0_0RCTPointerEvents)ABI49_0_0RCTPointerEvents:(id)json;
134 + (ABI49_0_0RCTAnimationType)ABI49_0_0RCTAnimationType:(id)json;
135 + (ABI49_0_0RCTBorderStyle)ABI49_0_0RCTBorderStyle:(id)json;
136 + (ABI49_0_0RCTBorderCurve)ABI49_0_0RCTBorderCurve:(id)json;
137 + (ABI49_0_0RCTTextDecorationLineType)ABI49_0_0RCTTextDecorationLineType:(id)json;
138 
139 @end
140 
141 @interface ABI49_0_0RCTConvert (Deprecated)
142 
143 /**
144  * Use lightweight generics syntax instead, e.g. NSArray<NSString *>
145  */
146 typedef NSArray NSArrayArray __deprecated_msg("Use NSArray<NSArray *>");
147 typedef NSArray NSStringArray __deprecated_msg("Use NSArray<NSString *>");
148 typedef NSArray NSStringArrayArray __deprecated_msg("Use NSArray<NSArray<NSString *> *>");
149 typedef NSArray NSDictionaryArray __deprecated_msg("Use NSArray<NSDictionary *>");
150 typedef NSArray NSURLArray __deprecated_msg("Use NSArray<NSURL *>");
151 typedef NSArray ABI49_0_0RCTFileURLArray __deprecated_msg("Use NSArray<ABI49_0_0RCTFileURL *>");
152 typedef NSArray NSNumberArray __deprecated_msg("Use NSArray<NSNumber *>");
153 typedef NSArray UIColorArray __deprecated_msg("Use NSArray<UIColor *>");
154 
155 /**
156  * Synchronous image loading is generally a bad idea for performance reasons.
157  * If you need to pass image references, try to use `ABI49_0_0RCTImageSource` and then
158  * `ABI49_0_0RCTImageLoader` instead of converting directly to a UIImage.
159  */
160 + (UIImage *)UIImage:(id)json;
161 + (CGImageRef)CGImage:(id)json CF_RETURNS_NOT_RETAINED;
162 
163 @end
164 
165 /**
166  * Underlying implementations of ABI49_0_0RCT_XXX_CONVERTER macros. Ignore these.
167  */
168 ABI49_0_0RCT_EXTERN NSNumber *ABI49_0_0RCTConvertEnumValue(const char *, NSDictionary *, NSNumber *, id);
169 ABI49_0_0RCT_EXTERN NSNumber *ABI49_0_0RCTConvertMultiEnumValue(const char *, NSDictionary *, NSNumber *, id);
170 ABI49_0_0RCT_EXTERN NSArray *ABI49_0_0RCTConvertArrayValue(SEL, id);
171 
172 /**
173  * This macro is used for logging conversion errors. This is just used to
174  * avoid repeating the same boilerplate for every error message.
175  */
176 #define ABI49_0_0RCTLogConvertError(json, typeName) \
177   ABI49_0_0RCTLogInfo(@"JSON value '%@' of type %@ cannot be converted to %@", json, [json classForCoder], typeName)
178 
179 /**
180  * This macro is used for creating simple converter functions that just call
181  * the specified getter method on the json value.
182  */
183 #define ABI49_0_0RCT_CONVERTER(type, name, getter) ABI49_0_0RCT_CUSTOM_CONVERTER(type, name, [json getter])
184 
185 /**
186  * This macro is used for creating converter functions with arbitrary logic.
187  */
188 #define ABI49_0_0RCT_CUSTOM_CONVERTER(type, name, code) \
189   +(type)name : (id)json ABI49_0_0RCT_DYNAMIC           \
190   {                                            \
191     if (!ABI49_0_0RCT_DEBUG) {                          \
192       return code;                             \
193     } else {                                   \
194       @try {                                   \
195         return code;                           \
196       } @catch (__unused NSException * e) {    \
197         ABI49_0_0RCTLogConvertError(json, @ #type);     \
198         json = nil;                            \
199         return code;                           \
200       }                                        \
201     }                                          \
202   }
203 
204 /**
205  * This macro is similar to ABI49_0_0RCT_CONVERTER, but specifically geared towards
206  * numeric types. It will handle string input correctly, and provides more
207  * detailed error reporting if an invalid value is passed in.
208  */
209 #define ABI49_0_0RCT_NUMBER_CONVERTER(type, getter) \
210   ABI49_0_0RCT_CUSTOM_CONVERTER(type, type, [ABI49_0_0RCT_DEBUG ? [self NSNumber:json] : json getter])
211 
212 /**
213  * When using ABI49_0_0RCT_ENUM_CONVERTER in ObjC, the compiler is OK with us returning
214  * the underlying NSInteger/NSUInteger. In ObjC++, this is a type mismatch and
215  * we need to explicitly cast the return value to expected enum return type.
216  */
217 #ifdef __cplusplus
218 #define _ABI49_0_0RCT_CAST(type, expr) static_cast<type>(expr)
219 #else
220 #define _ABI49_0_0RCT_CAST(type, expr) expr
221 #endif
222 
223 /**
224  * This macro is used for creating converters for enum types.
225  */
226 #define ABI49_0_0RCT_ENUM_CONVERTER(type, values, default, getter)                                   \
227   +(type)type : (id)json ABI49_0_0RCT_DYNAMIC                                                        \
228   {                                                                                         \
229     static NSDictionary *mapping;                                                           \
230     static dispatch_once_t onceToken;                                                       \
231     dispatch_once(&onceToken, ^{                                                            \
232       mapping = values;                                                                     \
233     });                                                                                     \
234     return _ABI49_0_0RCT_CAST(type, [ABI49_0_0RCTConvertEnumValue(#type, mapping, @(default), json) getter]); \
235   }
236 
237 /**
238  * This macro is used for creating converters for enum types for
239  * multiple enum values combined with | operator
240  */
241 #define ABI49_0_0RCT_MULTI_ENUM_CONVERTER(type, values, default, getter)                                  \
242   +(type)type : (id)json ABI49_0_0RCT_DYNAMIC                                                             \
243   {                                                                                              \
244     static NSDictionary *mapping;                                                                \
245     static dispatch_once_t onceToken;                                                            \
246     dispatch_once(&onceToken, ^{                                                                 \
247       mapping = values;                                                                          \
248     });                                                                                          \
249     return _ABI49_0_0RCT_CAST(type, [ABI49_0_0RCTConvertMultiEnumValue(#type, mapping, @(default), json) getter]); \
250   }
251 
252 /**
253  * This macro is used for creating explicitly-named converter functions
254  * for typed arrays.
255  */
256 #define ABI49_0_0RCT_ARRAY_CONVERTER_NAMED(type, name)            \
257   +(NSArray<type *> *)name##Array : (id)json ABI49_0_0RCT_DYNAMIC \
258   {                                                      \
259     return ABI49_0_0RCTConvertArrayValue(@selector(name:), json); \
260   }
261 
262 /**
263  * This macro is used for creating converter functions for typed arrays.
264  * ABI49_0_0RCT_ARRAY_CONVERTER_NAMED may be used when type contains characters
265  * which are disallowed in selector names.
266  */
267 #define ABI49_0_0RCT_ARRAY_CONVERTER(type) ABI49_0_0RCT_ARRAY_CONVERTER_NAMED(type, type)
268