expo-modules-core 0.4.8 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/CHANGELOG.md +14 -1
  2. package/android/build.gradle +30 -2
  3. package/android/src/main/java/expo/modules/adapters/react/ModuleRegistryAdapter.java +27 -5
  4. package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +49 -5
  5. package/android/src/main/java/expo/modules/core/BasePackage.java +6 -0
  6. package/android/src/main/java/expo/modules/core/ModulePriorities.kt +25 -0
  7. package/android/src/main/java/expo/modules/core/interfaces/ActivityEventListener.java +3 -1
  8. package/android/src/main/java/expo/modules/core/interfaces/Package.java +4 -0
  9. package/android/src/main/java/expo/modules/core/interfaces/ReactActivityHandler.kt +18 -0
  10. package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.kt +14 -0
  11. package/android/src/main/java/expo/modules/core/utilities/KotlinUtilities.kt +23 -0
  12. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +166 -0
  13. package/android/src/main/java/expo/modules/kotlin/DynamicExtenstions.kt +9 -0
  14. package/android/src/main/java/expo/modules/kotlin/ExpoModulesHelper.kt +18 -0
  15. package/android/src/main/java/expo/modules/kotlin/KPromiseWrapper.kt +23 -0
  16. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +98 -0
  17. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +41 -0
  18. package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +56 -0
  19. package/android/src/main/java/expo/modules/kotlin/ModulesProvider.kt +7 -0
  20. package/android/src/main/java/expo/modules/kotlin/Promise.kt +13 -0
  21. package/android/src/main/java/expo/modules/kotlin/ReactLifecycleDelegate.kt +39 -0
  22. package/android/src/main/java/expo/modules/kotlin/ReadableArrayIterator.kt +14 -0
  23. package/android/src/main/java/expo/modules/kotlin/ReadableTypeExtensions.kt +18 -0
  24. package/android/src/main/java/expo/modules/kotlin/allocators/ObjectConstructor.kt +5 -0
  25. package/android/src/main/java/expo/modules/kotlin/allocators/ObjectConstructorFactory.kt +31 -0
  26. package/android/src/main/java/expo/modules/kotlin/allocators/UnsafeAllocator.kt +49 -0
  27. package/android/src/main/java/expo/modules/kotlin/events/EventListener.kt +39 -0
  28. package/android/src/main/java/expo/modules/kotlin/events/EventName.kt +31 -0
  29. package/android/src/main/java/expo/modules/kotlin/events/EventsDefinition.kt +3 -0
  30. package/android/src/main/java/expo/modules/kotlin/events/KEventEmitterWrapper.kt +26 -0
  31. package/android/src/main/java/expo/modules/kotlin/events/OnActivityResultPayload.kt +8 -0
  32. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +70 -0
  33. package/android/src/main/java/expo/modules/kotlin/methods/AnyMethod.kt +50 -0
  34. package/android/src/main/java/expo/modules/kotlin/methods/Method.kt +14 -0
  35. package/android/src/main/java/expo/modules/kotlin/methods/PromiseMethod.kt +15 -0
  36. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +24 -0
  37. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +227 -0
  38. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +16 -0
  39. package/android/src/main/java/expo/modules/kotlin/records/Field.kt +5 -0
  40. package/android/src/main/java/expo/modules/kotlin/records/Record.kt +3 -0
  41. package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +55 -0
  42. package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +14 -0
  43. package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +44 -0
  44. package/android/src/main/java/expo/modules/kotlin/types/BasicTypeConverters.kt +60 -0
  45. package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +84 -0
  46. package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +25 -0
  47. package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +39 -0
  48. package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +28 -0
  49. package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +19 -0
  50. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +107 -0
  51. package/android/src/main/java/expo/modules/kotlin/views/AnyViewProp.kt +10 -0
  52. package/android/src/main/java/expo/modules/kotlin/views/ConcreteViewProp.kt +17 -0
  53. package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +22 -0
  54. package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +21 -0
  55. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +36 -0
  56. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +40 -0
  57. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +21 -0
  58. package/android/src/main/java/expo/modules/kotlin/views/ViewWrapperDelegateHolder.kt +5 -0
  59. package/build/NativeModulesProxy.native.d.ts +4 -0
  60. package/build/NativeModulesProxy.native.js +14 -1
  61. package/build/NativeModulesProxy.native.js.map +1 -1
  62. package/build/NativeModulesProxy.types.d.ts +3 -0
  63. package/build/NativeModulesProxy.types.js.map +1 -1
  64. package/ios/AppDelegates/EXAppDelegateWrapper.h +16 -0
  65. package/ios/AppDelegates/EXAppDelegateWrapper.m +42 -0
  66. package/ios/AppDelegates/EXAppDelegatesLoader.h +15 -0
  67. package/ios/AppDelegates/EXAppDelegatesLoader.m +29 -0
  68. package/ios/AppDelegates/EXLegacyAppDelegateWrapper.h +16 -0
  69. package/ios/{EXAppDelegateWrapper.m → AppDelegates/EXLegacyAppDelegateWrapper.m} +2 -2
  70. package/ios/AppDelegates/ExpoAppDelegate.swift +264 -0
  71. package/ios/AppDelegates/ExpoAppDelegateSubscriber.swift +24 -0
  72. package/ios/ExpoModulesCore.podspec +7 -2
  73. package/ios/JSI/ExpoModulesProxySpec.h +24 -0
  74. package/ios/JSI/ExpoModulesProxySpec.mm +135 -0
  75. package/ios/JSI/JSIConversions.h +42 -0
  76. package/ios/JSI/JSIConversions.mm +164 -0
  77. package/ios/JSI/JSIInstaller.h +19 -0
  78. package/ios/JSI/JSIInstaller.mm +22 -0
  79. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +1 -6
  80. package/ios/NativeModulesProxy/EXNativeModulesProxy.h +6 -0
  81. package/ios/NativeModulesProxy/{EXNativeModulesProxy.m → EXNativeModulesProxy.mm} +45 -12
  82. package/ios/Services/EXReactNativeEventEmitter.h +6 -0
  83. package/ios/Services/EXReactNativeEventEmitter.m +15 -0
  84. package/ios/Swift/AppContext.swift +14 -1
  85. package/ios/Swift/Arguments/AnyArgument.swift +14 -0
  86. package/ios/Swift/Arguments/AnyArgumentType.swift +13 -0
  87. package/ios/Swift/Arguments/ArgumentType.swift +24 -0
  88. package/ios/Swift/Arguments/ConvertibleArgument.swift +15 -0
  89. package/ios/Swift/Arguments/Convertibles.swift +93 -0
  90. package/ios/Swift/Arguments/Types/ArrayArgumentType.swift +42 -0
  91. package/ios/Swift/Arguments/Types/ConvertibleArgumentType.swift +16 -0
  92. package/ios/Swift/Arguments/Types/EnumArgumentType.swift +105 -0
  93. package/ios/Swift/Arguments/Types/OptionalArgumentType.swift +49 -0
  94. package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +15 -0
  95. package/ios/Swift/Arguments/Types/RawArgumentType.swift +25 -0
  96. package/ios/Swift/Conversions.swift +199 -7
  97. package/ios/Swift/EventListener.swift +37 -5
  98. package/ios/Swift/Functions/AnyFunction.swift +42 -0
  99. package/ios/Swift/{Methods/ConcreteMethod.swift → Functions/ConcreteFunction.swift} +32 -34
  100. package/ios/Swift/ModuleHolder.swift +75 -20
  101. package/ios/Swift/ModuleRegistry.swift +19 -8
  102. package/ios/Swift/Modules/AnyModule.swift +8 -8
  103. package/ios/Swift/Modules/Module.swift +7 -0
  104. package/ios/Swift/Modules/ModuleDefinition.swift +52 -8
  105. package/ios/Swift/Modules/ModuleDefinitionBuilder.swift +1 -1
  106. package/ios/Swift/Modules/ModuleDefinitionComponents.swift +140 -52
  107. package/ios/Swift/ModulesProvider.swift +9 -0
  108. package/ios/Swift/Promise.swift +1 -1
  109. package/ios/Swift/Records/Field.swift +1 -1
  110. package/ios/Swift/Records/Record.swift +8 -1
  111. package/ios/Swift/SwiftInteropBridge.swift +45 -16
  112. package/ios/Swift/Views/AnyViewProp.swift +2 -2
  113. package/ios/Swift/Views/ConcreteViewProp.swift +37 -10
  114. package/ios/Swift/Views/ViewModuleWrapper.swift +9 -4
  115. package/ios/Swift.h +9 -0
  116. package/ios/Tests/ArgumentTypeSpec.swift +145 -0
  117. package/ios/Tests/ConvertiblesSpec.swift +231 -0
  118. package/ios/Tests/{MethodSpec.swift → FunctionSpec.swift} +69 -54
  119. package/ios/Tests/FunctionWithConvertiblesSpec.swift +66 -0
  120. package/ios/Tests/Mocks/ModuleMocks.swift +21 -7
  121. package/ios/Tests/ModuleEventListenersSpec.swift +17 -16
  122. package/ios/Tests/ModuleRegistrySpec.swift +4 -7
  123. package/package.json +3 -3
  124. package/src/NativeModulesProxy.native.ts +22 -2
  125. package/src/NativeModulesProxy.types.ts +8 -0
  126. package/ios/EXAppDelegateWrapper.h +0 -13
  127. package/ios/Swift/Methods/AnyArgumentType.swift +0 -48
  128. package/ios/Swift/Methods/AnyMethod.swift +0 -31
  129. package/ios/Swift/Methods/AnyMethodArgument.swift +0 -13
