expo-modules-core 0.4.6 → 0.6.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 (150) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +6 -6
  3. package/android/build.gradle +30 -2
  4. package/android/src/main/java/expo/modules/adapters/react/ModuleRegistryAdapter.java +27 -5
  5. package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +49 -5
  6. package/android/src/main/java/expo/modules/core/BasePackage.java +6 -0
  7. package/android/src/main/java/expo/modules/core/ModulePriorities.kt +25 -0
  8. package/android/src/main/java/expo/modules/core/interfaces/ActivityEventListener.java +3 -1
  9. package/android/src/main/java/expo/modules/core/interfaces/ApplicationLifecycleListener.java +10 -0
  10. package/android/src/main/java/expo/modules/core/interfaces/Package.java +4 -0
  11. package/android/src/main/java/expo/modules/core/interfaces/ReactActivityHandler.java +21 -0
  12. package/android/src/main/java/expo/modules/core/interfaces/ReactActivityLifecycleListener.java +14 -0
  13. package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.java +70 -0
  14. package/android/src/main/java/expo/modules/core/utilities/KotlinUtilities.kt +23 -0
  15. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +166 -0
  16. package/android/src/main/java/expo/modules/kotlin/DynamicExtenstions.kt +9 -0
  17. package/android/src/main/java/expo/modules/kotlin/ExpoModulesHelper.kt +18 -0
  18. package/android/src/main/java/expo/modules/kotlin/KPromiseWrapper.kt +24 -0
  19. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +98 -0
  20. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +41 -0
  21. package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +56 -0
  22. package/android/src/main/java/expo/modules/kotlin/ModulesProvider.kt +7 -0
  23. package/android/src/main/java/expo/modules/kotlin/Promise.kt +13 -0
  24. package/android/src/main/java/expo/modules/kotlin/ReactLifecycleDelegate.kt +39 -0
  25. package/android/src/main/java/expo/modules/kotlin/ReadableArrayIterator.kt +14 -0
  26. package/android/src/main/java/expo/modules/kotlin/ReadableTypeExtensions.kt +18 -0
  27. package/android/src/main/java/expo/modules/kotlin/allocators/ObjectConstructor.kt +5 -0
  28. package/android/src/main/java/expo/modules/kotlin/allocators/ObjectConstructorFactory.kt +31 -0
  29. package/android/src/main/java/expo/modules/kotlin/allocators/UnsafeAllocator.kt +49 -0
  30. package/android/src/main/java/expo/modules/kotlin/events/EventListener.kt +39 -0
  31. package/android/src/main/java/expo/modules/kotlin/events/EventName.kt +31 -0
  32. package/android/src/main/java/expo/modules/kotlin/events/EventsDefinition.kt +3 -0
  33. package/android/src/main/java/expo/modules/kotlin/events/KEventEmitterWrapper.kt +26 -0
  34. package/android/src/main/java/expo/modules/kotlin/events/OnActivityResultPayload.kt +8 -0
  35. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +70 -0
  36. package/android/src/main/java/expo/modules/kotlin/methods/AnyMethod.kt +50 -0
  37. package/android/src/main/java/expo/modules/kotlin/methods/Method.kt +14 -0
  38. package/android/src/main/java/expo/modules/kotlin/methods/PromiseMethod.kt +15 -0
  39. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +24 -0
  40. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +227 -0
  41. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +16 -0
  42. package/android/src/main/java/expo/modules/kotlin/records/Field.kt +5 -0
  43. package/android/src/main/java/expo/modules/kotlin/records/Record.kt +3 -0
  44. package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +55 -0
  45. package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +14 -0
  46. package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +44 -0
  47. package/android/src/main/java/expo/modules/kotlin/types/BasicTypeConverters.kt +60 -0
  48. package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +84 -0
  49. package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +25 -0
  50. package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +39 -0
  51. package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +28 -0
  52. package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +19 -0
  53. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +107 -0
  54. package/android/src/main/java/expo/modules/kotlin/views/AnyViewProp.kt +10 -0
  55. package/android/src/main/java/expo/modules/kotlin/views/ConcreteViewProp.kt +17 -0
  56. package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +22 -0
  57. package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +21 -0
  58. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +41 -0
  59. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +40 -0
  60. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +21 -0
  61. package/android/src/main/java/expo/modules/kotlin/views/ViewWrapperDelegateHolder.kt +5 -0
  62. package/build/NativeModulesProxy.native.d.ts +4 -0
  63. package/build/NativeModulesProxy.native.js +14 -1
  64. package/build/NativeModulesProxy.native.js.map +1 -1
  65. package/build/NativeModulesProxy.types.d.ts +3 -0
  66. package/build/NativeModulesProxy.types.js.map +1 -1
  67. package/build/NativeViewManagerAdapter.native.js +1 -1
  68. package/build/NativeViewManagerAdapter.native.js.map +1 -1
  69. package/ios/AppDelegates/EXAppDelegateWrapper.h +19 -0
  70. package/ios/AppDelegates/EXAppDelegateWrapper.m +45 -0
  71. package/ios/AppDelegates/EXAppDelegatesLoader.h +15 -0
  72. package/ios/AppDelegates/EXAppDelegatesLoader.m +30 -0
  73. package/ios/AppDelegates/EXLegacyAppDelegateWrapper.h +16 -0
  74. package/ios/{EXAppDelegateWrapper.m → AppDelegates/EXLegacyAppDelegateWrapper.m} +2 -2
  75. package/ios/AppDelegates/ExpoAppDelegate.swift +282 -0
  76. package/ios/AppDelegates/ExpoAppDelegateSubscriber.swift +24 -0
  77. package/ios/EXAppDefines.h +26 -0
  78. package/ios/EXAppDefines.m +61 -0
  79. package/ios/ExpoModulesCore.podspec +8 -3
  80. package/ios/JSI/ExpoModulesProxySpec.h +24 -0
  81. package/ios/JSI/ExpoModulesProxySpec.mm +135 -0
  82. package/ios/JSI/JSIConversions.h +42 -0
  83. package/ios/JSI/JSIConversions.mm +164 -0
  84. package/ios/JSI/JSIInstaller.h +19 -0
  85. package/ios/JSI/JSIInstaller.mm +22 -0
  86. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +1 -6
  87. package/ios/NativeModulesProxy/EXNativeModulesProxy.h +6 -0
  88. package/ios/NativeModulesProxy/{EXNativeModulesProxy.m → EXNativeModulesProxy.mm} +91 -18
  89. package/ios/ReactDelegates/EXRCTBridgeDelegateInterceptor.h +16 -0
  90. package/ios/ReactDelegates/EXRCTBridgeDelegateInterceptor.m +49 -0
  91. package/ios/ReactDelegates/EXReactDelegateWrapper+Private.h +18 -0
  92. package/ios/ReactDelegates/EXReactDelegateWrapper.h +25 -0
  93. package/ios/ReactDelegates/EXReactDelegateWrapper.m +40 -0
  94. package/ios/ReactDelegates/ExpoReactDelegate.swift +37 -0
  95. package/ios/ReactDelegates/ExpoReactDelegateHandler.swift +52 -0
  96. package/ios/ReactDelegates/ModulePriorities.swift +20 -0
  97. package/ios/Services/EXReactNativeEventEmitter.h +6 -0
  98. package/ios/Services/EXReactNativeEventEmitter.m +15 -0
  99. package/ios/Swift/AppContext.swift +14 -1
  100. package/ios/Swift/Arguments/AnyArgument.swift +14 -0
  101. package/ios/Swift/Arguments/AnyArgumentType.swift +13 -0
  102. package/ios/Swift/Arguments/ArgumentType.swift +24 -0
  103. package/ios/Swift/Arguments/ConvertibleArgument.swift +15 -0
  104. package/ios/Swift/Arguments/Convertibles.swift +107 -0
  105. package/ios/Swift/Arguments/Types/ArrayArgumentType.swift +42 -0
  106. package/ios/Swift/Arguments/Types/ConvertibleArgumentType.swift +16 -0
  107. package/ios/Swift/Arguments/Types/EnumArgumentType.swift +105 -0
  108. package/ios/Swift/Arguments/Types/OptionalArgumentType.swift +49 -0
  109. package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +15 -0
  110. package/ios/Swift/Arguments/Types/RawArgumentType.swift +25 -0
  111. package/ios/Swift/Conversions.swift +199 -7
  112. package/ios/Swift/EventListener.swift +37 -5
  113. package/ios/Swift/Functions/AnyFunction.swift +42 -0
  114. package/ios/Swift/{Methods/ConcreteMethod.swift → Functions/ConcreteFunction.swift} +32 -34
  115. package/ios/Swift/ModuleHolder.swift +86 -20
  116. package/ios/Swift/ModuleRegistry.swift +19 -8
  117. package/ios/Swift/Modules/AnyModule.swift +8 -8
  118. package/ios/Swift/Modules/Module.swift +11 -0
  119. package/ios/Swift/Modules/ModuleDefinition.swift +55 -15
  120. package/ios/Swift/Modules/ModuleDefinitionBuilder.swift +1 -1
  121. package/ios/Swift/Modules/ModuleDefinitionComponents.swift +149 -54
  122. package/ios/Swift/ModulesProvider.swift +19 -0
  123. package/ios/Swift/Promise.swift +1 -1
  124. package/ios/Swift/Records/Field.swift +1 -1
  125. package/ios/Swift/Records/Record.swift +8 -1
  126. package/ios/Swift/SwiftInteropBridge.swift +46 -17
  127. package/ios/Swift/Views/AnyViewProp.swift +2 -2
  128. package/ios/Swift/Views/ConcreteViewProp.swift +37 -10
  129. package/ios/Swift/Views/ViewModuleWrapper.swift +9 -4
  130. package/ios/Swift.h +9 -0
  131. package/ios/Tests/ArgumentTypeSpec.swift +145 -0
  132. package/ios/Tests/ConstantsSpec.swift +36 -0
  133. package/ios/Tests/ConvertiblesSpec.swift +265 -0
  134. package/ios/Tests/EXAppDefinesTest.m +99 -0
  135. package/ios/Tests/{MethodSpec.swift → FunctionSpec.swift} +69 -54
  136. package/ios/Tests/FunctionWithConvertiblesSpec.swift +66 -0
  137. package/ios/Tests/Mocks/ModuleMocks.swift +21 -7
  138. package/ios/Tests/ModuleEventListenersSpec.swift +17 -16
  139. package/ios/Tests/ModuleRegistrySpec.swift +4 -7
  140. package/package.json +3 -3
  141. package/src/NativeModulesProxy.native.ts +22 -2
  142. package/src/NativeModulesProxy.types.ts +8 -0
  143. package/src/NativeViewManagerAdapter.native.tsx +1 -1
  144. package/android/src/main/java/expo/modules/core/interfaces/ApplicationLifecycleListener.kt +0 -9
  145. package/android/src/main/java/expo/modules/core/interfaces/ReactActivityLifecycleListener.kt +0 -11
  146. package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.kt +0 -51
  147. package/ios/EXAppDelegateWrapper.h +0 -13
  148. package/ios/Swift/Methods/AnyArgumentType.swift +0 -48
  149. package/ios/Swift/Methods/AnyMethod.swift +0 -31
  150. package/ios/Swift/Methods/AnyMethodArgument.swift +0 -13
