1 import UIKit 2 3 /** 4 Extends all modules with the functions used to build a module definition. 5 Unfortunately they need to be scoped here, but hopefully this proposal 6 https://github.com/apple/swift-evolution/blob/main/proposals/0289-result-builders.md#builder-scoped-name-lookup 7 will be implemented in the future. 8 */ 9 extension AnyModule { 10 // MARK: - Module name 11 12 /** 13 Sets the name of the module that is exported to the JavaScript world. 14 */ 15 public func name(_ name: String) -> AnyDefinition { 16 return ModuleNameDefinition(name: name) 17 } 18 19 // MARK: - Constants 20 21 /** 22 Definition function setting the module's constants to export. 23 */ 24 public func constants(_ closure: () -> [String : Any?]) -> AnyDefinition { 25 return ConstantsDefinition(constants: closure()) 26 } 27 28 // MARK: - Methods 29 30 /** 31 Factory function for methods without arguments. 32 */ 33 public func method<R>( 34 _ name: String, 35 _ closure: @escaping () -> R 36 ) -> AnyMethod { 37 return ConcreteMethod( 38 name, 39 argTypes: [], 40 closure 41 ) 42 } 43 44 /** 45 Factory function for methods with one argument. 46 */ 47 public func method<R, A0: AnyMethodArgument>( 48 _ name: String, 49 _ closure: @escaping (A0) -> R 50 ) -> AnyMethod { 51 return ConcreteMethod( 52 name, 53 argTypes: [AnyArgumentType(A0.self)], 54 closure 55 ) 56 } 57 58 /** 59 Factory function for methods with 2 arguments. 60 */ 61 public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument>( 62 _ name: String, 63 _ closure: @escaping (A0, A1) -> R 64 ) -> AnyMethod { 65 return ConcreteMethod( 66 name, 67 argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self)], 68 closure 69 ) 70 } 71 72 /** 73 Factory function for methods with 3 arguments. 74 */ 75 public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument>( 76 _ name: String, 77 _ closure: @escaping (A0, A1, A2) -> R 78 ) -> AnyMethod { 79 return ConcreteMethod( 80 name, 81 argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self)], 82 closure 83 ) 84 } 85 86 /** 87 Factory function for methods with 4 arguments. 88 */ 89 public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument>( 90 _ name: String, 91 _ closure: @escaping (A0, A1, A2, A3) -> R 92 ) -> AnyMethod { 93 return ConcreteMethod( 94 name, 95 argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self)], 96 closure 97 ) 98 } 99 100 /** 101 Factory function for methods with 5 arguments. 102 */ 103 public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument>( 104 _ name: String, 105 _ closure: @escaping (A0, A1, A2, A3, A4) -> R 106 ) -> AnyMethod { 107 return ConcreteMethod( 108 name, 109 argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self), AnyArgumentType(A4.self)], 110 closure 111 ) 112 } 113 114 /** 115 Factory function for methods with 6 arguments. 116 */ 117 public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument, A5: AnyMethodArgument>( 118 _ name: String, 119 _ closure: @escaping (A0, A1, A2, A3, A4, A5) -> R 120 ) -> AnyMethod { 121 return ConcreteMethod( 122 name, 123 argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self), AnyArgumentType(A4.self), AnyArgumentType(A5.self)], 124 closure 125 ) 126 } 127 128 /** 129 Factory function for methods with 7 arguments. 130 */ 131 public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument, A5: AnyMethodArgument, A6: AnyMethodArgument>( 132 _ name: String, 133 _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6) -> R 134 ) -> AnyMethod { 135 return ConcreteMethod( 136 name, 137 argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self), AnyArgumentType(A4.self), AnyArgumentType(A5.self), AnyArgumentType(A6.self)], 138 closure 139 ) 140 } 141 142 /** 143 Factory function for methods with 8 arguments. 144 */ 145 public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument, A5: AnyMethodArgument, A6: AnyMethodArgument, A7: AnyMethodArgument>( 146 _ name: String, 147 _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6, A7) -> R 148 ) -> AnyMethod { 149 return ConcreteMethod( 150 name, 151 argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self), AnyArgumentType(A4.self), AnyArgumentType(A5.self), AnyArgumentType(A6.self), AnyArgumentType(A7.self)], 152 closure 153 ) 154 } 155 156 // MARK: - Module's lifecycle 157 158 /** 159 Creates module's lifecycle listener that is called right after module initialization. 160 */ 161 public func onCreate(_ closure: @escaping () -> Void) -> AnyDefinition { 162 return EventListener(.moduleCreate, closure) 163 } 164 165 /** 166 Creates module's lifecycle listener that is called when the module is about to be deallocated. 167 */ 168 public func onDestroy(_ closure: @escaping () -> Void) -> AnyDefinition { 169 return EventListener(.moduleDestroy, closure) 170 } 171 172 /** 173 Creates module's lifecycle listener that is called when the app context owning the module is about to be deallocated. 174 */ 175 public func onAppContextDestroys(_ closure: @escaping () -> Void) -> AnyDefinition { 176 return EventListener(.appContextDestroys, closure) 177 } 178 179 /** 180 Creates a listener that is called when the app is about to enter the foreground mode. 181 */ 182 public func onAppEntersForeground(_ closure: @escaping () -> Void) -> AnyDefinition { 183 return EventListener(.appEntersForeground, closure) 184 } 185 186 /** 187 Creates a listener that is called when the app becomes active again. 188 */ 189 public func onAppBecomesActive(_ closure: @escaping () -> Void) -> AnyDefinition { 190 return EventListener(.appBecomesActive, closure) 191 } 192 193 /** 194 Creates a listener that is called when the app enters the background mode. 195 */ 196 public func onAppEntersBackground(_ closure: @escaping () -> Void) -> AnyDefinition { 197 return EventListener(.appEntersBackground, closure) 198 } 199 200 // MARK: - View Manager 201 202 /** 203 Creates the view manager definition that scopes other view-related definitions. 204 */ 205 public func viewManager(@ViewManagerDefinitionBuilder _ closure: @escaping () -> ViewManagerDefinition) -> AnyDefinition { 206 return closure() 207 } 208 209 // MARK: - Events 210 211 /** 212 Defines event names that this module can send to JavaScript. 213 */ 214 public func events(_ names: String...) -> AnyDefinition { 215 return EventsDefinition(names: names) 216 } 217 218 /** 219 Method that is invoked when the first event listener is added. 220 */ 221 public func onStartObserving(_ body: @escaping () -> ()) -> AnyMethod { 222 return ConcreteMethod("startObserving", argTypes: [], body) 223 } 224 225 /** 226 Method that is invoked when all event listeners are removed. 227 */ 228 public func onStopObserving(_ body: @escaping () -> ()) -> AnyMethod { 229 return ConcreteMethod("stopObserving", argTypes: [], body) 230 } 231 } 232 233 /** 234 Defines the factory creating a native view when the module is used as a view. 235 */ 236 public func view(_ closure: @escaping () -> UIView) -> AnyDefinition { 237 return ViewFactory(closure) 238 } 239 240 /** 241 Creates a view prop that defines its name and setter. 242 */ 243 public func prop<ViewType: UIView, PropType>(_ name: String, _ setter: @escaping (ViewType, PropType) -> Void) -> AnyDefinition { 244 return ConcreteViewProp(name, setter) 245 } 246