@@ -1,8 +1,8 @@
1
1
 
2
2
  /**
3
- A protocol for any type-erased module that provides methods used by the core.
3
+ A protocol for any type-erased module that provides functions used by the core.
4
4
  */
5
- public protocol AnyModule: AnyObject {
5
+ public protocol AnyModule: AnyObject, AnyArgument {
6
6
  /**
7
7
  The default initializer. Must be public, but the module class does *not* need to
8
8
  define it as it is implemented in protocol composition, see `BaseModule` class.
@@ -10,7 +10,7 @@ public protocol AnyModule: AnyObject {
10
10
  init(appContext: AppContext)
11
11
 
12
12
  /**
13
- A DSL-like function that returns a `ModuleDefinition` which can be built up from module's name, constants or methods.
13
+ A DSL-like function that returns a `ModuleDefinition` which can be built up from module's name, constants or functions.
14
14
  The `@ModuleDefinitionBuilder` wrapper is *not* required in the implementation — it is implicitly taken from the protocol.
15
15
 
16
16
  # Example
@@ -18,7 +18,7 @@ public protocol AnyModule: AnyObject {
18
18
  ```
19
19
  public func definition() -> ModuleDefinition {
20
20
  name("MyModule")
21
- method("myMethod") { (a: String, b: String) in
21
+ function("myFunction") { (a: String, b: String) in
22
22
  "\(a) \(b)"
23
23
  }
24
24
  }
@@ -29,16 +29,16 @@ public protocol AnyModule: AnyObject {
29
29
  ```javascript
30
30
  import { NativeModulesProxy } from 'expo-modules-core';
31
31
 
32
- await NativeModulesProxy.MyModule.myMethod('Hello', 'World!'); // -> 'Hello World!'
32
+ await NativeModulesProxy.MyModule.myFunction('Hello', 'World!'); // -> 'Hello World!'
33
33
  ```
34
34
 
35
- # Method's result obtained asynchronously
35
+ # Function's result obtained asynchronously
36
36
 
37
37
  If you need to run some async code to get the proper value that you want to return to JavaScript,
38
- just specify an argument of type `Promise` as the last one and use its `resolve` or `reject` methods.
38
+ just specify an argument of type `Promise` as the last one and use its `resolve` or `reject` functions.
39
39
 
40
40
  ```
41
- method("myMethod") { (promise: Promise) in
41
+ function("myFunction") { (promise: Promise) in
42
42
  DispatchQueue.main.async {
43
43
  promise.resolve("return value obtained in async callback")
44
44
  }
@@ -10,6 +10,13 @@ open class BaseModule {
10
10
  required public init(appContext: AppContext) {
11
11
  self.appContext = appContext
12
12
  }
13
+
14
+ /**
15
+ Sends an event with given name and body to JavaScript.
16
+ */
17
+ public func sendEvent(_ eventName: String, _ body: [String: Any?] = [:]) {
18
+ appContext?.eventEmitter?.sendEvent(withName: eventName, body: body)
19
+ }
13
20
  }
14
21
 
15
22
  /**
@@ -9,23 +9,40 @@ public protocol AnyDefinition {}
9
9
  of the module and what it exports to the JavaScript world.
10
10
  See `ModuleDefinitionBuilder` for more details on how to create it.
11
11
  */
12
- public struct ModuleDefinition: AnyDefinition {
13
- let name: String?
14
- let methods: [String : AnyMethod]
12
+ public final class ModuleDefinition: AnyDefinition {
13
+ /**
14
+ The module's type associated with the definition. It's used to create the module instance.
15
+ */
16
+ var type: AnyModule.Type?
17
+
18
+ /**
19
+ Name of the defined module. Falls back to the type name if not provided in the definition.
20
+ */
21
+ var name: String
22
+
23
+ let functions: [String : AnyFunction]
15
24
  let constants: [String : Any?]
16
25
  let eventListeners: [EventListener]
17
26
  let viewManager: ViewManagerDefinition?
18
27
 
28
+ /**
29
+ Names of the events that the module can send to JavaScript.
30
+ */
31
+ let eventNames: [String]
32
+
33
+ /**
34
+ Initializer that is called by the `ModuleDefinitionBuilder` results builder.
35
+ */
19
36
  init(definitions: [AnyDefinition]) {
20
37
  self.name = definitions
21
38
  .compactMap { $0 as? ModuleNameDefinition }
22
39
  .last?
23
- .name
40
+ .name ?? ""
24
41
 
25
- self.methods = definitions
26
- .compactMap { $0 as? AnyMethod }
27
- .reduce(into: [String : AnyMethod]()) { dict, method in
28
- dict[method.name] = method
42
+ self.functions = definitions
43
+ .compactMap { $0 as? AnyFunction }
44
+ .reduce(into: [String : AnyFunction]()) { dict, function in
45
+ dict[function.name] = function
29
46
  }
30
47
 
31
48
  self.constants = definitions
@@ -39,6 +56,26 @@ public struct ModuleDefinition: AnyDefinition {
39
56
  self.viewManager = definitions
40
57
  .compactMap { $0 as? ViewManagerDefinition }
41
58
  .last
59
+
60
+ self.eventNames = Array(
61
+ definitions
62
+ .compactMap { ($0 as? EventsDefinition)?.names }
63
+ .joined()
64
+ )
65
+ }
66
+
67
+ /**
68
+ Sets the module type that the definition is associated with. We can't pass this in the initializer
69
+ as it's called by the results builder that doesn't have access to the type.
70
+ */
71
+ func withType(_ type: AnyModule.Type) -> Self {
72
+ self.type = type
73
+
74
+ // Use the type name if the name is not in the definition or was defined empty.
75
+ if name.isEmpty {
76
+ name = String(describing: type)
77
+ }
78
+ return self
42
79
  }
43
80
  }
44
81
 
@@ -55,3 +92,10 @@ internal struct ModuleNameDefinition: AnyDefinition {
55
92
  internal struct ConstantsDefinition: AnyDefinition {
56
93
  let constants: [String : Any?]
57
94
  }
95
+
96
+ /**
97
+ A definition for module's events that can be sent to JavaScript.
98
+ */
99
+ internal struct EventsDefinition: AnyDefinition {
100
+ let names: [String]
101
+ }
@@ -2,7 +2,7 @@
2
2
  #if swift(>=5.4)
3
3
  /**
4
4
  A function builder that provides DSL-like syntax. Thanks to this, the function doesn't need to explicitly return an array,
5
- but can just return multiple methods one after another. This works similarly to SwiftUI's `body` block.
5
+ but can just return multiple components one after another. This works similarly to SwiftUI's `body` block.
6
6
  */
7
7
  @resultBuilder
8
8
  public struct ModuleDefinitionBuilder {
@@ -7,6 +7,8 @@ import UIKit
7
7
  will be implemented in the future.
8
8
  */
9
9
  extension AnyModule {
10
+ // MARK: - Module name
11
+
10
12
  /**
11
13
  Sets the name of the module that is exported to the JavaScript world.
12
14
  */
@@ -14,6 +16,8 @@ extension AnyModule {
14
16
  return ModuleNameDefinition(name: name)
15
17
  }
16
18
 
19
+ // MARK: - Constants
20
+
17
21
  /**
18
22
  Definition function setting the module's constants to export.
19
23
  */
@@ -21,14 +25,16 @@ extension AnyModule {
21
25
  return ConstantsDefinition(constants: closure())
22
26
  }
23
27
 
28
+ // MARK: - Functions
29
+
24
30
  /**
25
- Factory function for methods without arguments.
31
+ Function without arguments.
26
32
  */
27
- public func method<R>(
33
+ public func function<R>(
28
34
  _ name: String,
29
35
  _ closure: @escaping () -> R
30
- ) -> AnyMethod {
31
- return ConcreteMethod(
36
+ ) -> AnyFunction {
37
+ return ConcreteFunction(
32
38
  name,
33
39
  argTypes: [],
34
40
  closure
@@ -36,117 +42,119 @@ extension AnyModule {
36
42
  }
37
43
 
38
44
  /**
39
- Factory function for methods with one argument.
45
+ Function with one argument.
40
46
  */
41
- public func method<R, A0: AnyMethodArgument>(
47
+ public func function<R, A0: AnyArgument>(
42
48
  _ name: String,
43
49
  _ closure: @escaping (A0) -> R
44
- ) -> AnyMethod {
45
- return ConcreteMethod(
50
+ ) -> AnyFunction {
51
+ return ConcreteFunction(
46
52
  name,
47
- argTypes: [AnyArgumentType(A0.self)],
53
+ argTypes: [ArgumentType(A0.self)],
48
54
  closure
49
55
  )
50
56
  }
51
57
 
52
58
  /**
53
- Factory function for methods with 2 arguments.
59
+ Function with two arguments.
54
60
  */
55
- public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument>(
61
+ public func function<R, A0: AnyArgument, A1: AnyArgument>(
56
62
  _ name: String,
57
63
  _ closure: @escaping (A0, A1) -> R
58
- ) -> AnyMethod {
59
- return ConcreteMethod(
64
+ ) -> AnyFunction {
65
+ return ConcreteFunction(
60
66
  name,
61
- argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self)],
67
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self)],
62
68
  closure
63
69
  )
64
70
  }
65
71
 
66
72
  /**
67
- Factory function for methods with 3 arguments.
73
+ Function with three arguments.
68
74
  */
69
- public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument>(
75
+ public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument>(
70
76
  _ name: String,
71
77
  _ closure: @escaping (A0, A1, A2) -> R
72
- ) -> AnyMethod {
73
- return ConcreteMethod(
78
+ ) -> AnyFunction {
79
+ return ConcreteFunction(
74
80
  name,
75
- argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self)],
81
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self), ArgumentType(A2.self)],
76
82
  closure
77
83
  )
78
84
  }
79
85
 
80
86
  /**
81
- Factory function for methods with 4 arguments.
87
+ Function with four arguments.
82
88
  */
83
- public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument>(
89
+ public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument>(
84
90
  _ name: String,
85
91
  _ closure: @escaping (A0, A1, A2, A3) -> R
86
- ) -> AnyMethod {
87
- return ConcreteMethod(
92
+ ) -> AnyFunction {
93
+ return ConcreteFunction(
88
94
  name,
89
- argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self)],
95
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self), ArgumentType(A2.self), ArgumentType(A3.self)],
90
96
  closure
91
97
  )
92
98
  }
93
99
 
94
100
  /**
95
- Factory function for methods with 5 arguments.
101
+ Function with five arguments.
96
102
  */
97
- public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument>(
103
+ public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument>(
98
104
  _ name: String,
99
105
  _ closure: @escaping (A0, A1, A2, A3, A4) -> R
100
- ) -> AnyMethod {
101
- return ConcreteMethod(
106
+ ) -> AnyFunction {
107
+ return ConcreteFunction(
102
108
  name,
103
- argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self), AnyArgumentType(A4.self)],
109
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self), ArgumentType(A2.self), ArgumentType(A3.self), ArgumentType(A4.self)],
104
110
  closure
105
111
  )
106
112
  }
107
113
 
108
114
  /**
109
- Factory function for methods with 6 arguments.
115
+ Function with six arguments.
110
116
  */
111
- public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument, A5: AnyMethodArgument>(
117
+ public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument>(
112
118
  _ name: String,
113
119
  _ closure: @escaping (A0, A1, A2, A3, A4, A5) -> R
114
- ) -> AnyMethod {
115
- return ConcreteMethod(
120
+ ) -> AnyFunction {
121
+ return ConcreteFunction(
116
122
  name,
117
- argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self), AnyArgumentType(A4.self), AnyArgumentType(A5.self)],
123
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self), ArgumentType(A2.self), ArgumentType(A3.self), ArgumentType(A4.self), ArgumentType(A5.self)],
118
124
  closure
119
125
  )
120
126
  }
121
127
 
122
128
  /**
123
- Factory function for methods with 7 arguments.
129
+ Function with seven arguments.
124
130
  */
125
- public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument, A5: AnyMethodArgument, A6: AnyMethodArgument>(
131
+ public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument, A6: AnyArgument>(
126
132
  _ name: String,
127
133
  _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6) -> R
128
- ) -> AnyMethod {
129
- return ConcreteMethod(
134
+ ) -> AnyFunction {
135
+ return ConcreteFunction(
130
136
  name,
131
- argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self), AnyArgumentType(A4.self), AnyArgumentType(A5.self), AnyArgumentType(A6.self)],
137
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self), ArgumentType(A2.self), ArgumentType(A3.self), ArgumentType(A4.self), ArgumentType(A5.self), ArgumentType(A6.self)],
132
138
  closure
133
139
  )
134
140
  }
