expo 55.0.0-canary-20260119-70f7c28 → 55.0.0-canary-20260119-17896bf

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 (72) hide show
  1. package/Expo.podspec +0 -1
  2. package/android/build.gradle +5 -5
  3. package/android/src/main/java/expo/modules/ExpoReactHostFactory.kt +32 -67
  4. package/android/src/main/java/expo/modules/ReactActivityDelegateWrapper.kt +9 -6
  5. package/android/src/main/java/expo/modules/ReactNativeHostWrapper.kt +51 -0
  6. package/android/src/main/java/expo/modules/ReactNativeHostWrapperBase.kt +107 -0
  7. package/android/src/main/java/expo/modules/fetch/ExpoFetchModule.kt +3 -4
  8. package/android/src/main/java/expo/modules/fetch/NativeResponse.kt +3 -3
  9. package/android/src/main/java/expo/modules/fetch/ResponseSink.kt +3 -7
  10. package/android/src/test/java/expo/modules/ReactActivityDelegateWrapperDelayLoadTest.kt +3 -2
  11. package/build/Expo.d.ts +1 -1
  12. package/build/Expo.d.ts.map +1 -1
  13. package/build/async-require/getDevServer.d.ts.map +1 -1
  14. package/build/async-require/hmr.d.ts +8 -8
  15. package/build/async-require/hmr.d.ts.map +1 -1
  16. package/build/async-require/hmr.native.d.ts +3 -0
  17. package/build/async-require/hmr.native.d.ts.map +1 -0
  18. package/build/dom/dom-entry.d.ts.map +1 -1
  19. package/build/dom/dom.types.d.ts +0 -5
  20. package/build/dom/dom.types.d.ts.map +1 -1
  21. package/build/dom/internal.d.ts +0 -1
  22. package/build/dom/internal.d.ts.map +1 -1
  23. package/build/dom/webview-wrapper.d.ts +2 -2
  24. package/build/dom/webview-wrapper.d.ts.map +1 -1
  25. package/build/hooks/useEvent.d.ts +2 -2
  26. package/bundledNativeModules.json +101 -99
  27. package/ios/AppDelegates/AppDelegatesLoaderDelegate.swift +0 -2
  28. package/ios/AppDelegates/EXAppDelegateWrapper.h +30 -0
  29. package/ios/AppDelegates/EXAppDelegateWrapper.mm +112 -0
  30. package/ios/AppDelegates/EXReactRootViewFactory.h +1 -8
  31. package/ios/AppDelegates/EXReactRootViewFactory.mm +0 -26
  32. package/ios/AppDelegates/ExpoAppDelegate.swift +52 -13
  33. package/ios/AppDelegates/ExpoReactNativeFactory.swift +1 -22
  34. package/ios/Expo.h +1 -2
  35. package/ios/Fetch/ExpoFetchModule.swift +2 -2
  36. package/package.json +23 -29
  37. package/src/Expo.fx.tsx +25 -1
  38. package/src/Expo.fx.web.tsx +2 -2
  39. package/src/Expo.ts +0 -3
  40. package/src/__tests__/__fbBatchedBridgeConfig-test.ts +3 -7
  41. package/src/async-require/asyncRequireModule.ts +2 -2
  42. package/src/async-require/getDevServer.ts +9 -3
  43. package/src/async-require/hmr.native.ts +3 -0
  44. package/src/async-require/hmr.ts +103 -118
  45. package/src/async-require/index.ts +1 -1
  46. package/src/async-require/setupFastRefresh.ts +2 -3
  47. package/src/dom/dom-entry.tsx +8 -15
  48. package/src/dom/dom.types.ts +0 -6
  49. package/src/dom/internal.ts +0 -2
  50. package/src/dom/webview-wrapper.tsx +6 -14
  51. package/src/hooks/useEvent.ts +2 -2
  52. package/template.tgz +0 -0
  53. package/types/react-native-web.d.ts +1 -1
  54. package/build/async-require/buildErrors.d.ts +0 -5
  55. package/build/async-require/buildErrors.d.ts.map +0 -1
  56. package/build/async-require/getFullBundlerUrl.d.ts +0 -2
  57. package/build/async-require/getFullBundlerUrl.d.ts.map +0 -1
  58. package/build/async-require/hmrUtils.d.ts +0 -13
  59. package/build/async-require/hmrUtils.d.ts.map +0 -1
  60. package/build/async-require/hmrUtils.native.d.ts +0 -13
  61. package/build/async-require/hmrUtils.native.d.ts.map +0 -1
  62. package/build/dom/dom-internal.types.d.ts +0 -11
  63. package/build/dom/dom-internal.types.d.ts.map +0 -1
  64. package/ios/AppDelegates/ExpoReactNativeFactory.h +0 -12
  65. package/ios/AppDelegates/ExpoReactNativeFactory.mm +0 -45
  66. package/local-build-cache-provider.d.ts +0 -1
  67. package/local-build-cache-provider.js +0 -1
  68. package/src/async-require/buildErrors.ts +0 -14
  69. package/src/async-require/getFullBundlerUrl.ts +0 -13
  70. package/src/async-require/hmrUtils.native.ts +0 -97
  71. package/src/async-require/hmrUtils.ts +0 -54
  72. package/src/dom/dom-internal.types.ts +0 -9
