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.
- package/CHANGELOG.md +39 -0
- package/README.md +6 -6
- package/android/build.gradle +30 -2
- package/android/src/main/java/expo/modules/adapters/react/ModuleRegistryAdapter.java +27 -5
- package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +49 -5
- package/android/src/main/java/expo/modules/core/BasePackage.java +6 -0
- package/android/src/main/java/expo/modules/core/ModulePriorities.kt +25 -0
- package/android/src/main/java/expo/modules/core/interfaces/ActivityEventListener.java +3 -1
- package/android/src/main/java/expo/modules/core/interfaces/ApplicationLifecycleListener.java +10 -0
- package/android/src/main/java/expo/modules/core/interfaces/Package.java +4 -0
- package/android/src/main/java/expo/modules/core/interfaces/ReactActivityHandler.java +21 -0
- package/android/src/main/java/expo/modules/core/interfaces/ReactActivityLifecycleListener.java +14 -0
- package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.java +70 -0
- package/android/src/main/java/expo/modules/core/utilities/KotlinUtilities.kt +23 -0
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +166 -0
- package/android/src/main/java/expo/modules/kotlin/DynamicExtenstions.kt +9 -0
- package/android/src/main/java/expo/modules/kotlin/ExpoModulesHelper.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/KPromiseWrapper.kt +24 -0
- package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +98 -0
- package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +41 -0
- package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +56 -0
- package/android/src/main/java/expo/modules/kotlin/ModulesProvider.kt +7 -0
- package/android/src/main/java/expo/modules/kotlin/Promise.kt +13 -0
- package/android/src/main/java/expo/modules/kotlin/ReactLifecycleDelegate.kt +39 -0
- package/android/src/main/java/expo/modules/kotlin/ReadableArrayIterator.kt +14 -0
- package/android/src/main/java/expo/modules/kotlin/ReadableTypeExtensions.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/allocators/ObjectConstructor.kt +5 -0
- package/android/src/main/java/expo/modules/kotlin/allocators/ObjectConstructorFactory.kt +31 -0
- package/android/src/main/java/expo/modules/kotlin/allocators/UnsafeAllocator.kt +49 -0
- package/android/src/main/java/expo/modules/kotlin/events/EventListener.kt +39 -0
- package/android/src/main/java/expo/modules/kotlin/events/EventName.kt +31 -0
- package/android/src/main/java/expo/modules/kotlin/events/EventsDefinition.kt +3 -0
- package/android/src/main/java/expo/modules/kotlin/events/KEventEmitterWrapper.kt +26 -0
- package/android/src/main/java/expo/modules/kotlin/events/OnActivityResultPayload.kt +8 -0
- package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +70 -0
- package/android/src/main/java/expo/modules/kotlin/methods/AnyMethod.kt +50 -0
- package/android/src/main/java/expo/modules/kotlin/methods/Method.kt +14 -0
- package/android/src/main/java/expo/modules/kotlin/methods/PromiseMethod.kt +15 -0
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +24 -0
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +227 -0
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +16 -0
- package/android/src/main/java/expo/modules/kotlin/records/Field.kt +5 -0
- package/android/src/main/java/expo/modules/kotlin/records/Record.kt +3 -0
- package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +55 -0
- package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +14 -0
- package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +44 -0
- package/android/src/main/java/expo/modules/kotlin/types/BasicTypeConverters.kt +60 -0
- package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +84 -0
- package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +25 -0
- package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +39 -0
- package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +28 -0
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +19 -0
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +107 -0
- package/android/src/main/java/expo/modules/kotlin/views/AnyViewProp.kt +10 -0
- package/android/src/main/java/expo/modules/kotlin/views/ConcreteViewProp.kt +17 -0
- package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +22 -0
- package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +41 -0
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +40 -0
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/views/ViewWrapperDelegateHolder.kt +5 -0
- package/build/NativeModulesProxy.native.d.ts +4 -0
- package/build/NativeModulesProxy.native.js +14 -1
- package/build/NativeModulesProxy.native.js.map +1 -1
- package/build/NativeModulesProxy.types.d.ts +3 -0
- package/build/NativeModulesProxy.types.js.map +1 -1
- package/build/NativeViewManagerAdapter.native.js +1 -1
- package/build/NativeViewManagerAdapter.native.js.map +1 -1
- package/ios/AppDelegates/EXAppDelegateWrapper.h +19 -0
- package/ios/AppDelegates/EXAppDelegateWrapper.m +45 -0
- package/ios/AppDelegates/EXAppDelegatesLoader.h +15 -0
- package/ios/AppDelegates/EXAppDelegatesLoader.m +30 -0
- package/ios/AppDelegates/EXLegacyAppDelegateWrapper.h +16 -0
- package/ios/{EXAppDelegateWrapper.m → AppDelegates/EXLegacyAppDelegateWrapper.m} +2 -2
- package/ios/AppDelegates/ExpoAppDelegate.swift +282 -0
- package/ios/AppDelegates/ExpoAppDelegateSubscriber.swift +24 -0
- package/ios/EXAppDefines.h +26 -0
- package/ios/EXAppDefines.m +61 -0
- package/ios/ExpoModulesCore.podspec +8 -3
- package/ios/JSI/ExpoModulesProxySpec.h +24 -0
- package/ios/JSI/ExpoModulesProxySpec.mm +135 -0
- package/ios/JSI/JSIConversions.h +42 -0
- package/ios/JSI/JSIConversions.mm +164 -0
- package/ios/JSI/JSIInstaller.h +19 -0
- package/ios/JSI/JSIInstaller.mm +22 -0
- package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +1 -6
- package/ios/NativeModulesProxy/EXNativeModulesProxy.h +6 -0
- package/ios/NativeModulesProxy/{EXNativeModulesProxy.m → EXNativeModulesProxy.mm} +91 -18
- package/ios/ReactDelegates/EXRCTBridgeDelegateInterceptor.h +16 -0
- package/ios/ReactDelegates/EXRCTBridgeDelegateInterceptor.m +49 -0
- package/ios/ReactDelegates/EXReactDelegateWrapper+Private.h +18 -0
- package/ios/ReactDelegates/EXReactDelegateWrapper.h +25 -0
- package/ios/ReactDelegates/EXReactDelegateWrapper.m +40 -0
- package/ios/ReactDelegates/ExpoReactDelegate.swift +37 -0
- package/ios/ReactDelegates/ExpoReactDelegateHandler.swift +52 -0
- package/ios/ReactDelegates/ModulePriorities.swift +20 -0
- package/ios/Services/EXReactNativeEventEmitter.h +6 -0
- package/ios/Services/EXReactNativeEventEmitter.m +15 -0
- package/ios/Swift/AppContext.swift +14 -1
- package/ios/Swift/Arguments/AnyArgument.swift +14 -0
- package/ios/Swift/Arguments/AnyArgumentType.swift +13 -0
- package/ios/Swift/Arguments/ArgumentType.swift +24 -0
- package/ios/Swift/Arguments/ConvertibleArgument.swift +15 -0
- package/ios/Swift/Arguments/Convertibles.swift +107 -0
- package/ios/Swift/Arguments/Types/ArrayArgumentType.swift +42 -0
- package/ios/Swift/Arguments/Types/ConvertibleArgumentType.swift +16 -0
- package/ios/Swift/Arguments/Types/EnumArgumentType.swift +105 -0
- package/ios/Swift/Arguments/Types/OptionalArgumentType.swift +49 -0
- package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +15 -0
- package/ios/Swift/Arguments/Types/RawArgumentType.swift +25 -0
- package/ios/Swift/Conversions.swift +199 -7
- package/ios/Swift/EventListener.swift +37 -5
- package/ios/Swift/Functions/AnyFunction.swift +42 -0
- package/ios/Swift/{Methods/ConcreteMethod.swift → Functions/ConcreteFunction.swift} +32 -34
- package/ios/Swift/ModuleHolder.swift +86 -20
- package/ios/Swift/ModuleRegistry.swift +19 -8
- package/ios/Swift/Modules/AnyModule.swift +8 -8
- package/ios/Swift/Modules/Module.swift +11 -0
- package/ios/Swift/Modules/ModuleDefinition.swift +55 -15
- package/ios/Swift/Modules/ModuleDefinitionBuilder.swift +1 -1
- package/ios/Swift/Modules/ModuleDefinitionComponents.swift +149 -54
- package/ios/Swift/ModulesProvider.swift +19 -0
- package/ios/Swift/Promise.swift +1 -1
- package/ios/Swift/Records/Field.swift +1 -1
- package/ios/Swift/Records/Record.swift +8 -1
- package/ios/Swift/SwiftInteropBridge.swift +46 -17
- package/ios/Swift/Views/AnyViewProp.swift +2 -2
- package/ios/Swift/Views/ConcreteViewProp.swift +37 -10
- package/ios/Swift/Views/ViewModuleWrapper.swift +9 -4
- package/ios/Swift.h +9 -0
- package/ios/Tests/ArgumentTypeSpec.swift +145 -0
- package/ios/Tests/ConstantsSpec.swift +36 -0
- package/ios/Tests/ConvertiblesSpec.swift +265 -0
- package/ios/Tests/EXAppDefinesTest.m +99 -0
- package/ios/Tests/{MethodSpec.swift → FunctionSpec.swift} +69 -54
- package/ios/Tests/FunctionWithConvertiblesSpec.swift +66 -0
- package/ios/Tests/Mocks/ModuleMocks.swift +21 -7
- package/ios/Tests/ModuleEventListenersSpec.swift +17 -16
- package/ios/Tests/ModuleRegistrySpec.swift +4 -7
- package/package.json +3 -3
- package/src/NativeModulesProxy.native.ts +22 -2
- package/src/NativeModulesProxy.types.ts +8 -0
- package/src/NativeViewManagerAdapter.native.tsx +1 -1
- package/android/src/main/java/expo/modules/core/interfaces/ApplicationLifecycleListener.kt +0 -9
- package/android/src/main/java/expo/modules/core/interfaces/ReactActivityLifecycleListener.kt +0 -11
- package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.kt +0 -51
- package/ios/EXAppDelegateWrapper.h +0 -13
- package/ios/Swift/Methods/AnyArgumentType.swift +0 -48
- package/ios/Swift/Methods/AnyMethod.swift +0 -31
- 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/
|
|
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
|
|
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
|
-
'
|
|
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
|