135
141
 
136
142
  /**
137
- Factory function for methods with 8 arguments.
143
+ Function with eight arguments.
138
144
  */
139
- public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument, A5: AnyMethodArgument, A6: AnyMethodArgument, A7: AnyMethodArgument>(
145
+ public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument, A6: AnyArgument, A7: AnyArgument>(
140
146
  _ name: String,
141
147
  _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6, A7) -> R
142
- ) -> AnyMethod {
143
- return ConcreteMethod(
148
+ ) -> AnyFunction {
149
+ return ConcreteFunction(
144
150
  name,
145
- 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)],
151
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self), ArgumentType(A2.self), ArgumentType(A3.self), ArgumentType(A4.self), ArgumentType(A5.self), ArgumentType(A6.self), ArgumentType(A7.self)],
146
152
  closure
147
153
  )
148
154
  }
149
155
 
156
+ // MARK: - Module's lifecycle
157
+
150
158
  /**
151
159
  Creates module's lifecycle listener that is called right after module initialization.
152
160
  */
@@ -188,13 +196,38 @@ extension AnyModule {
188
196
  public func onAppEntersBackground(_ closure: @escaping () -> Void) -> AnyDefinition {
189
197
  return EventListener(.appEntersBackground, closure)
190
198
  }
191
- }
192
199
 