@@ -15,7 +15,7 @@ type InferEventParameter<TEventListener extends AnyEventListener, TInitialValue>
15
15
  /**
16
16
  * React hook that listens to events emitted by the given object. The returned value is an event parameter
17
17
  * that gets updated whenever a new event is dispatched.
18
- * @param eventEmitter An object that emits events. For example, a native module or shared object or an instance of [`EventEmitter`](#eventemittertype).
18
+ * @param eventEmitter An object that emits events. For example, a native module or shared object or an instance of [`EventEmitter`](#eventemitter).
19
19
  * @param eventName Name of the event to listen to.
20
20
  * @param initialValue An event parameter to use until the event is called for the first time.
21
21
  * @returns A parameter of the event listener.
@@ -35,7 +35,7 @@ export declare function useEvent<TEventsMap extends Record<string, AnyEventListe
35
35
  /**
36
36
  * React hook that listens to events emitted by the given object and calls the listener function whenever a new event is dispatched.
37
37
  * The event listener is automatically added during the first render and removed when the component unmounts.
38
- * @param eventEmitter An object that emits events. For example, a native module or shared object or an instance of [`EventEmitter`](#eventemittertype).
38
+ * @param eventEmitter An object that emits events. For example, a native module or shared object or an instance of [`EventEmitter`](#eventemitter).
39
39
  * @param eventName Name of the event to listen to.
40
40
  * @param listener A function to call when the event is dispatched.
41
41
  * @example
@@ -1,118 +1,120 @@
1
1
  {
2
- "@expo/fingerprint": "0.15.5-canary-20260119-70f7c28",
3
- "@expo/metro-runtime": "6.2.0-canary-20260119-70f7c28",
4
- "@expo/vector-icons": "^15.0.2",
5
- "@expo/ui": "0.2.0-canary-20260119-70f7c28",
2
+ "@expo/fingerprint": "0.15.5-canary-20260119-17896bf",
3
+ "@expo/metro-runtime": "6.1.3-canary-20260119-17896bf",
4
+ "@expo/vector-icons": "^15.0.3",
5
+ "@expo/ui": "0.2.0-canary-20260119-17896bf",
6
6
  "@react-native-async-storage/async-storage": "2.2.0",
7
- "@react-native-community/datetimepicker": "8.6.0",
7
+ "@react-native-community/datetimepicker": "8.4.4",
8
8
  "@react-native-masked-view/masked-view": "0.3.2",
9
9
  "@react-native-community/netinfo": "11.4.1",
10
- "@react-native-community/slider": "5.1.1",
10
+ "@react-native-community/slider": "5.0.1",
11
11
  "@react-native-community/viewpager": "5.0.11",
12
- "@react-native-picker/picker": "2.11.4",
12
+ "@react-native-picker/picker": "2.11.1",
13
13
  "@react-native-segmented-control/segmented-control": "2.5.7",
14
- "@stripe/stripe-react-native": "0.57.2",
15
- "eslint-config-expo": "10.0.1-canary-20260119-70f7c28",
14
+ "@stripe/stripe-react-native": "0.50.3",
15
+ "eslint-config-expo": "10.0.1-canary-20260119-17896bf",
16
+ "expo-age-range": "0.2.2-canary-20260119-17896bf",
16
17
  "expo-analytics-amplitude": "~11.3.0",
17
18
  "expo-app-auth": "~11.1.0",
18
19
  "expo-app-loader-provider": "~8.0.0",
19
- "expo-apple-authentication": "8.0.9-canary-20260119-70f7c28",
20
- "expo-application": "7.0.9-canary-20260119-70f7c28",
21
- "expo-asset": "12.0.13-canary-20260119-70f7c28",
22
- "expo-audio": "1.2.0-canary-20260119-70f7c28",
23
- "expo-auth-session": "7.1.0-canary-20260119-70f7c28",
24
- "expo-background-fetch": "14.0.10-canary-20260119-70f7c28",
25
- "expo-background-task": "1.0.11-canary-20260119-70f7c28",
26
- "expo-battery": "10.0.9-canary-20260119-70f7c28",
27
- "expo-blur": "16.0.0-canary-20260119-70f7c28",
28
- "expo-brightness": "15.0.0-canary-20260119-70f7c28",
29
- "expo-build-properties": "2.0.0-canary-20260119-70f7c28",
30
- "expo-calendar": "15.1.0-canary-20260119-70f7c28",
31
- "expo-camera": "17.1.0-canary-20260119-70f7c28",
32
- "expo-cellular": "8.0.9-canary-20260119-70f7c28",
33
- "expo-checkbox": "5.0.9-canary-20260119-70f7c28",
34
- "expo-clipboard": "9.0.0-canary-20260119-70f7c28",
35
- "expo-constants": "18.1.0-canary-20260119-70f7c28",
36
- "expo-contacts": "15.1.0-canary-20260119-70f7c28",
37
- "expo-crypto": "15.1.0-canary-20260119-70f7c28",
38
- "expo-dev-client": "6.1.0-canary-20260119-70f7c28",
39
- "expo-device": "8.0.11-canary-20260119-70f7c28",
40
- "expo-document-picker": "14.0.9-canary-20260119-70f7c28",
41
- "expo-file-system": "19.0.22-canary-20260119-70f7c28",
42
- "expo-font": "14.1.0-canary-20260119-70f7c28",
43
- "expo-gl": "16.0.10-canary-20260119-70f7c28",
44
- "expo-glass-effect": "0.2.0-canary-20260119-70f7c28",
20
+ "expo-apple-authentication": "8.0.9-canary-20260119-17896bf",
21
+ "expo-application": "7.0.9-canary-20260119-17896bf",
22
+ "expo-asset": "12.0.13-canary-20260119-17896bf",
23
+ "expo-audio": "1.1.2-canary-20260119-17896bf",
24
+ "expo-auth-session": "7.0.11-canary-20260119-17896bf",
25
+ "expo-av": "16.0.9-canary-20260119-17896bf",
26
+ "expo-background-fetch": "14.0.10-canary-20260119-17896bf",
27
+ "expo-background-task": "1.0.11-canary-20260119-17896bf",
28
+ "expo-battery": "10.0.9-canary-20260119-17896bf",
29
+ "expo-blur": "15.0.9-canary-20260119-17896bf",
30
+ "expo-brightness": "14.0.9-canary-20260119-17896bf",
31
+ "expo-build-properties": "1.0.11-canary-20260119-17896bf",
32
+ "expo-calendar": "15.0.9-canary-20260119-17896bf",
33
+ "expo-camera": "17.0.11-canary-20260119-17896bf",
34
+ "expo-cellular": "8.0.9-canary-20260119-17896bf",
35
+ "expo-checkbox": "5.0.9-canary-20260119-17896bf",
36
+ "expo-clipboard": "8.0.9-canary-20260119-17896bf",
37
+ "expo-constants": "18.0.14-canary-20260119-17896bf",
38
+ "expo-contacts": "15.0.12-canary-20260119-17896bf",
39
+ "expo-crypto": "15.0.9-canary-20260119-17896bf",
40
+ "expo-dev-client": "6.0.21-canary-20260119-17896bf",
41
+ "expo-device": "8.0.11-canary-20260119-17896bf",
42
+ "expo-document-picker": "14.0.9-canary-20260119-17896bf",
43
+ "expo-file-system": "19.0.22-canary-20260119-17896bf",
44
+ "expo-font": "14.0.11-canary-20260119-17896bf",
45
+ "expo-gl": "16.0.10-canary-20260119-17896bf",
46
+ "expo-glass-effect": "0.1.9-canary-20260119-17896bf",
45
47
  "expo-google-app-auth": "~8.3.0",
46
- "expo-haptics": "15.0.9-canary-20260119-70f7c28",
47
- "expo-image": "3.1.0-canary-20260119-70f7c28",
48
- "expo-image-loader": "7.0.0-canary-20260119-70f7c28",
49
- "expo-image-manipulator": "14.0.9-canary-20260119-70f7c28",
50
- "expo-image-picker": "17.1.0-canary-20260119-70f7c28",
51
- "expo-intent-launcher": "13.0.9-canary-20260119-70f7c28",
52
- "expo-insights": "0.10.9-canary-20260119-70f7c28",
53
- "expo-keep-awake": "15.0.9-canary-20260119-70f7c28",
54
- "expo-linear-gradient": "15.0.9-canary-20260119-70f7c28",
55
- "expo-linking": "8.0.12-canary-20260119-70f7c28",
56
- "expo-local-authentication": "17.0.9-canary-20260119-70f7c28",
57
- "expo-localization": "18.0.0-canary-20260119-70f7c28",
58
- "expo-location": "19.1.0-canary-20260119-70f7c28",
59
- "expo-mail-composer": "15.0.9-canary-20260119-70f7c28",
60
- "expo-manifests": "1.0.11-canary-20260119-70f7c28",
61
- "expo-maps": "0.13.0-canary-20260119-70f7c28",
48
+ "expo-haptics": "15.0.9-canary-20260119-17896bf",
49
+ "expo-image": "3.0.12-canary-20260119-17896bf",
50
+ "expo-image-loader": "6.0.1-canary-20260119-17896bf",
51
+ "expo-image-manipulator": "14.0.9-canary-20260119-17896bf",
52
+ "expo-image-picker": "17.0.11-canary-20260119-17896bf",
53
+ "expo-intent-launcher": "13.0.9-canary-20260119-17896bf",
54
+ "expo-insights": "0.10.9-canary-20260119-17896bf",
55
+ "expo-keep-awake": "15.0.9-canary-20260119-17896bf",
56
+ "expo-linear-gradient": "15.0.9-canary-20260119-17896bf",
57
+ "expo-linking": "8.0.12-canary-20260119-17896bf",
58
+ "expo-local-authentication": "17.0.9-canary-20260119-17896bf",
59
+ "expo-localization": "17.0.9-canary-20260119-17896bf",
60
+ "expo-location": "19.0.9-canary-20260119-17896bf",
61
+ "expo-mail-composer": "15.0.9-canary-20260119-17896bf",
62
+ "expo-manifests": "1.0.11-canary-20260119-17896bf",
63
+ "expo-maps": "0.12.11-canary-20260119-17896bf",
62
64
  "expo-mcp": "~0.2.1",
63
- "expo-media-library": "18.3.0-canary-20260119-70f7c28",
64
- "expo-mesh-gradient": "0.4.9-canary-20260119-70f7c28",
65
- "expo-module-template": "11.0.19-canary-20260119-70f7c28",
66
- "expo-modules-core": "4.0.0-canary-20260119-70f7c28",
67
- "expo-navigation-bar": "5.0.11-canary-20260119-70f7c28",
68
- "expo-network": "8.0.9-canary-20260119-70f7c28",
69
- "expo-notifications": "1.0.0-canary-20260119-70f7c28",
70
- "expo-print": "15.0.9-canary-20260119-70f7c28",
71
- "expo-live-photo": "1.0.9-canary-20260119-70f7c28",
72
- "expo-router": "7.0.0-canary-20260119-70f7c28",
73
- "expo-screen-capture": "8.0.10-canary-20260119-70f7c28",
74
- "expo-screen-orientation": "9.0.9-canary-20260119-70f7c28",
75
- "expo-secure-store": "15.0.9-canary-20260119-70f7c28",
76
- "expo-sensors": "15.0.9-canary-20260119-70f7c28",
77
- "expo-server": "1.1.0-canary-20260119-70f7c28",
78
- "expo-sharing": "14.0.9-canary-20260119-70f7c28",
79
- "expo-sms": "14.0.9-canary-20260119-70f7c28",
80
- "expo-speech": "14.1.0-canary-20260119-70f7c28",
81
- "expo-splash-screen": "31.0.14-canary-20260119-70f7c28",
82
- "expo-sqlite": "16.1.0-canary-20260119-70f7c28",
83
- "expo-status-bar": "3.0.10-canary-20260119-70f7c28",
84
- "expo-store-review": "9.0.10-canary-20260119-70f7c28",
85
- "expo-symbols": "1.1.0-canary-20260119-70f7c28",
86
- "expo-system-ui": "6.0.10-canary-20260119-70f7c28",
87
- "expo-task-manager": "14.0.10-canary-20260119-70f7c28",
88
- "expo-tracking-transparency": "6.0.9-canary-20260119-70f7c28",
89
- "expo-updates": "29.1.0-canary-20260119-70f7c28",
90
- "expo-video-thumbnails": "10.0.9-canary-20260119-70f7c28",
91
- "expo-video": "4.0.0-canary-20260119-70f7c28",
92
- "expo-web-browser": "15.0.11-canary-20260119-70f7c28",
93
- "jest-expo": "55.0.0-canary-20260119-70f7c28",
94
- "lottie-react-native": "~7.3.4",
95
- "react": "19.2.0",
96
- "react-dom": "19.2.0",
97
- "react-native": "0.83.1",
65
+ "expo-media-library": "18.2.2-canary-20260119-17896bf",
66
+ "expo-mesh-gradient": "0.4.9-canary-20260119-17896bf",
67
+ "expo-module-template": "11.0.19-canary-20260119-17896bf",
68
+ "expo-modules-core": "3.0.30-canary-20260119-17896bf",
69
+ "expo-navigation-bar": "5.0.11-canary-20260119-17896bf",
70
+ "expo-network": "8.0.9-canary-20260119-17896bf",
71
+ "expo-notifications": "0.32.17-canary-20260119-17896bf",
72
+ "expo-print": "15.0.9-canary-20260119-17896bf",
73
+ "expo-live-photo": "1.0.9-canary-20260119-17896bf",
74
+ "expo-router": "6.0.22-canary-20260119-17896bf",
75
+ "expo-screen-capture": "8.0.10-canary-20260119-17896bf",
76
+ "expo-screen-orientation": "9.0.9-canary-20260119-17896bf",
77
+ "expo-secure-store": "15.0.9-canary-20260119-17896bf",
78
+ "expo-sensors": "15.0.9-canary-20260119-17896bf",
79
+ "expo-server": "1.0.6-canary-20260119-17896bf",
80
+ "expo-sharing": "14.0.9-canary-20260119-17896bf",
81
+ "expo-sms": "14.0.9-canary-20260119-17896bf",
82
+ "expo-speech": "14.0.9-canary-20260119-17896bf",
83
+ "expo-splash-screen": "31.0.14-canary-20260119-17896bf",
84
+ "expo-sqlite": "16.0.11-canary-20260119-17896bf",
85
+ "expo-status-bar": "3.0.10-canary-20260119-17896bf",
86
+ "expo-store-review": "9.0.10-canary-20260119-17896bf",
87
+ "expo-symbols": "1.0.9-canary-20260119-17896bf",
88
+ "expo-system-ui": "6.0.10-canary-20260119-17896bf",
89
+ "expo-task-manager": "14.0.10-canary-20260119-17896bf",
90
+ "expo-tracking-transparency": "6.0.9-canary-20260119-17896bf",
91
+ "expo-updates": "29.0.17-canary-20260119-17896bf",
92
+ "expo-video-thumbnails": "10.0.9-canary-20260119-17896bf",
93
+ "expo-video": "3.0.16-canary-20260119-17896bf",
94
+ "expo-web-browser": "15.0.11-canary-20260119-17896bf",
95
+ "jest-expo": "55.0.0-canary-20260119-17896bf",
96
+ "lottie-react-native": "~7.3.1",
97
+ "react": "19.1.0",
98
+ "react-dom": "19.1.0",
99
+ "react-native": "0.81.5",
98
100
  "react-native-web": "~0.21.0",
99
- "react-native-gesture-handler": "~2.30.0",
101
+ "react-native-gesture-handler": "~2.28.0",
100
102
  "react-native-get-random-values": "~1.11.0",
101
- "react-native-keyboard-controller": "1.20.4",
102
- "react-native-maps": "1.26.20",
103
- "react-native-pager-view": "8.0.0",
104
- "react-native-worklets": "0.7.1",
105
- "react-native-reanimated": "~4.2.1",
106
- "react-native-screens": "~4.19.0",
107
- "react-native-safe-area-context": "~5.6.2",
108
- "react-native-svg": "15.15.1",
103
+ "react-native-keyboard-controller": "1.18.5",
104
+ "react-native-maps": "1.20.1",
105
+ "react-native-pager-view": "6.9.1",
106
+ "react-native-worklets": "0.5.1",
107
+ "react-native-reanimated": "~4.1.1",
108
+ "react-native-screens": "~4.16.0",
109
+ "react-native-safe-area-context": "~5.6.0",
110
+ "react-native-svg": "15.12.1",
109
111
  "react-native-view-shot": "4.0.3",
110
- "react-native-webview": "13.16.0",
111
- "react-server-dom-webpack": "~19.2.3",
112
+ "react-native-webview": "13.15.0",
113
+ "react-server-dom-webpack": "~19.1.4",
112
114
  "sentry-expo": "~7.0.0",
113
- "unimodules-app-loader": "6.0.9-canary-20260119-70f7c28",
115
+ "unimodules-app-loader": "6.0.9-canary-20260119-17896bf",
114
116
  "unimodules-image-loader-interface": "~6.1.0",
115
- "@shopify/react-native-skia": "2.4.14",
117
+ "@shopify/react-native-skia": "2.2.12",
116
118
  "@shopify/flash-list": "2.0.2",
117
119
  "@sentry/react-native": "~7.2.0",
118
120
  "react-native-bootsplash": "^6.3.10"
@@ -2,8 +2,6 @@
2
2
 
3
3
  import ExpoModulesCore
4
4
 
5
- @MainActor
6
- @preconcurrency
7
5
  @objc
8
6
  public class AppDelegatesLoaderDelegate: NSObject {
9
7
  /**
@@ -0,0 +1,30 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ #import <ExpoModulesCore/Platform.h>
4
+ #import <ExpoModulesCore/EXReactDelegateWrapper.h>
5
+ #import <Expo/RCTAppDelegateUmbrella.h>
6
+
7
+ NS_ASSUME_NONNULL_BEGIN
8
+
9
+ @interface RCTAppDelegate ()
10
+
11
+ @end
12
+
13
+ __deprecated_msg("EXAppDelegateWrapper is deprecated. Migrate your AppDelegate to Swift and use ExpoAppDelegate instead. EXAppDelegateWrapper will be removed in SDK 55.")
14
+ @interface EXAppDelegateWrapper : NSObject <UIApplicationDelegate, UISceneDelegate, RCTReactNativeFactoryDelegate>
15
+
16
+ @property (nonatomic, strong, readonly) EXReactDelegateWrapper *reactDelegate;
17
+
18
+ @property (nonatomic, strong, nullable) NSString *moduleName;
19
+ @property (nonatomic, strong, nullable) NSDictionary *initialProps;
20
+
21
+ /**
22
+ Currently (RN 0.76) `customizeRootView` signature in `RCTAppDelegate` is broken as it uses `RCTRootView` type,
23
+ but this type is no longer used. It should rather be `RCTSurfaceHostingView`, but for simplicity it could be just `UIView`.
24
+ We need a helper function in Objective-C to actually make it to work, otherwise the types will conflict in Swift.
25
+ */
26
+ + (void)customizeRootView:(nonnull UIView *)rootView byAppDelegate:(nonnull RCTAppDelegate *)appDelegate;
27
+
28
+ @end
29
+
30
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,112 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ #import <Expo/EXAppDelegateWrapper.h>
4
+
5
+ #import <Expo/RCTAppDelegateUmbrella.h>
6
+ #import <Expo/Swift.h>
7
+
8
+ #import <React/RCTComponentViewFactory.h> // Allows non-umbrella since it's coming from React-RCTFabric
9
+ #import <ReactCommon/RCTHost.h> // Allows non-umbrella because the header is not inside a clang module
10
+
11
+ @implementation EXAppDelegateWrapper {
12
+ EXExpoAppDelegate *_expoAppDelegate;
13
+ }
14
+
15
+ - (instancetype)init
16
+ {
17
+ if (self = [super init]) {
18
+ _expoAppDelegate = [EXExpoAppDelegate new];
19
+ }
20
+ return self;
21
+ }
22
+
23
+ // This needs to be implemented, otherwise forwarding won't be called.
24
+ // When the app starts, `UIApplication` uses it to check beforehand
25
+ // which `UIApplicationDelegate` selectors are implemented.
26
+ - (BOOL)respondsToSelector:(SEL)selector
27
+ {
28
+ return [super respondsToSelector:selector] || [_expoAppDelegate respondsToSelector:selector];
29
+ }
30
+
31
+ // Forwards all invocations to `ExpoAppDelegate` object.
32
+ - (id)forwardingTargetForSelector:(SEL)selector
33
+ {
34
+ return _expoAppDelegate;
35
+ }
36
+
37
+ #pragma mark - UIApplicationDelegate
38
+
39
+ // Make sure to override all necessary methods from `RCTAppDelegate` here, explicitly forwarding everything to `_expoAppDelegate`.
40
+ // `forwardingTargetForSelector` works only for methods that are not specified in this and `RCTAppDelegate` classes.
41
+
42
+ #if !TARGET_OS_OSX
43
+ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
44
+ {
45
+ return [_expoAppDelegate application:application didFinishLaunchingWithOptions:launchOptions];
46
+ }
47
+
48
+ - (void)applicationDidBecomeActive:(UIApplication *)application
49
+ {
50
+ return [_expoAppDelegate applicationDidBecomeActive:application];
51
+ }
52
+ #else
53
+ - (void)applicationDidFinishLaunching:(NSNotification *)notification
54
+ {
55
+ return [_expoAppDelegate applicationDidFinishLaunching:notification];
56
+ }
57
+
58
+ - (void)applicationDidBecomeActive:(NSNotification *)notification
59
+ {
60
+ return [_expoAppDelegate applicationDidBecomeActive:notification];
61
+ }
62
+ #endif
63
+
64
+ - (UIViewController *)createRootViewController
65
+ {
66
+ return [_expoAppDelegate.factory.delegate createRootViewController];
67
+ }
68
+
69
+ - (void)customizeRootView:(UIView *)rootView
70
+ {
71
+ [_expoAppDelegate.factory.delegate customizeRootView:rootView];
72
+ }
73
+
74
+ #pragma mark - RCTComponentViewFactoryComponentProvider
75
+
76
+ - (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents
77
+ {
78
+ return self.dependencyProvider.thirdPartyFabricComponents;
79
+ }
80
+
81
+ #pragma mark - RCTHostDelegate
82
+
83
+ - (void)hostDidStart:(RCTHost *)host
84
+ {
85
+ }
86
+
87
+ - (void)host:(RCTHost *)host
88
+ didReceiveJSErrorStack:(NSArray<NSDictionary<NSString *, id> *> *)stack
89
+ message:(NSString *)message
90
+ exceptionId:(NSUInteger)exceptionId
91
+ isFatal:(BOOL)isFatal
92
+ {
93
+ }
94
+
95
+ - (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
96
+ {
97
+ return [_expoAppDelegate.factory.delegate getModuleInstanceFromClass:moduleClass];
98
+ }
99
+
100
+ - (Class)getModuleClassFromName:(const char *)name {
101
+ return [_expoAppDelegate.factory.delegate getModuleClassFromName:name];
102
+ }
103
+
104
+
105
+ #pragma mark - Helpers
106
+
107
+ + (void)customizeRootView:(nonnull UIView *)rootView byAppDelegate:(nonnull RCTAppDelegate *)appDelegate
108
+ {
109
+ [appDelegate customizeRootView:(RCTRootView *)rootView];
110
+ }
111
+
112
+ @end
@@ -15,7 +15,7 @@ NS_SWIFT_NAME(ExpoReactRootViewFactory)
15
15
  @property (nonatomic, weak, nullable) EXReactDelegate *reactDelegate;
16
16
 
17
17
  /**
18
- Initializer for ExpoReactNativeFactory integration
18
+ Initializer for EXAppDelegateWrapper integration
19
19
  */
20
20
  - (instancetype)initWithReactDelegate:(nullable EXReactDelegate *)reactDelegate
21
21
  configuration:(RCTRootViewFactoryConfiguration *)configuration
@@ -24,16 +24,9 @@ NS_SWIFT_NAME(ExpoReactRootViewFactory)
24
24
  /**
25
25
  Calls super `viewWithModuleName:initialProperties:launchOptions:` from `RCTRootViewFactory`.
26
26
  */
27
- #if TARGET_OS_IOS
28
- - (UIView *)superViewWithModuleName:(NSString *)moduleName
29
- initialProperties:(nullable NSDictionary *)initialProperties
30
- launchOptions:(nullable NSDictionary *)launchOptions
31
- devMenuConfiguration:(nullable RCTDevMenuConfiguration *)devMenuConfiguration;
32
- #else
33
27
  - (UIView *)superViewWithModuleName:(NSString *)moduleName
34
28
  initialProperties:(nullable NSDictionary *)initialProperties
35
29
  launchOptions:(nullable NSDictionary *)launchOptions;
36
- #endif
37
30
 
38
31
  @end
39
32
 
@@ -3,7 +3,6 @@
3
3
  #import <Expo/EXReactRootViewFactory.h>
4
4
  #import <Expo/RCTAppDelegateUmbrella.h>
5
5
  #import <Expo/Swift.h>
6
- #import <React/RCTDevMenu.h>
7
6
 
8
7
  // When `use_frameworks!` is used, the generated Swift header is inside ExpoModulesCore module.
9
8
  // Otherwise, it's available only locally with double-quoted imports.
@@ -31,30 +30,6 @@
31
30
  return self;
32
31
  }
33
32
 
34
- #if TARGET_OS_IOS
35
- - (UIView *)viewWithModuleName:(NSString *)moduleName
36
- initialProperties:(nullable NSDictionary *)initialProperties
37
- launchOptions:(nullable NSDictionary *)launchOptions
38
- devMenuConfiguration:(RCTDevMenuConfiguration *)devMenuConfiguration
39
- {
40
- if (self.reactDelegate != nil) {
41
- return [self.reactDelegate createReactRootViewWithModuleName:moduleName initialProperties:initialProperties launchOptions:launchOptions];
42
- }
43
- return [super viewWithModuleName:moduleName initialProperties:initialProperties launchOptions:launchOptions devMenuConfiguration:devMenuConfiguration];
44
- }
45
-
46
- - (UIView *)superViewWithModuleName:(NSString *)moduleName
47
- initialProperties:(nullable NSDictionary *)initialProperties
48
- launchOptions:(nullable NSDictionary *)launchOptions
49
- devMenuConfiguration:(nullable RCTDevMenuConfiguration *)devMenuConfiguration
50
- {
51
- if (devMenuConfiguration == nil) {
52
- devMenuConfiguration = [RCTDevMenuConfiguration defaultConfiguration];
53
- }
54
-
55
- return [super viewWithModuleName:moduleName initialProperties:initialProperties launchOptions:launchOptions devMenuConfiguration:devMenuConfiguration];
56
- }
57
- #else
58
33
  - (UIView *)viewWithModuleName:(NSString *)moduleName
59
34
  initialProperties:(nullable NSDictionary *)initialProperties
60
35
  launchOptions:(nullable NSDictionary *)launchOptions
@@ -71,7 +46,6 @@
71
46
  {
72
47
  return [super viewWithModuleName:moduleName initialProperties:initialProperties launchOptions:launchOptions];
73
48
  }
74
- #endif
75
49
 
76
50
  - (NSURL *)bundleURL
77
51
  {
@@ -4,28 +4,67 @@ import ExpoModulesCore
4
4
  import ReactAppDependencyProvider
5
5
 
6
6
  /**
7
+ Note: you cannot subclass Swift from Objective-C, use EXAppDelegateWrapper with Obj-C app delegates
7
8
  Allows classes extending `ExpoAppDelegateSubscriber` to hook into project's app delegate
8
9
  by forwarding `UIApplicationDelegate` events to the subscribers.
9
10
 
10
11
  Keep functions and markers in sync with https://developer.apple.com/documentation/uikit/uiapplicationdelegate
11
12
  */
12
13
  @objc(EXExpoAppDelegate)
13
- open class ExpoAppDelegate: UIResponder, UIApplicationDelegate {
14
- override public init() {
15
- // The subscribers are initializing and registering before the main code starts executing.
16
- // Here we're letting them know when the `AppDelegate` is being created,
17
- // which happens at the beginning of the main code execution and before launching the app.
18
- ExpoAppDelegateSubscriberRepository.subscribers.forEach {
19
- $0.appDelegateWillBeginInitialization?()
14
+ open class ExpoAppDelegate: UIResponder, @preconcurrency ReactNativeFactoryProvider, UIApplicationDelegate {
15
+ @objc public var factory: RCTReactNativeFactory?
16
+ private let defaultModuleName = "main"
17
+ private let defaultInitialProps = [AnyHashable: Any]()
18
+
19
+ public func bindReactNativeFactory(_ factory: RCTReactNativeFactory) {
20
+ self.factory = factory
21
+ }
22
+
23
+ public func recreateRootView(
24
+ withBundleURL: URL?,
25
+ moduleName: String?,
26
+ initialProps: [AnyHashable: Any]?,
27
+ launchOptions: [AnyHashable: Any]?
28
+ ) -> UIView {
29
+ guard let delegate = self.factory?.delegate,
30
+ let rootViewFactory = self.factory?.rootViewFactory else {
31
+ fatalError("recreateRootView: Missing factory in ExpoAppDelegate")
32
+ }
33
+
34
+ if delegate.newArchEnabled() {
35
+ // chrfalch: rootViewFactory.reactHost is not available here in swift due to the underlying RCTHost type of the property. (todo: check)
36
+ assert(rootViewFactory.value(forKey: "reactHost") == nil, "recreateRootViewWithBundleURL: does not support when react instance is created")
37
+ } else {
38
+ assert(rootViewFactory.bridge == nil, "recreateRootViewWithBundleURL: does not support when react instance is created")
20
39
  }
21
- super.init()
22
- }
23
40
 
24
- #if os(macOS)
25
- required public init?(coder: NSCoder) {
26
- super.init(coder: coder)
41
+ let configuration = rootViewFactory.value(forKey: "_configuration") as? RCTRootViewFactoryConfiguration
42
+
43
+ if let bundleURL = withBundleURL {
44
+ configuration?.bundleURLBlock = {
45
+ return bundleURL
46
+ }
47
+ }
48
+
49
+ let rootView: UIView
50
+ if let factory = rootViewFactory as? ExpoReactRootViewFactory {
51
+ // When calling `recreateRootViewWithBundleURL:` from `EXReactRootViewFactory`,
52
+ // we don't want to loop the ReactDelegate again. Otherwise, it will be an infinite loop.
53
+ rootView = factory.superView(
54
+ withModuleName: moduleName ?? defaultModuleName,
55
+ initialProperties: initialProps,
56
+ launchOptions: launchOptions ?? [:]
57
+ )
58
+ } else {
59
+ rootView = rootViewFactory.view(
60
+ withModuleName: moduleName ?? defaultModuleName,
61
+ initialProperties: initialProps,
62
+ launchOptions: launchOptions
63
+ )
64
+ }
65
+
66
+ return rootView
27
67
  }
28
- #endif
29
68
 
30
69
  // MARK: - Initializing the App
31
70
  #if os(iOS) || os(tvOS)
@@ -2,10 +2,8 @@
2
2
 
3
3
  import React
4
4
 
5
- public class ExpoReactNativeFactory: ExpoReactNativeFactoryObjC, ExpoReactNativeFactoryProtocol {
5
+ public class ExpoReactNativeFactory: RCTReactNativeFactory, ExpoReactNativeFactoryProtocol {
6
6
  private let defaultModuleName = "main"
7
-
8
- @MainActor
9
7
  private lazy var reactDelegate: ExpoReactDelegate = {
10
8
  ExpoReactDelegate(
11
9
  handlers: ExpoAppDelegateSubscriberRepository.reactDelegateHandlers,
@@ -120,38 +118,19 @@ public class ExpoReactNativeFactory: ExpoReactNativeFactoryObjC, ExpoReactNative
120
118
 
121
119
  let rootView: UIView
122
120
  if let factory = self.rootViewFactory as? ExpoReactRootViewFactory {
123
- // RCTDevMenuConfiguration is only available in react-native 0.83+
124
- #if os(iOS)
125
121
  // When calling `recreateRootViewWithBundleURL:` from `EXReactRootViewFactory`,
126
122
  // we don't want to loop the ReactDelegate again. Otherwise, it will be an infinite loop.
127
- rootView = factory.superView(
128
- withModuleName: moduleName ?? defaultModuleName,
129
- initialProperties: initialProps,
130
- launchOptions: launchOptions ?? [:],
131
- devMenuConfiguration: self.devMenuConfiguration
132
- )
133
- #else
134
123
  rootView = factory.superView(
135
124
  withModuleName: moduleName ?? defaultModuleName,
136
125
  initialProperties: initialProps,
137
126
  launchOptions: launchOptions ?? [:]
138
127
  )
139
- #endif
140
128
  } else {
141
- #if os(iOS)
142
- rootView = rootViewFactory.view(
143
- withModuleName: moduleName ?? defaultModuleName,
144
- initialProperties: initialProps,
145
- launchOptions: launchOptions,
146
- devMenuConfiguration: self.devMenuConfiguration
147
- )
148
- #else
149
129
  rootView = rootViewFactory.view(
150
130
  withModuleName: moduleName ?? defaultModuleName,
151
131
  initialProperties: initialProps,
152
132
  launchOptions: launchOptions
153
133
  )
154
- #endif
155
134
  }
156
135
 
157
136
  return rootView
package/ios/Expo.h CHANGED
@@ -1,4 +1,3 @@
1
1
  #import <ExpoModulesCore/ExpoModulesCore.h>
2
2
  #import <Expo/EXAppDefinesLoader.h>
3
- #import <Expo/ExpoReactNativeFactory.h>
4
- #import <Expo/RCTAppDelegateUmbrella.h>
3
+ #import <Expo/EXAppDelegateWrapper.h>
@@ -3,9 +3,9 @@
3
3
  @preconcurrency import ExpoModulesCore
4
4
 
5
5
  private let fetchRequestQueue = DispatchQueue(label: "expo.modules.fetch.RequestQueue")
6
- nonisolated(unsafe) internal var urlSessionConfigurationProvider: NSURLSessionConfigurationProvider?
6
+ @MainActor internal var urlSessionConfigurationProvider: NSURLSessionConfigurationProvider?
7
7
 
8
- public final class ExpoFetchModule: Module {
8
+ @MainActor public final class ExpoFetchModule: @preconcurrency Module {
9
9
  private lazy var urlSession = createURLSession()
10
10
  private let urlSessionDelegate: URLSessionSessionDelegateProxy
11
11