@@ -0,0 +1,45 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ #import <ExpoModulesCore/EXAppDelegateWrapper.h>
4
+ #import <ExpoModulesCore/EXReactDelegateWrapper+Private.h>
5
+ #import <ExpoModulesCore/Swift.h>
6
+
7
+
8
+ @interface EXAppDelegateWrapper()
9
+
10
+ @property (nonatomic, strong) EXReactDelegateWrapper *reactDelegate;
11
+
12
+ @end
13
+
14
+ @implementation EXAppDelegateWrapper {
15
+ EXExpoAppDelegate *_expoAppDelegate;
16
+ }
17
+
18
+ // Synthesize window, so the AppDelegate can synthesize it too.
19
+ @synthesize window = _window;
20
+
21
+ - (instancetype)init
22
+ {
23
+ if (self = [super init]) {
24
+ _expoAppDelegate = [[EXExpoAppDelegate alloc] init];
25
+ _reactDelegate = [[EXReactDelegateWrapper alloc] initWithExpoReactDelegate:_expoAppDelegate.reactDelegate];
26
+ }
27
+ return self;
28
+ }
29
+
30
+ // This needs to be implemented, otherwise forwarding won't be called.
31
+ // When the app starts, `UIApplication` uses it to check beforehand
32
+ // which `UIApplicationDelegate` selectors are implemented.
33
+ - (BOOL)respondsToSelector:(SEL)selector
34
+ {
35
+ return [super respondsToSelector:selector]
36
+ || [_expoAppDelegate respondsToSelector:selector];
37
+ }
38
+
39
+ // Forwards all invocations to `ExpoAppDelegate` object.
40
+ - (id)forwardingTargetForSelector:(SEL)selector
41
+ {
42
+ return _expoAppDelegate;
43
+ }
44
+
45
+ @end
@@ -0,0 +1,15 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ #import <Foundation/Foundation.h>
4
+
5
+ NS_ASSUME_NONNULL_BEGIN
6
+
7
+ /**
8
+ Loads `ExpoAppDelegate` subscribers based on
9
+ the list from the generated `ExpoModulesProvider`.
10
+ */
11
+ @interface EXAppDelegatesLoader : NSObject
12
+
13
+ @end
14
+
15
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,30 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ #import <ExpoModulesCore/EXAppDelegatesLoader.h>
4
+ #import <ExpoModulesCore/EXNativeModulesProxy.h>
5
+
6
+ #if __has_include(<ExpoModulesCore/ExpoModulesCore-Swift.h>)
7
+ // When `use_frameworks!` is used, the generated Swift header is inside ExpoModulesCore module.
8
+ #import <ExpoModulesCore/ExpoModulesCore-Swift.h>
9
+ #else
10
+ #import "ExpoModulesCore-Swift.h"
11
+ #endif
12
+
13
+ // Make the legacy wrapper conform to the protocol for subscribers.
14
+ @interface EXLegacyAppDelegateWrapper () <EXAppDelegateSubscriberProtocol>
15
+ @end
16
+
17
+ @implementation EXAppDelegatesLoader
18
+
19
+ // App delegate providers must be registered before any `AppDelegate` life-cycle event is called.
20
+ // Unfortunately it's not possible in Swift to run code right after the binary is loaded
21
+ // and before any code is executed, so we switch back to Objective-C just to do this one thing.
22
+ + (void)load
23
+ {
24
+ id<ModulesProviderObjCProtocol> modulesProvider = [EXNativeModulesProxy getExpoModulesProvider];
25
+ [EXExpoAppDelegate registerSubscriber:[[EXLegacyAppDelegateWrapper alloc] init]];
26
+ [EXExpoAppDelegate registerSubscribersFromModulesProvider:modulesProvider];
27
+ [EXExpoAppDelegate registerReactDelegateHandlersFromModulesProvider:modulesProvider];
28
+ }
29
+
30
+ @end
@@ -0,0 +1,16 @@
1
+ // Copyright © 2018 650 Industries. All rights reserved.
2
+
3
+ #import <Foundation/Foundation.h>
4
+ #import <UIKit/UIKit.h>
5
+
6
+ NS_ASSUME_NONNULL_BEGIN
7
+
8
+ /**
9
+ The legacy wrapper is still used to forward app delegate calls to singleton modules.
10
+ See `EXAppDelegatesLoader.m` which registers this class as a subscriber of `ExpoAppDelegate`.
11
+ */
12
+ @interface EXLegacyAppDelegateWrapper : UIResponder <UIApplicationDelegate>
13
+
14
+ @end
15
+
16
+ NS_ASSUME_NONNULL_END
@@ -3,13 +3,13 @@
3
3
  #import <Foundation/FoundationErrors.h>