193
- /**
194
- Creates the view manager definition that scopes other view-related definitions.
195
- */
196
- public func viewManager(@ViewManagerDefinitionBuilder _ closure: @escaping () -> ViewManagerDefinition) -> AnyDefinition {
197
- return closure()
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
+ Function that is invoked when the first event listener is added.
220
+ */
221
+ public func onStartObserving(_ body: @escaping () -> ()) -> AnyFunction {
222
+ return ConcreteFunction("startObserving", argTypes: [], body)
223
+ }
224
+
225
+ /**
226
+ Function that is invoked when all event listeners are removed.
227
+ */
228
+ public func onStopObserving(_ body: @escaping () -> ()) -> AnyFunction {
229
+ return ConcreteFunction("stopObserving", argTypes: [], body)
230
+ }
198
231
  }
199
232
 
200
233
  /**
@@ -207,6 +240,61 @@ public func view(_ closure: @escaping () -> UIView) -> AnyDefinition {
207
240
  /**
208
241
  Creates a view prop that defines its name and setter.
209
242
  */
210
- public func prop<ViewType: UIView, PropType>(_ name: String, _ setter: @escaping (ViewType, PropType) -> Void) -> AnyDefinition {
211
- return ConcreteViewProp(name, setter)
243
+ public func prop<ViewType: UIView, PropType: AnyArgument>(
244
+ _ name: String,
245
+ _ setter: @escaping (ViewType, PropType) -> Void
246
+ ) -> AnyDefinition {
247
+ return ConcreteViewProp(
248
+ name: name,
249
+ propType: ArgumentType(PropType.self),
250
+ setter: setter
251
+ )
252
+ }
253
+
254
+ // TODO: - Remove deprecated `method` component once SDK44 is out.
255
+ public extension AnyModule {
256
+ /**
257
+ Function without arguments.
258
+ */
259
+ @available(*, deprecated, renamed: "function")
260
+ func method<R>(
261
+ _ name: String,
262
+ _ closure: @escaping () -> R
263
+ ) -> AnyFunction {
264
+ return ConcreteFunction(
265
+ name,
266
+ argTypes: [],
267
+ closure
268
+ )
269
+ }
270
+
271
+ /**
272
+ Function with one argument.
273
+ */
274
+ @available(*, deprecated, renamed: "function")
275
+ func method<R, A0: AnyArgument>(
276
+ _ name: String,
277
+ _ closure: @escaping (A0) -> R
278
+ ) -> AnyFunction {
279
+ return ConcreteFunction(
280
+ name,
281
+ argTypes: [ArgumentType(A0.self)],
282
+ closure
283
+ )
284
+ }
285
+
286
+ /**
287
+ Function with two arguments.
288
+ */
289
+ @available(*, deprecated, renamed: "function")
290
+ func method<R, A0: AnyArgument, A1: AnyArgument>(
291
+ _ name: String,
292
+ _ closure: @escaping (A0, A1) -> R
293
+ ) -> AnyFunction {
294
+ return ConcreteFunction(
295
+ name,
296
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self)],
297
+ closure
298
+ )
299
+ }
212
300
  }
