expo-modules-core 2.1.2 → 2.1.4

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 CHANGED
@@ -10,6 +10,20 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 2.1.4 — 2025-01-19
14
+
15
+ ### 🎉 New features
16
+
17
+ - support RN 0.77 in SDK 52 ([#34088](https://github.com/expo/expo/pull/34088) by [@vonovak](https://github.com/vonovak))
18
+
19
+ ### 💡 Others
20
+
21
+ - Allowed extending `process.env` types. ([#34112](https://github.com/expo/expo/pull/34112) by [@kudo](https://github.com/kudo))
22
+
23
+ ## 2.1.3 — 2025-01-10
24
+
25
+ _This version does not introduce any user-facing changes._
26
+
13
27
  ## 2.1.2 — 2024-12-16
14
28
 
15
29
  ### 🐛 Bug fixes
@@ -92,6 +92,10 @@ Pod::Spec.new do |s|
92
92
  s.dependency 'React-NativeModulesApple'
93
93
  s.dependency 'React-RCTFabric'
94
94
 
95
+ if reactNativeTargetVersion >= 77
96
+ s.dependency 'ReactAppDependencyProvider'
97
+ end
98
+
95
99
  install_modules_dependencies(s)
96
100
 
97
101
  s.source_files = 'ios/**/*.{h,m,mm,swift,cpp}', 'common/cpp/**/*.{h,cpp}'
@@ -3,7 +3,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
3
3
  apply plugin: 'com.android.library'
4
4
 
5
5
  group = 'host.exp.exponent'
6
- version = '2.1.2'
6
+ version = '2.1.4'
7
7
 
8
8
  def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
9
9
  apply from: expoModulesCorePlugin
@@ -67,7 +67,7 @@ android {
67
67
  defaultConfig {
68
68
  consumerProguardFiles 'proguard-rules.pro'
69
69
  versionCode 1
70
- versionName "2.1.2"
70
+ versionName "2.1.4"
71
71
  buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled.toString()
72
72
 
73
73
  testInstrumentationRunner "expo.modules.TestRunner"
@@ -47,29 +47,37 @@ type ViewConfig = {
47
47
  registrationName: string;
48
48
  }>;
49
49
  };
50
+ export interface ExpoProcessEnv {
51
+ NODE_ENV: string;
52
+ /** Used in `@expo/metro-runtime`. */
53
+ EXPO_DEV_SERVER_ORIGIN?: string;
54
+ EXPO_ROUTER_IMPORT_MODE?: string;
55
+ EXPO_ROUTER_ABS_APP_ROOT?: string;
56
+ EXPO_ROUTER_APP_ROOT?: string;
57
+ /** Maps to the `experiments.baseUrl` property in the project Expo config. This is injected by `babel-preset-expo` and supports automatic cache invalidation. */
58
+ EXPO_BASE_URL?: string;
59
+ /** Build-time representation of the `Platform.OS` value that the current JavaScript was bundled for. Does not support platform shaking wrapped require statements. */
60
+ EXPO_OS?: string;
61
+ [key: string]: any;
62
+ }
50
63
  export interface ExpoProcess {
51
- env: {
52
- NODE_ENV: string;
53
- /** Used in `@expo/metro-runtime`. */
54
- EXPO_DEV_SERVER_ORIGIN?: string;
55
- EXPO_ROUTER_IMPORT_MODE?: string;
56
- EXPO_ROUTER_ABS_APP_ROOT?: string;
57
- EXPO_ROUTER_APP_ROOT?: string;
58
- /** Maps to the `experiments.baseUrl` property in the project Expo config. This is injected by `babel-preset-expo` and supports automatic cache invalidation. */
59
- EXPO_BASE_URL?: string;
60
- /** Build-time representation of the `Platform.OS` value that the current JavaScript was bundled for. Does not support platform shaking wrapped require statements. */
61
- EXPO_OS?: string;
62
- [key: string]: any;
63
- };
64
+ env: ExpoProcessEnv;
64
65
  [key: string]: any;
65
66
  }
66
67
  declare global {
68
+ namespace NodeJS {
69
+ interface ProcessEnv extends ExpoProcessEnv {
70
+ }
71
+ interface Process extends ExpoProcess {
72
+ env: ProcessEnv;
73
+ }
74
+ }
67
75
  /**
68
76
  * Global object containing all the native bindings installed by Expo.
69
77
  * This object is not available in projects without the `expo` package installed.
70
78
  */
71
79
  var expo: ExpoGlobal;
72
- var process: ExpoProcess;
80
+ var process: NodeJS.Process;
73
81
  /**
74
82
  * ExpoDomWebView is defined in `@expo/dom-webview` runtime.
75
83
  */
@@ -1 +1 @@
1
- {"version":3,"file":"global.d.ts","sourceRoot":"","sources":["../../src/ts-declarations/global.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAI7B;;OAEG;IACH,YAAY,EAAE,OAAO,YAAY,CAAC;IAElC;;OAEG;IACH,YAAY,EAAE,OAAO,YAAY,CAAC;IAElC;;OAEG;IACH,SAAS,EAAE,OAAO,SAAS,CAAC;IAE5B;;OAEG;IACH,YAAY,EAAE,OAAO,YAAY,CAAC;IAIlC;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC;IAEjB;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAEhD;;;OAGG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC;IAEnD;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,KAAK,UAAU,GAAG;IAChB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChE,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE;QACH,QAAQ,EAAE,MAAM,CAAC;QACjB,qCAAqC;QACrC,sBAAsB,CAAC,EAAE,MAAM,CAAC;QAEhC,uBAAuB,CAAC,EAAE,MAAM,CAAC;QACjC,wBAAwB,CAAC,EAAE,MAAM,CAAC;QAClC,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAE9B,gKAAgK;QAChK,aAAa,CAAC,EAAE,MAAM,CAAC;QAEvB,sKAAsK;QACtK,OAAO,CAAC,EAAE,MAAM,CAAC;QAEjB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAID,OAAO,CAAC,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,IAAI,EAAE,UAAU,CAAC;IAGrB,IAAI,OAAO,EAAE,WAAW,CAAC;IAEzB;;OAEG;IACH,IAAI,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC;CACrD"}
1
+ {"version":3,"file":"global.d.ts","sourceRoot":"","sources":["../../src/ts-declarations/global.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAI7B;;OAEG;IACH,YAAY,EAAE,OAAO,YAAY,CAAC;IAElC;;OAEG;IACH,YAAY,EAAE,OAAO,YAAY,CAAC;IAElC;;OAEG;IACH,SAAS,EAAE,OAAO,SAAS,CAAC;IAE5B;;OAEG;IACH,YAAY,EAAE,OAAO,YAAY,CAAC;IAIlC;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC;IAEjB;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAEhD;;;OAGG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC;IAEnD;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,KAAK,UAAU,GAAG;IAChB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChE,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAE9B,gKAAgK;IAChK,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,sKAAsK;IACtK,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,cAAc,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAID,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM,CAAC;QACf,UAAiB,UAAW,SAAQ,cAAc;SAAG;QACrD,UAAiB,OAAQ,SAAQ,WAAW;YAC1C,GAAG,EAAE,UAAU,CAAC;SACjB;KACF;IAED;;;OAGG;IACH,IAAI,IAAI,EAAE,UAAU,CAAC;IAErB,IAAI,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC;IAE5B;;OAEG;IACH,IAAI,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC;CACrD"}
@@ -6,10 +6,23 @@
6
6
 
7
7
  NS_ASSUME_NONNULL_BEGIN
8
8
 
9
+ @interface RCTAppDelegate ()
10
+
11
+ - (RCTRootViewFactory *)createRCTRootViewFactory;
12
+
13
+ @end
14
+
9
15
  @interface EXAppDelegateWrapper : RCTAppDelegate
10
16
 
11
17
  @property (nonatomic, strong, readonly) EXReactDelegateWrapper *reactDelegate;
12
18
 
19
+ /**
20
+ Currently (RN 0.76) `customizeRootView` signature in `RCTAppDelegate` is broken as it uses `RCTRootView` type,
21
+ but this type is no longer used. It should rather be `RCTSurfaceHostingView`, but for simplicity it could be just `UIView`.
22
+ We need a helper function in Objective-C to actually make it to work, otherwise the types will conflict in Swift.
23
+ */
24
+ + (void)customizeRootView:(nonnull UIView *)rootView byAppDelegate:(nonnull RCTAppDelegate *)appDelegate;
25
+
13
26
  @end
14
27
 
15
28
  NS_ASSUME_NONNULL_END
@@ -9,22 +9,14 @@
9
9
  #import <React/RCTComponentViewFactory.h> // Allows non-umbrella since it's coming from React-RCTFabric
10
10
  #import <ReactCommon/RCTHost.h> // Allows non-umbrella because the header is not inside a clang module
11
11
 
12
+ // TODO remove the if when 76 is not supported, or rather remove the EXAppDelegateWrapper because it's deprecated
13
+ #if __has_include(<ReactAppDependencyProvider/RCTAppDependencyProvider.h>)
14
+ #import <ReactAppDependencyProvider/RCTAppDependencyProvider.h>
15
+ #endif
12
16
 
13
17
  @interface RCTAppDelegate () <RCTComponentViewFactoryComponentProvider, RCTHostDelegate>
14
18
  @end
15
19
 
16
- @interface RCTRootViewFactoryConfiguration ()
17
-
18
- - (void)setCustomizeRootView:(void (^)(UIView *rootView))customizeRootView;
19
-
20
- @end
21
-
22
- @interface EXAppDelegateWrapper()
23
-
24
- @property (nonatomic, strong) EXReactDelegateWrapper *reactDelegate;
25
-
26
- @end
27
-
28
20
  @implementation EXAppDelegateWrapper {
29
21
  EXExpoAppDelegate *_expoAppDelegate;
30
22
  }
@@ -33,7 +25,7 @@
33
25
  {
34
26
  if (self = [super init]) {
35
27
  _expoAppDelegate = [[EXExpoAppDelegate alloc] init];
36
- _reactDelegate = [[EXReactDelegateWrapper alloc] initWithExpoReactDelegate:_expoAppDelegate.reactDelegate];
28
+ _expoAppDelegate.shouldCallReactNativeSetup = NO;
37
29
  }
38
30
  return self;
39
31
  }
@@ -43,8 +35,7 @@
43
35
  // which `UIApplicationDelegate` selectors are implemented.
44
36
  - (BOOL)respondsToSelector:(SEL)selector
45
37
  {
46
- return [super respondsToSelector:selector]
47
- || [_expoAppDelegate respondsToSelector:selector];
38
+ return [super respondsToSelector:selector] || [_expoAppDelegate respondsToSelector:selector];
48
39
  }
49
40
 
50
41
  // Forwards all invocations to `ExpoAppDelegate` object.
@@ -53,89 +44,48 @@
53
44
  return _expoAppDelegate;
54
45
  }
55
46
 
56
- #if !TARGET_OS_OSX
47
+ #pragma mark - RCTAppDelegate
48
+
49
+ // Make sure to override all necessary methods from `RCTAppDelegate` here, explicitly forwarding everything to `_expoAppDelegate`.
50
+ // `forwardingTargetForSelector` works only for methods that are not specified in this and `RCTAppDelegate` classes.
51
+
57
52
  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
58
53
  {
54
+ #if __has_include(<ReactAppDependencyProvider/RCTAppDependencyProvider.h>)
55
+ self.dependencyProvider = [RCTAppDependencyProvider new];
56
+ #endif
59
57
  [super application:application didFinishLaunchingWithOptions:launchOptions];
60
- #pragma clang diagnostic push
61
- #pragma clang diagnostic ignored "-Wunused-result"
62
- [_expoAppDelegate application:application didFinishLaunchingWithOptions:launchOptions];
63
- #pragma clang diagnostic pop
64
- return YES;
58
+ return [_expoAppDelegate application:application didFinishLaunchingWithOptions:launchOptions];
59
+ }
60
+
61
+ - (void)applicationDidBecomeActive:(UIApplication *)application
62
+ {
63
+ return [_expoAppDelegate applicationDidBecomeActive:application];
65
64
  }
66
- #endif // !TARGET_OS_OSX
67
65
 
68
66
  - (UIViewController *)createRootViewController
69
67
  {
70
- return [self.reactDelegate createRootViewController];
68
+ return [_expoAppDelegate createRootViewController];
71
69
  }
72
70
 
73
71
  - (RCTRootViewFactory *)createRCTRootViewFactory
74
72
  {
75
- __weak __typeof(self) weakSelf = self;
76
- RCTBundleURLBlock bundleUrlBlock = ^{
77
- RCTAppDelegate *strongSelf = weakSelf;
78
- return strongSelf.bundleURL;
79
- };
80
-
81
- RCTRootViewFactoryConfiguration *configuration =
82
- [[RCTRootViewFactoryConfiguration alloc] initWithBundleURLBlock:bundleUrlBlock
83
- newArchEnabled:self.newArchEnabled
84
- turboModuleEnabled:self.newArchEnabled
85
- bridgelessEnabled:self.newArchEnabled];
86
-
87
- configuration.createRootViewWithBridge = ^UIView *(RCTBridge *bridge, NSString *moduleName, NSDictionary *initProps)
88
- {
89
- return [weakSelf createRootViewWithBridge:bridge moduleName:moduleName initProps:initProps];
90
- };
91
-
92
- configuration.createBridgeWithDelegate = ^RCTBridge *(id<RCTBridgeDelegate> delegate, NSDictionary *launchOptions)
93
- {
94
- return [weakSelf createBridgeWithDelegate:delegate launchOptions:launchOptions];
95
- };
96
-
97
- configuration.customizeRootView = ^(UIView *_Nonnull rootView) {
98
- [weakSelf customizeRootView:(RCTRootView *)rootView];
99
- };
100
-
101
- // NOTE(kudo): `sourceURLForBridge` is not referenced intentionally because it does not support New Architecture.
102
- configuration.sourceURLForBridge = nil;
103
-
104
- if ([self respondsToSelector:@selector(extraModulesForBridge:)]) {
105
- configuration.extraModulesForBridge = ^NSArray<id<RCTBridgeModule>> *_Nonnull(RCTBridge *_Nonnull bridge)
106
- {
107
- return [weakSelf extraModulesForBridge:bridge];
108
- };
109
- }
110
-
111
- if ([self respondsToSelector:@selector(extraLazyModuleClassesForBridge:)]) {
112
- configuration.extraLazyModuleClassesForBridge =
113
- ^NSDictionary<NSString *, Class> *_Nonnull(RCTBridge *_Nonnull bridge)
114
- {
115
- return [weakSelf extraLazyModuleClassesForBridge:bridge];
116
- };
117
- }
118
-
119
- if ([self respondsToSelector:@selector(bridge:didNotFindModule:)]) {
120
- configuration.bridgeDidNotFindModule = ^BOOL(RCTBridge *_Nonnull bridge, NSString *_Nonnull moduleName) {
121
- return [weakSelf bridge:bridge didNotFindModule:moduleName];
122
- };
123
- }
124
-
125
- return [[EXReactRootViewFactory alloc] initWithReactDelegate:self.reactDelegate configuration:configuration turboModuleManagerDelegate:self];
73
+ return [_expoAppDelegate createRCTRootViewFactory];
126
74
  }
127
75
 
128
- #if !TARGET_OS_OSX
129
- - (void)customizeRootView:(UIView *)rootView {
76
+ - (void)customizeRootView:(UIView *)rootView
77
+ {
130
78
  [_expoAppDelegate customizeRootView:rootView];
131
79
  }
132
- #endif // !TARGET_OS_OSX
133
80
 
134
81
  #pragma mark - RCTComponentViewFactoryComponentProvider
135
82
 
136
83
  - (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents
137
84
  {
138
- return @{};
85
+ #if __has_include(<ReactAppDependencyProvider/RCTAppDependencyProvider.h>)
86
+ return self.dependencyProvider.thirdPartyFabricComponents;
87
+ #endif
88
+ return @{};
139
89
  }
140
90
 
141
91
  #pragma mark - RCTHostDelegate
@@ -152,4 +102,11 @@
152
102
  {
153
103
  }
154
104
 
105
+ #pragma mark - Helpers
106
+
107
+ + (void)customizeRootView:(nonnull UIView *)rootView byAppDelegate:(nonnull RCTAppDelegate *)appDelegate
108
+ {
109
+ [appDelegate customizeRootView:(RCTRootView *)rootView];
110
+ }
111
+
155
112
  @end
@@ -1,8 +1,13 @@
1
1
  import Dispatch
2
2
  import Foundation
3
+ import React_RCTAppDelegate
4
+
5
+ // TODO(vonovak,20250107) - Remove the if expression when we drop SDK 52 / RN 76 support
6
+ #if canImport(ReactAppDependencyProvider)
7
+ import ReactAppDependencyProvider
8
+ #endif
3
9
 
4
10
  var subscribers = [ExpoAppDelegateSubscriberProtocol]()
5
- var reactDelegateHandlers = [ExpoReactDelegateHandler]()
6
11
 
7
12
  /**
8
13
  Allows classes extending `ExpoAppDelegateSubscriber` to hook into project's app delegate
@@ -11,16 +16,22 @@ var reactDelegateHandlers = [ExpoReactDelegateHandler]()
11
16
  Keep functions and markers in sync with https://developer.apple.com/documentation/uikit/uiapplicationdelegate
12
17
  */
13
18
  @objc(EXExpoAppDelegate)
14
- open class ExpoAppDelegate: UIResponder, UIApplicationDelegate {
15
- open var window: UIWindow?
16
-
19
+ open class ExpoAppDelegate: ExpoAppInstance {
20
+ /**
21
+ Whether to skip calling the React Native instance setup from `RCTAppDelegate`.
22
+ Set this property to `false` if your app delegate is not supposed to initialize a React Native app,
23
+ but only to handle the app delegate subscribers.
24
+ */
17
25
  @objc
18
- public let reactDelegate = ExpoReactDelegate(handlers: reactDelegateHandlers)
26
+ public var shouldCallReactNativeSetup: Bool = true
19
27
 
20
28
  #if os(iOS) || os(tvOS)
21
29
  // MARK: - Initializing the App
22
30
 
23
- open func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
31
+ open override func application(
32
+ _ application: UIApplication,
33
+ willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
34
+ ) -> Bool {
24
35
  let parsedSubscribers = subscribers.filter {
25
36
  $0.responds(to: #selector(application(_:willFinishLaunchingWithOptions:)))
26
37
  }
@@ -37,10 +48,22 @@ open class ExpoAppDelegate: UIResponder, UIApplicationDelegate {
37
48
  }
38
49
  }
39
50
 
40
- open func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
41
- return subscribers.reduce(false) { result, subscriber in
42
- return subscriber.application?(application, didFinishLaunchingWithOptions: launchOptions) ?? false || result
51
+ open override func application(
52
+ _ application: UIApplication,
53
+ didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
54
+ ) -> Bool {
55
+ #if canImport(ReactAppDependencyProvider)
56
+ self.dependencyProvider = RCTAppDependencyProvider()
57
+ #endif
58
+ if shouldCallReactNativeSetup {
59
+ super.application(application, didFinishLaunchingWithOptions: launchOptions)
60
+ }
61
+
62
+ subscribers.forEach { subscriber in
63
+ // Subscriber result is ignored as it doesn't matter if any subscriber handled the incoming URL – we always return `true` anyway.
64
+ _ = subscriber.application?(application, didFinishLaunchingWithOptions: launchOptions)
43
65
  }
66
+ return true
44
67
  }
45
68
 
46
69
  // TODO: - Configuring and Discarding Scenes
@@ -48,39 +71,39 @@ open class ExpoAppDelegate: UIResponder, UIApplicationDelegate {
48
71
  // MARK: - Responding to App Life-Cycle Events
49
72
 
50
73
  @objc
51
- open func applicationDidBecomeActive(_ application: UIApplication) {
74
+ open override func applicationDidBecomeActive(_ application: UIApplication) {
52
75
  subscribers.forEach { $0.applicationDidBecomeActive?(application) }
53
76
  }
54
77
 
55
78
  @objc
56
- open func applicationWillResignActive(_ application: UIApplication) {
79
+ open override func applicationWillResignActive(_ application: UIApplication) {
57
80
  subscribers.forEach { $0.applicationWillResignActive?(application) }
58
81
  }
59
82
 
60
83
  @objc
61
- open func applicationDidEnterBackground(_ application: UIApplication) {
84
+ open override func applicationDidEnterBackground(_ application: UIApplication) {
62
85
  subscribers.forEach { $0.applicationDidEnterBackground?(application) }
63
86
  }
64
87
 
65
- open func applicationWillEnterForeground(_ application: UIApplication) {
88
+ open override func applicationWillEnterForeground(_ application: UIApplication) {
66
89
  subscribers.forEach { $0.applicationWillEnterForeground?(application) }
67
90
  }
68
91
 
69
- open func applicationWillTerminate(_ application: UIApplication) {
92
+ open override func applicationWillTerminate(_ application: UIApplication) {
70
93
  subscribers.forEach { $0.applicationWillTerminate?(application) }
71
94
  }
72
95
 
73
- @objc public func customizeRootView(_ rootView: UIView) {
74
- subscribers.forEach { $0.customizeRootView?(rootView) }
75
- }
76
-
77
96
  // TODO: - Responding to Environment Changes
78
97
 
79
98
  // TODO: - Managing App State Restoration
80
99
 
81
100
  // MARK: - Downloading Data in the Background
82
101
 
83
- open func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
102
+ open override func application(
103
+ _ application: UIApplication,
104
+ handleEventsForBackgroundURLSession identifier: String,
105
+ completionHandler: @escaping () -> Void
106
+ ) {
84
107
  let selector = #selector(application(_:handleEventsForBackgroundURLSession:completionHandler:))
85
108
  let subs = subscribers.filter { $0.responds(to: selector) }
86
109
  var subscribersLeft = subs.count
@@ -107,15 +130,15 @@ open class ExpoAppDelegate: UIResponder, UIApplicationDelegate {
107
130
 
108
131
  // MARK: - Handling Remote Notification Registration
109
132
 
110
- open func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
133
+ open override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
111
134
  subscribers.forEach { $0.application?(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken) }
112
135
  }
113
136
 
114
- open func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
137
+ open override func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
115
138
  subscribers.forEach { $0.application?(application, didFailToRegisterForRemoteNotificationsWithError: error) }
116
139
  }
117
140
 
118
- open func application(
141
+ open override func application(
119
142
  _ application: UIApplication,
120
143
  didReceiveRemoteNotification userInfo: [AnyHashable: Any],
121
144
  fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
@@ -160,13 +183,13 @@ open class ExpoAppDelegate: UIResponder, UIApplicationDelegate {
160
183
 
161
184
  // MARK: - Continuing User Activity and Handling Quick Actions
162
185
 
163
- open func application(_ application: UIApplication, willContinueUserActivityWithType userActivityType: String) -> Bool {
186
+ open override func application(_ application: UIApplication, willContinueUserActivityWithType userActivityType: String) -> Bool {
164
187
  return subscribers.reduce(false) { result, subscriber in
165
188
  return subscriber.application?(application, willContinueUserActivityWithType: userActivityType) ?? false || result
166
189
  }
167
190
  }
168
191
 
169
- open func application(
192
+ open override func application(
170
193
  _ application: UIApplication,
171
194
  continue userActivity: NSUserActivity,
172
195
  restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
@@ -196,18 +219,22 @@ open class ExpoAppDelegate: UIResponder, UIApplicationDelegate {
196
219
  }
197
220
  }
198
221
 
199
- open func application(_ application: UIApplication, didUpdate userActivity: NSUserActivity) {
222
+ open override func application(_ application: UIApplication, didUpdate userActivity: NSUserActivity) {
200
223
  return subscribers.forEach { $0.application?(application, didUpdate: userActivity) }
201
224
  }
202
225
 
203
- open func application(_ application: UIApplication, didFailToContinueUserActivityWithType userActivityType: String, error: Error) {
226
+ open override func application(_ application: UIApplication, didFailToContinueUserActivityWithType userActivityType: String, error: Error) {
204
227
  return subscribers.forEach {
205
228
  $0.application?(application, didFailToContinueUserActivityWithType: userActivityType, error: error)
206
229
  }
207
230
  }
208
231
 
209
232
  #if !os(tvOS)
210
- open func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
233
+ open override func application(
234
+ _ application: UIApplication,
235
+ performActionFor shortcutItem: UIApplicationShortcutItem,
236
+ completionHandler: @escaping (Bool) -> Void
237
+ ) {
211
238
  let selector = #selector(application(_:performActionFor:completionHandler:))
212
239
  let subs = subscribers.filter { $0.responds(to: selector) }
213
240
  var subscribersLeft = subs.count
@@ -237,7 +264,10 @@ open class ExpoAppDelegate: UIResponder, UIApplicationDelegate {
237
264
 
238
265
  // MARK: - Background Fetch
239
266
 
240
- open func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
267
+ open override func application(
268
+ _ application: UIApplication,
269
+ performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
270
+ ) {
241
271
  let selector = #selector(application(_:performFetchWithCompletionHandler:))
242
272
  let subs = subscribers.filter { $0.responds(to: selector) }
243
273
  var subscribersLeft = subs.count
@@ -282,7 +312,7 @@ open class ExpoAppDelegate: UIResponder, UIApplicationDelegate {
282
312
 
283
313
  // MARK: - Opening a URL-Specified Resource
284
314
 
285
- open func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
315
+ open override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
286
316
  return subscribers.reduce(false) { result, subscriber in
287
317
  return subscriber.application?(app, open: url, options: options) ?? false || result
288
318
  }
@@ -301,7 +331,7 @@ open class ExpoAppDelegate: UIResponder, UIApplicationDelegate {
301
331
  * a different orientation.
302
332
  */
303
333
  #if !os(tvOS)
304
- open func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
334
+ open override func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
305
335
  let deviceOrientationMask = allowedOrientations(for: UIDevice.current.userInterfaceIdiom)
306
336
  let universalOrientationMask = allowedOrientations(for: .unspecified)
307
337
  let infoPlistOrientations = deviceOrientationMask.isEmpty ? universalOrientationMask : deviceOrientationMask
@@ -323,6 +353,13 @@ open class ExpoAppDelegate: UIResponder, UIApplicationDelegate {
323
353
 
324
354
  #endif // os(iOS)
325
355
 
356
+ // MARK: - ExpoAppDelegateSubscriberProtocol
357
+
358
+ @objc
359
+ open override func customize(_ rootView: RCTRootView) {
360
+ subscribers.forEach { $0.customizeRootView?(rootView) }
361
+ }
362
+
326
363
  // MARK: - Statics
327
364
 
328
365
  @objc
@@ -348,17 +385,6 @@ open class ExpoAppDelegate: UIResponder, UIApplicationDelegate {
348
385
  public static func getSubscriberOfType<Subscriber>(_ type: Subscriber.Type) -> Subscriber? {
349
386
  return subscribers.first { $0 is Subscriber } as? Subscriber
350
387
  }
351
-
352
- @objc
353
- public static func registerReactDelegateHandlersFrom(modulesProvider: ModulesProvider) {
354
- modulesProvider.getReactDelegateHandlers()
355
- .sorted { tuple1, tuple2 -> Bool in
356
- return ModulePriorities.get(tuple1.packageName) > ModulePriorities.get(tuple2.packageName)
357
- }
358
- .forEach { handlerTuple in
359
- reactDelegateHandlers.append(handlerTuple.handler.init())
360
- }
361
- }
362
388
  }
363
389
 
364
390
  #if os(iOS)
@@ -0,0 +1,94 @@
1
+ import React_RCTAppDelegate
2
+
3
+ private var reactDelegateHandlers = [ExpoReactDelegateHandler]()
4
+
5
+ @objc(EXAppInstance)
6
+ open class ExpoAppInstance: RCTAppDelegate {
7
+ @objc
8
+ public let reactDelegate = ExpoReactDelegate(handlers: reactDelegateHandlers)
9
+
10
+ @objc
11
+ open override func createRootViewController() -> UIViewController {
12
+ return reactDelegate.createRootViewController()
13
+ }
14
+
15
+ open override func bundleURL() -> URL? {
16
+ #if DEBUG
17
+ return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: ".expo/.virtual-metro-entry")
18
+ #else
19
+ return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
20
+ #endif
21
+ }
22
+
23
+ @objc
24
+ open override func createRCTRootViewFactory() -> RCTRootViewFactory {
25
+ let bundleUrlBlock: RCTBundleURLBlock = { [weak self] in
26
+ return self?.bundleURL()
27
+ }
28
+
29
+ let configuration = RCTRootViewFactoryConfiguration(
30
+ bundleURLBlock: bundleUrlBlock,
31
+ newArchEnabled: newArchEnabled(),
32
+ turboModuleEnabled: turboModuleEnabled(),
33
+ bridgelessEnabled: bridgelessEnabled()
34
+ )
35
+
36
+ configuration.createRootViewWithBridge = { bridge, moduleName, initProps in
37
+ return self.createRootView(with: bridge, moduleName: moduleName, initProps: initProps)
38
+ }
39
+
40
+ configuration.createBridgeWithDelegate = { delegate, launchOptions in
41
+ return self.createBridge(with: delegate, launchOptions: launchOptions)
42
+ }
43
+
44
+ configuration.customizeRootView = { rootView in
45
+ // @tsapeta: We cannot just call `self.customize(rootView)` – see the comment of the `customizeRootView:byAppDelegate:` function in EXAppDelegateWrapper.h
46
+ return EXAppDelegateWrapper.customizeRootView(rootView, by: self)
47
+ }
48
+
49
+ // NOTE(kudo): `sourceURLForBridge` is not referenced intentionally because it does not support New Architecture.
50
+ configuration.sourceURLForBridge = nil
51
+
52
+ if responds(to: #selector(extraModules(for:))) {
53
+ configuration.extraModulesForBridge = { bridge in
54
+ return self.extraModules(for: bridge)
55
+ }
56
+ }
57
+
58
+ if responds(to: #selector(extraLazyModuleClasses(for:))) {
59
+ configuration.extraLazyModuleClassesForBridge = { bridge in
60
+ return self.extraLazyModuleClasses(for: bridge)
61
+ }
62
+ }
63
+
64
+ if responds(to: #selector(bridge(_:didNotFindModule:))) {
65
+ configuration.bridgeDidNotFindModule = { bridge, moduleName in
66
+ return self.bridge(bridge, didNotFindModule: moduleName)
67
+ }
68
+ }
69
+
70
+ return ExpoReactRootViewFactory(
71
+ reactDelegate: reactDelegate,
72
+ configuration: configuration,
73
+ turboModuleManagerDelegate: self
74
+ )
75
+ }
76
+
77
+ open override func sourceURL(for bridge: RCTBridge) -> URL? {
78
+ // This method is called only in the old architecture. For compatibility just use the result of a new `bundleURL` method.
79
+ return bundleURL()
80
+ }
81
+
82
+ // MARK: - Statics
83
+
84
+ @objc
85
+ public static func registerReactDelegateHandlersFrom(modulesProvider: ModulesProvider) {
86
+ modulesProvider.getReactDelegateHandlers()
87
+ .sorted { tuple1, tuple2 -> Bool in
88
+ return ModulePriorities.get(tuple1.packageName) > ModulePriorities.get(tuple2.packageName)
89
+ }
90
+ .forEach { handlerTuple in
91
+ reactDelegateHandlers.append(handlerTuple.handler.init())
92
+ }
93
+ }
94
+ }
@@ -3,22 +3,23 @@
3
3
  #pragma once
4
4
 
5
5
  #import <ExpoModulesCore/Platform.h>
6
- #import <ExpoModulesCore/EXReactDelegateWrapper.h>
7
6
  #import <ExpoModulesCore/RCTAppDelegateUmbrella.h>
8
7
 
9
8
  NS_ASSUME_NONNULL_BEGIN
10
9
 
10
+ @class EXReactDelegate;
11
+
11
12
  NS_SWIFT_NAME(ExpoReactRootViewFactory)
12
13
  @interface EXReactRootViewFactory : RCTRootViewFactory
13
14
 
14
- @property (nonatomic, weak, nullable) EXReactDelegateWrapper *reactDelegate;
15
+ @property (nonatomic, weak, nullable) EXReactDelegate *reactDelegate;
15
16
 
16
17
  /**
17
18
  Initializer for EXAppDelegateWrapper integration
18
19
  */
19
- - (instancetype)initWithReactDelegate:(nullable EXReactDelegateWrapper *)reactDelegate
20
+ - (instancetype)initWithReactDelegate:(nullable EXReactDelegate *)reactDelegate
20
21
  configuration:(RCTRootViewFactoryConfiguration *)configuration
21
- turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate;
22
+ turboModuleManagerDelegate:(nullable id)turboModuleManagerDelegate;
22
23
 
23
24
  /**
24
25
  Calls super `viewWithModuleName:initialProperties:launchOptions:` from `RCTRootViewFactory`.
@@ -1,9 +1,9 @@
1
1
  // Copyright 2018-present 650 Industries. All rights reserved.
2
2
 
3
3
  #import <ExpoModulesCore/EXReactRootViewFactory.h>
4
-
5
4
  #import <ExpoModulesCore/EXReactDelegateWrapper+Private.h>
6
5
  #import <ExpoModulesCore/RCTAppDelegateUmbrella.h>
6
+ #import <ExpoModulesCore/Swift.h>
7
7
 
8
8
  @interface RCTRootViewFactory ()
9
9
 
@@ -13,9 +13,9 @@
13
13
 
14
14
  @implementation EXReactRootViewFactory
15
15
 
16
- - (instancetype)initWithReactDelegate:(nullable EXReactDelegateWrapper *)reactDelegate
16
+ - (instancetype)initWithReactDelegate:(nullable EXReactDelegate *)reactDelegate
17
17
  configuration:(RCTRootViewFactoryConfiguration *)configuration
18
- turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
18
+ turboModuleManagerDelegate:(nullable id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
19
19
  {
20
20
  if (self = [super initWithConfiguration:configuration andTurboModuleManagerDelegate:turboModuleManagerDelegate]) {
21
21
  self.reactDelegate = reactDelegate;
@@ -28,7 +28,7 @@
28
28
  launchOptions:(nullable NSDictionary *)launchOptions
29
29
  {
30
30
  if (self.reactDelegate != nil) {
31
- return [self.reactDelegate createReactRootView:moduleName initialProperties:initialProperties launchOptions:launchOptions];
31
+ return [self.reactDelegate createReactRootViewWithModuleName:moduleName initialProperties:initialProperties launchOptions:launchOptions];
32
32
  }
33
33
  return [super viewWithModuleName:moduleName initialProperties:initialProperties launchOptions:launchOptions];
34
34
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-modules-core",
3
- "version": "2.1.2",
3
+ "version": "2.1.4",
4
4
  "description": "The core of Expo Modules architecture",
5
5
  "main": "src/index.ts",
6
6
  "types": "build/index.d.ts",
@@ -42,7 +42,7 @@
42
42
  },
43
43
  "devDependencies": {
44
44
  "@testing-library/react-native": "^12.5.2",
45
- "expo-module-scripts": "^4.0.0"
45
+ "expo-module-scripts": "^4.0.3"
46
46
  },
47
- "gitHead": "637acf537a92ac6209bfced71e097ba736b43fef"
47
+ "gitHead": "0a0c6d35a691fc59c0d94675d159ac9e3dfd6f26"
48
48
  }
@@ -60,38 +60,46 @@ type ViewConfig = {
60
60
  directEventTypes: Record<string, { registrationName: string }>;
61
61
  };
62
62
 
63
- export interface ExpoProcess {
64
- env: {
65
- NODE_ENV: string;
66
- /** Used in `@expo/metro-runtime`. */
67
- EXPO_DEV_SERVER_ORIGIN?: string;
63
+ export interface ExpoProcessEnv {
64
+ NODE_ENV: string;
65
+ /** Used in `@expo/metro-runtime`. */
66
+ EXPO_DEV_SERVER_ORIGIN?: string;
67
+
68
+ EXPO_ROUTER_IMPORT_MODE?: string;
69
+ EXPO_ROUTER_ABS_APP_ROOT?: string;
70
+ EXPO_ROUTER_APP_ROOT?: string;
68
71
 
69
- EXPO_ROUTER_IMPORT_MODE?: string;
70
- EXPO_ROUTER_ABS_APP_ROOT?: string;
71
- EXPO_ROUTER_APP_ROOT?: string;
72
+ /** Maps to the `experiments.baseUrl` property in the project Expo config. This is injected by `babel-preset-expo` and supports automatic cache invalidation. */
73
+ EXPO_BASE_URL?: string;
72
74
 
73
- /** Maps to the `experiments.baseUrl` property in the project Expo config. This is injected by `babel-preset-expo` and supports automatic cache invalidation. */
74
- EXPO_BASE_URL?: string;
75
+ /** Build-time representation of the `Platform.OS` value that the current JavaScript was bundled for. Does not support platform shaking wrapped require statements. */
76
+ EXPO_OS?: string;
75
77
 
76
- /** Build-time representation of the `Platform.OS` value that the current JavaScript was bundled for. Does not support platform shaking wrapped require statements. */
77
- EXPO_OS?: string;
78
+ [key: string]: any;
79
+ }
78
80
 
79
- [key: string]: any;
80
- };
81
+ export interface ExpoProcess {
82
+ env: ExpoProcessEnv;
81
83
  [key: string]: any;
82
84
  }
83
85
 
84
86
  /* eslint-disable no-var */
85
87
 
86
88
  declare global {
89
+ namespace NodeJS {
90
+ export interface ProcessEnv extends ExpoProcessEnv {}
91
+ export interface Process extends ExpoProcess {
92
+ env: ProcessEnv;
93
+ }
94
+ }
95
+
87
96
  /**
88
97
  * Global object containing all the native bindings installed by Expo.
89
98
  * This object is not available in projects without the `expo` package installed.
90
99
  */
91
100
  var expo: ExpoGlobal;
92
101
 
93
- // @ts-ignore - Suppress incompatible `NodeJS.Process` type if people include process type from `@types/node`
94
- var process: ExpoProcess;
102
+ var process: NodeJS.Process;
95
103
 
96
104
  /**
97
105
  * ExpoDomWebView is defined in `@expo/dom-webview` runtime.