4
4
 
5
5
  #import <ExpoModulesCore/EXModuleRegistryProvider.h>
6
- #import <ExpoModulesCore/EXAppDelegateWrapper.h>
6
+ #import <ExpoModulesCore/EXLegacyAppDelegateWrapper.h>
7
7
 
8
8
  static NSMutableArray<id<UIApplicationDelegate>> *subcontractors;
9
9
  static NSMutableDictionary<NSString *,NSArray<id<UIApplicationDelegate>> *> *subcontractorsForSelector;
10
10
  static dispatch_once_t onceToken;
11
11
 
12
- @implementation EXAppDelegateWrapper
12
+ @implementation EXLegacyAppDelegateWrapper
13
13
 
14
14
  @synthesize window = _window;
15
15
 
@@ -0,0 +1,282 @@
1
+ import UIKit
2
+ import Dispatch
3
+ import Foundation
4
+
5
+ var subscribers = [ExpoAppDelegateSubscriberProtocol]()
6
+ var reactDelegateHandlers = [ExpoReactDelegateHandler]()
7
+
8
+ /**
9
+ Allows classes extending `ExpoAppDelegateSubscriber` to hook into project's app delegate
10
+ by forwarding `UIApplicationDelegate` events to the subscribers.
11
+
12
+ Keep functions and markers in sync with https://developer.apple.com/documentation/uikit/uiapplicationdelegate
13
+ */
14
+ @objc(EXExpoAppDelegate)
15
+ open class ExpoAppDelegate: UIResponder, UIApplicationDelegate {
16
+ open var window: UIWindow?
17
+
18
+ @objc
19
+ public let reactDelegate = ExpoReactDelegate(handlers: reactDelegateHandlers)
20
+
21
+ // MARK: - Initializing the App
22
+
23
+ open func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
24
+ return subscribers.reduce(false) { result, subscriber in
25
+ return subscriber.application?(application, willFinishLaunchingWithOptions: launchOptions) ?? false || result
26
+ }
27
+ }
28
+
29
+ open func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
30
+ return subscribers.reduce(false) { result, subscriber in
31
+ return subscriber.application?(application, didFinishLaunchingWithOptions: launchOptions) ?? false || result
32
+ }
33
+ }
34
+
35
+ // TODO: - Configuring and Discarding Scenes
36
+
37
+ // MARK: - Responding to App Life-Cycle Events
38
+
39
+ @objc
40
+ open func applicationDidBecomeActive(_ application: UIApplication) {
41
+ subscribers.forEach { $0.applicationDidBecomeActive?(application) }
42
+ }
43
+
44
+ @objc
45
+ open func applicationWillResignActive(_ application: UIApplication) {
46
+ subscribers.forEach { $0.applicationWillResignActive?(application) }
47
+ }
48
+
49
+ @objc
50
+ open func applicationDidEnterBackground(_ application: UIApplication) {
51
+ subscribers.forEach { $0.applicationDidEnterBackground?(application) }
52
+ }
53
+
54
+ open func applicationWillEnterForeground(_ application: UIApplication) {
55
+ subscribers.forEach { $0.applicationWillEnterForeground?(application) }
56
+ }
57
+
58
+ open func applicationWillTerminate(_ application: UIApplication) {
59
+ subscribers.forEach { $0.applicationWillTerminate?(application) }
60
+ }
61
+
62
+ // TODO: - Responding to Environment Changes
63
+
64
+ // TODO: - Managing App State Restoration
65
+
66
+ // MARK: - Downloading Data in the Background
67
+
68
+ open func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
69
+ let selector = #selector(application(_:handleEventsForBackgroundURLSession:completionHandler:))
70
+ let subs = subscribers.filter { $0.responds(to: selector) }
71
+ var subscribersLeft = subs.count
72
+ let dispatchQueue = DispatchQueue(label: "expo.application.handleBackgroundEvents")
73
+
74
+ let handler = {
75
+ dispatchQueue.sync {
76
+ subscribersLeft -= 1
77
+
78
+ if subscribersLeft == 0 {
79
+ completionHandler()
80
+ }
81
+ }
82
+ }
83
+
84
+ subs.forEach {
85
+ $0.application?(application, handleEventsForBackgroundURLSession: identifier, completionHandler: handler)
86
+ }
87
+ }
88
+
89
+ // MARK: - Handling Remote Notification Registration
90
+
91
+ open func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
92
+ subscribers.forEach { $0.application?(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken) }
93
+ }
94
+
95
+ open func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
96
+ subscribers.forEach { $0.application?(application, didFailToRegisterForRemoteNotificationsWithError: error) }
97
+ }
98
+
99
+ open func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
100
+ let selector = #selector(application(_:didReceiveRemoteNotification:fetchCompletionHandler:))
101
+ let subs = subscribers.filter { $0.responds(to: selector) }
102
+ var subscribersLeft = subs.count
103
+ var fetchResult: UIBackgroundFetchResult = .noData
104
+ let dispatchQueue = DispatchQueue(label: "expo.application.remoteNotification", qos: .userInteractive)
105
+
106
+ let handler = { (result: UIBackgroundFetchResult) in
107
+ dispatchQueue.sync {
108
+ if result == .failed {
109
+ fetchResult = .failed
110
+ } else if fetchResult != .failed && result == .newData {
111
+ fetchResult = .newData
112
+ }
113
+
114
+ subscribersLeft -= 1
115
+
116
+ if subscribersLeft == 0 {
117
+ completionHandler(fetchResult)
118
+ }
119
+ }
120
+ }
121
+
122
+ subs.forEach { subscriber in
123
+ subscriber.application?(application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: handler)
124
+ }
125
+ }
126
+
127
+ // MARK: - Continuing User Activity and Handling Quick Actions
128
+
129
+ open func application(_ application: UIApplication, willContinueUserActivityWithType userActivityType: String) -> Bool {
130
+ return subscribers.reduce(false) { result, subscriber in
131
+ return subscriber.application?(application, willContinueUserActivityWithType: userActivityType) ?? false || result
132
+ }
133
+ }
134
+
135
+ open func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
136
+ let selector = #selector(application(_:continue:restorationHandler:))
137
+ let subs = subscribers.filter { $0.responds(to: selector) }
138
+ var subscribersLeft = subs.count
139
+ let dispatchQueue = DispatchQueue(label: "expo.application.continueUserActivity", qos: .userInteractive)
140
+ var allRestorableObjects = [UIUserActivityRestoring]()
141
+
142
+ let handler = { (restorableObjects: [UIUserActivityRestoring]?) in
143
+ dispatchQueue.sync {
144
+ if let restorableObjects = restorableObjects {
145
+ allRestorableObjects.append(contentsOf: restorableObjects)
146
+ }
147
+
148
+ subscribersLeft -= 1
149
+
150
+ if subscribersLeft == 0 {
151
+ restorationHandler(allRestorableObjects)
152
+ }
153
+ }
154
+ }
155
+
156
+ return subs.reduce(false) { result, subscriber in
157
+ return subscriber.application?(application, continue: userActivity, restorationHandler: handler) ?? false || result
158
+ }
159
+ }
160
+
161
+ open func application(_ application: UIApplication, didUpdate userActivity: NSUserActivity) {
162
+ return subscribers.forEach { $0.application?(application, didUpdate: userActivity) }
163
+ }
164
+
165
+ open func application(_ application: UIApplication, didFailToContinueUserActivityWithType userActivityType: String, error: Error) {
166
+ return subscribers.forEach {
167
+ $0.application?(application, didFailToContinueUserActivityWithType: userActivityType, error: error)
168
+ }
169
+ }
170
+
171
+ open func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
172
+ let selector = #selector(application(_:performActionFor:completionHandler:))
173
+ let subs = subscribers.filter { $0.responds(to: selector) }
174
+ var subscribersLeft = subs.count
175
+ var result: Bool = false
176
+ let dispatchQueue = DispatchQueue(label: "expo.application.performAction", qos: .userInteractive)
177
+
178
+ let handler = { (succeeded: Bool) in
179
+ dispatchQueue.sync {
180
+ result = result || succeeded
181
+ subscribersLeft -= 1
182
+
183
+ if subscribersLeft == 0 {
184
+ completionHandler(result)
185
+ }
186
+ }
187
+ }
188
+
189
+ subs.forEach { subscriber in
190
+ subscriber.application?(application, performActionFor: shortcutItem, completionHandler: handler)
191
+ }
192
+ }
193
+
194
+ // MARK: - Background Fetch
195
+
196
+ open func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
197
+ let selector = #selector(application(_:performFetchWithCompletionHandler:))
198
+ let subs = subscribers.filter { $0.responds(to: selector) }
199
+ var subscribersLeft = subs.count
200
+ var fetchResult: UIBackgroundFetchResult = .noData
201
+ let dispatchQueue = DispatchQueue(label: "expo.application.performFetch", qos: .userInteractive)
202
+
203
+ let handler = { (result: UIBackgroundFetchResult) in
204
+ dispatchQueue.sync {
205
+ if result == .failed {
206
+ fetchResult = .failed
207
+ } else if fetchResult != .failed && result == .newData {
208
+ fetchResult = .newData
209
+ }
210
+
211
+ subscribersLeft -= 1
212
+
213
+ if subscribersLeft == 0 {
214
+ completionHandler(fetchResult)
215
+ }
216
+ }
217
+ }
218
+
219
+ subs.forEach { subscriber in
220
+ subscriber.application?(application, performFetchWithCompletionHandler: handler)
221
+ }
222
+ }
223
+
224
+ // TODO: - Interacting With WatchKit
225
+
226
+ // TODO: - Interacting With HealthKit
227
+
228
+ // MARK: - Opening a URL-Specified Resource
229
+
230
+ open func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
231
+ return subscribers.contains { subscriber in
232
+ return subscriber.application?(app, open: url, options: options) ?? false
233
+ }
234
+ }
235
+
236
+ // TODO: - Disallowing Specified App Extension Types
237
+
238
+ // TODO: - Handling SiriKit Intents
239
+
240
+ // TODO: - Handling CloudKit Invitations
241
+
242
+ // TODO: - Managing Interface Geometry
243
+
244
+ // MARK: - Statics
245
+
246
+ @objc
247
+ public static func registerSubscribersFrom(modulesProvider: ModulesProviderObjCProtocol) {
248
+ guard let provider = modulesProvider as? ModulesProviderProtocol else {
249
+ fatalError("Expo modules provider must implement `ModulesProviderProtocol`.")
250
+ }
251
+ provider.getAppDelegateSubscribers().forEach { subscriberType in
252
+ registerSubscriber(subscriberType.init())
253
+ }
254
+ }
255
+
256
+ @objc
257
+ public static func registerSubscriber(_ subscriber: ExpoAppDelegateSubscriberProtocol) {
258
+ if subscribers.contains(where: { $0 === subscriber }) {
259
+ fatalError("Given app delegate subscriber `\(String(describing: subscriber))` is already registered.")
260
+ }
261
+ subscribers.append(subscriber)
262
+ }
263
+
264
+ @objc
265
+ public static func getSubscriber(_ name: String) -> ExpoAppDelegateSubscriberProtocol? {
266
+ return subscribers.first { String(describing: $0) == name }
267
+ }
268
+
269
+ @objc
270
+ public static func registerReactDelegateHandlersFrom(modulesProvider: ModulesProviderObjCProtocol) {
271
+ guard let provider = modulesProvider as? ModulesProviderProtocol else {
272
+ fatalError("Expo modules provider must implement `ModulesProviderProtocol`.")
273
+ }
274
+ provider.getReactDelegateHandlers()
275
+ .sorted { (tuple1, tuple2) -> Bool in
276
+ return ModulePriorities.get(tuple1.packageName) > ModulePriorities.get(tuple2.packageName)
277
+ }
278
+ .forEach { handlerTuple in
279
+ reactDelegateHandlers.append(handlerTuple.handler.init())
280
+ }
281
+ }
282
+ }
@@ -0,0 +1,24 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ import UIKit
4
+
5
+ /**
6
+ Base class for app delegate subscribers. Ensures the class
7
+ inherits from `UIResponder` and has `required init()` initializer.
8
+ */
9
+ @objc(EXBaseAppDelegateSubscriber)
10
+ open class BaseExpoAppDelegateSubscriber: UIResponder {
11
+ public override required init() {}
12
+ }
13
+
14
+ /**
15
+ Typealias to `UIApplicationDelegate` protocol.
16
+ Might be useful for compatibility reasons if we decide to add more things here.
17
+ */
18
+ @objc(EXAppDelegateSubscriberProtocol)
19
+ public protocol ExpoAppDelegateSubscriberProtocol: UIApplicationDelegate {}
20
+
21
+ /**
22
+ Typealias merging the base class for app delegate subscribers and protocol inheritance to `UIApplicationDelegate`.
23
+ */
24
+ public typealias ExpoAppDelegateSubscriber = BaseExpoAppDelegateSubscriber & ExpoAppDelegateSubscriberProtocol
@@ -0,0 +1,26 @@
1
+ // Copyright 2016-present 650 Industries. All rights reserved.
2
+
3
+ #import <Foundation/Foundation.h>
4
+
5
+ NS_ASSUME_NONNULL_BEGIN
6
+
7
+ /**
8
+ For expo modules to get app build time preprocessor values.
9
+ We ship some modules in [prebuilt binaries](https://expo.fyi/prebuilt-modules),
10
+ classic defines like `DEBUG` or `RCT_DEV` may not work as expected
11
+ because the prebuilt modules are always built with Release configuration.
12
+ This class acts as a supporter to get app build time preprocessor values.
13
+ */
14
+ @interface EXAppDefines : NSObject
15
+
16
+ @property (class, nonatomic, assign, readonly) BOOL APP_DEBUG NS_SWIFT_NAME(APP_DEBUG);
17
+ @property (class, nonatomic, assign, readonly) BOOL APP_RCT_DEBUG NS_SWIFT_NAME(APP_RCT_DEBUG);
18
+ @property (class, nonatomic, assign, readonly) BOOL APP_RCT_DEV NS_SWIFT_NAME(APP_RCT_DEV);
19
+
20
+ + (NSDictionary *)getAllDefines;
21
+
22
+ + (void)load:(NSDictionary *)defines;
23
+
24
+ @end
25
+
26
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,61 @@
1
+ // Copyright 2016-present 650 Industries. All rights reserved.
2
+
3
+ #import <ExpoModulesCore/EXAppDefines.h>
4
+ #import <React/RCTDefines.h>
5
+
6
+ @implementation EXAppDefines
7
+
8
+ static NSDictionary *_storage;
9
+ static BOOL _loaded = NO;
10
+
11
+ + (BOOL)APP_DEBUG
12
+ {
13
+ [self throwIfNotLoaded];
14
+ return [_storage[@"APP_DEBUG"] boolValue];
15
+ }
16
+
17
+ + (BOOL)APP_RCT_DEBUG
18
+ {
19
+ [self throwIfNotLoaded];
20
+ return [_storage[@"APP_RCT_DEBUG"] boolValue];
21
+ }
22
+
23
+ + (BOOL)APP_RCT_DEV
24
+ {
25
+ [self throwIfNotLoaded];
26
+ return [_storage[@"APP_RCT_DEV"] boolValue];
27
+ }
28
+
29
+ + (NSDictionary *)getAllDefines
30
+ {
31
+ return _storage;
32
+ }
33
+
34
+ + (void)load:(NSDictionary *)defines
35
+ {
36
+ NSAssert([NSThread isMainThread], @"This function must be called on main thread");
37
+ NSAssert(!_loaded, @"EXAppDefines is already loaded");
38
+ if (!_loaded) {
39
+ _storage = defines;
40
+ _loaded = YES;
41
+ }
42
+ }
43
+
44
+ // Private function for EXAppDefinesTest to unload the current state.
45
+ + (void)_unload
46
+ {
47
+ _storage = nil;
48
+ _loaded = NO;
49
+ }
50
+
51
+ + (void)throwIfNotLoaded
52
+ {
53
+ if (!_loaded) {
54
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
55
+ reason:@"EXAppDefines is not loaded."
56
+ userInfo:nil];
57
+ }
58
+ }
59
+
60
+
61
+ @end
@@ -18,24 +18,29 @@ Pod::Spec.new do |s|
18
18
 