@@ -13,6 +13,11 @@ public protocol ModulesProviderObjCProtocol {}
13
13
  */
14
14
  public protocol ModulesProviderProtocol: ModulesProviderObjCProtocol {
15
15
  func getModuleClasses() -> [AnyModule.Type]
16
+
17
+ /**
18
+ Returns an array of classes that hooks into `ExpoAppDelegate` to receive app delegate events.
19
+ */
20
+ func getAppDelegateSubscribers() -> [ExpoAppDelegateSubscriber.Type]
16
21
  }
17
22
 
18
23
  /**
@@ -24,4 +29,8 @@ open class ModulesProvider: NSObject, ModulesProviderProtocol, ModulesProviderOb
24
29
  open func getModuleClasses() -> [AnyModule.Type] {
25
30
  return []
26
31
  }
32
+
33
+ open func getAppDelegateSubscribers() -> [ExpoAppDelegateSubscriber.Type] {
34
+ return []
35
+ }
27
36
  }
@@ -1,5 +1,5 @@
1
1
 
2
- public struct Promise: AnyMethodArgument {
2
+ public struct Promise: AnyArgument {
3
3
  public typealias ResolveClosure = (Any?) -> Void
4
4
  public typealias RejectClosure = (CodedError) -> Void
5
5
 
@@ -2,7 +2,7 @@
2
2
  Property wrapper for `Record`'s data members that takes part in the process of serialization to and deserialization from the dictionary.
3
3
  */