19
19
  # Swift/Objective-C compatibility
20
20
  s.pod_target_xcconfig = {
21
- 'DEFINES_MODULE' => 'YES'
21
+ 'USE_HEADERMAP' => 'YES',
22
+ 'DEFINES_MODULE' => 'YES',
23
+ 'CLANG_CXX_LANGUAGE_STANDARD' => 'c++14',
24
+ 'SWIFT_COMPILATION_MODE' => 'wholemodule',
22
25
  }
23
26
 
24
27
  s.dependency 'React-Core'
28
+ s.dependency 'ReactCommon/turbomodule/core'
25
29
 
26
30
  if !$ExpoUseSources&.include?(package['name']) && ENV['EXPO_USE_SOURCE'].to_i == 0 && File.exist?("#{s.name}.xcframework") && Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.10.0')
27
31
  s.source_files = '**/*.h'
28
32
  s.vendored_frameworks = "#{s.name}.xcframework"
29
33
  else
30
- s.source_files = '**/*.{h,m,swift}'
34
+ s.source_files = '**/*.{h,m,mm,swift}'
31
35
  end
32
36
 
33
37
  s.exclude_files = 'Tests/'
38
+ s.private_header_files = ['**/*+Private.h', '**/Swift.h']
34
39
 
35
40
  s.test_spec 'Tests' do |test_spec|
36
41
  test_spec.dependency 'Quick'
37
42
  test_spec.dependency 'Nimble'
38
43
 
39
- test_spec.source_files = 'Tests/**/*.swift'
44
+ test_spec.source_files = 'Tests/**/*.{m,swift}'
40
45
  end
41
46
  end
@@ -0,0 +1,24 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ #ifdef __cplusplus
4
+
5
+ #import <jsi/jsi.h>
6
+ #import <ReactCommon/RCTTurboModule.h>
7
+
8
+ #import <ExpoModulesCore/EXNativeModulesProxy.h>
9
+
10
+ using namespace facebook;
11
+ using namespace react;
12
+
13
+ namespace expo {
14
+
15
+ class JSI_EXPORT ExpoModulesProxySpec : public TurboModule {
16
+ public:
17
+ ExpoModulesProxySpec(std::shared_ptr<CallInvoker> callInvoker, EXNativeModulesProxy *nativeModulesProxy);
18
+
19
+ EXNativeModulesProxy *nativeModulesProxy;
20
+ };
21
+
22
+ } // namespace expo
23
+
24
+ #endif