4
4
  @propertyWrapper
5
- public class Field<Type>: AnyFieldInternal {
5
+ public final class Field<Type>: AnyFieldInternal {
6
6
  /**
7
7
  The wrapped value.
8
8
  */
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  A protocol that allows initializing the object with a dictionary.
3
3
  */
4
- public protocol Record: AnyMethodArgument {
4
+ public protocol Record: ConvertibleArgument {
5
5
  /**
6
6
  The dictionary type that the record can be created from or converted back.
7
7
  */
@@ -27,6 +27,13 @@ public protocol Record: AnyMethodArgument {
27
27
  Provides the default implementation of `Record` protocol.
28
28
  */
29
29
  public extension Record {
30
+ static func convert(from value: Any?) throws -> Self {
31
+ if let value = value as? Dict {
32
+ return try Self(from: value)
33
+ }
34
+ throw Conversions.ConvertingError<Self>(value: value)
35
+ }
36
+
30
37
  init(from dict: Dict) throws {
31
38
  self.init()
32
39
 
@@ -2,7 +2,7 @@
2
2
  import Foundation
3
3
 
4
4
  @objc
5
- public class SwiftInteropBridge: NSObject {
5
+ public final class SwiftInteropBridge: NSObject {
6
6
  let appContext: AppContext
7
7
 
8
8
  var registry: ModuleRegistry {
@@ -21,15 +21,15 @@ public class SwiftInteropBridge: NSObject {
21
21
  }
22
22
 
23
23
  @objc
24
- public func callMethod(_ methodName: String,
25
- onModule moduleName: String,
26
- withArgs args: [Any],
27
- resolve: @escaping EXPromiseResolveBlock,
28
- reject: @escaping EXPromiseRejectBlock) {
24
+ public func callFunction(_ functionName: String,
25
+ onModule moduleName: String,
26
+ withArgs args: [Any],
27
+ resolve: @escaping EXPromiseResolveBlock,
28
+ reject: @escaping EXPromiseRejectBlock) {
29
29
  registry
30
30
  .get(moduleHolderForName: moduleName)?
31
- .call(method: methodName, args: args) { value, error in
32
- if let error = error as? CodedError {
31
+ .call(function: functionName, args: args) { value, error in
32
+ if let error = error {
33
33
  reject(error.code, error.description, error)
34
34
  } else if let error = error {
35
35
  reject("ERR_UNKNOWN_ERROR", error.localizedDescription, error)
@@ -40,18 +40,24 @@ public class SwiftInteropBridge: NSObject {
40
40
  }
41
41
 
42
42
  @objc
43
- public func exportedMethodNames() -> [String: [[String: Any]]] {
43
+ public func callFunctionSync(_ functionName: String,
44
+ onModule moduleName: String,
45
+ withArgs args: [Any]) -> Any? {
46
+ return registry
47
+ .get(moduleHolderForName: moduleName)?
48
+ .callSync(function: functionName, args: args)
49
+ }
50
+
51
+ @objc
52
+ public func exportedFunctionNames() -> [String: [[String: Any]]] {
44
53
  var constants = [String: [[String: Any]]]()
45
54
 
46
55
  for holder in registry {
47
- var index = -1
48
-
49
- constants[holder.name] = holder.definition.methods.map({ (methodName, method) in
50
- index += 1
56
+ constants[holder.name] = holder.definition.functions.map({ (functionName, function) in
51
57
  return [
52
- "name": methodName,
53
- "argumentsCount": method.argumentsCount,
54
- "key": methodName,
58
+ "name": functionName,
59
+ "argumentsCount": function.argumentsCount,
60
+ "key": functionName,
55
61
  ]
56
62
  })
57
63
  }
@@ -85,4 +91,27 @@ public class SwiftInteropBridge: NSObject {
85
91
  }
86
92
  }
87
93
  }
94
+
95
+ // MARK: - Events
96
+
97
+ /**
98
+ Returns an array of event names supported by all Swift modules.
99
+ */
100
+ @objc
101
+ public func getSupportedEvents() -> [String] {
102
+ return registry.reduce(into: [String]()) { events, holder in
103
+ events.append(contentsOf: holder.definition.eventNames)
104
+ }
105
+ }
106
+
107
+ /**
108
+ Modifies listeners count for module with given name. Depending on the listeners count,
109
+ `onStartObserving` and `onStopObserving` are called.
110
+ */
111
+ @objc
112
+ public func modifyEventListenersCount(_ moduleName: String, count: Int) {
113
+ registry
114
+ .get(moduleHolderForName: moduleName)?
115
+ .modifyListenersCount(count)
116
+ }
88
117
  }
@@ -5,12 +5,12 @@ import UIKit
5
5
  */
6
6
  public protocol AnyViewProp: AnyDefinition {
7
7
  /**
8
- Name of the prop.
8
+ Name of the view prop that JavaScript refers to.
9
9
  */
10
10
  var name: String { get }
11
11
 
12
12
  /**
13
13
  Function that sets the underlying prop value for given view.
14
14
  */
15
- func set(value: Any?, onView: UIView)
15
+ func set(value: Any, onView: UIView) throws
16
16
  }