Repository: expo/expo
Pull request #36787: [ios][expo] Add `createRootViewController` to the factory
Author: login: alanjhughes
Labels: name: bot: passed checks
description: ExpoBot has nothing to complain about
name: published
description: Changes from the PR have been published to npm
name: bot: fingerprint changed
Created: 2025-05-09T21:52:38Z | Merged: 2025-05-19T08:00:40Z

# Why
Closes #36772
`createRootViewController` needs to be added to the `ExpoReactNativeFactoryDelegate`

# How
Override the method in `ExpoReactNativeFactoryDelegate` and call the handlers. We only use this for `expo-screen-orientation`

# Test Plan
`expo-screen-orientation` is setup correctly and works as expected



Linked issue #36772: [expo-screen-orientation] Not detecting orientation change on iOS
### Minimal reproducible example

https://github.com/vr7bd/expo-screen-orientation-issue

### Steps to reproduce

- Clone the repo
- Run the command `pnpm i && pnpm expo prebuild --clean -p ios && pnpm expo run:ios` or the equivalent command from your package manager. Make sure to run in on an iPad (haven't tested it on iPhone)
- Change the orientation of the device. You will not see logs that are supposed to get printed when the orientation changes

This issue started occurring after upgrading to Expo SDK 53 and wasn't happening on SDK 52. It doesn't happen on Android. It hasn't been tested on iPhone.

## Expected behavior
To fire events after the orientation has been changed. 

## Actual behavior
No events are getting fired when the orientation changes 

### Environment

```text
expo-env-info 1.3.3 environment info:
    System:
      OS: macOS 15.4.1
      Shell: 5.9 - /bin/zsh
    Binaries:
      Node: 22.15.0 - ~/Library/pnpm/node
      npm: 10.9.2 - ~/Library/pnpm/npm
    Managers:
      CocoaPods: 1.16.2 - /opt/homebrew/bin/pod
    SDKs:
      iOS SDK:
        Platforms: DriverKit 24.4, iOS 18.4, macOS 15.4, tvOS 18.4, visionOS 2.4, watchOS 11.4
      Android SDK:
        Android NDK: 22.1.7171670
    IDEs:
      Android Studio: 2024.3 AI-243.25659.59.2432.13423653
      Xcode: 16.3/16E140 - /usr/bin/xcodebuild
    npmPackages:
      expo: ~53.0.9 => 53.0.9
      react: 19.0.0 => 19.0.0
      react-native: 0.79.2 => 0.79.2
    Expo Workflow: managed
```

### Expo Doctor Diagnostics

```text
15/15 checks passed. No issues detected!
```
Linked issue comments: user: login: Intrflex
created_at: 2025-05-17T08:58:34Z
body: I can confirm this i am not getting any events firing from it at all more specifically only on release builds of IOS though
author_association: NONE

Diff:
diff --git a/apps/bare-expo/ios/Podfile.lock b/apps/bare-expo/ios/Podfile.lock
index e34c763ea582a2..41610c6bfd09da 100644
--- a/apps/bare-expo/ios/Podfile.lock
+++ b/apps/bare-expo/ios/Podfile.lock
@@ -43,17 +43,17 @@ PODS:
     - React-Core
   - EXJSONUtils (0.15.0)
   - EXJSONUtils/Tests (0.15.0)
-  - EXManifests (0.16.4):
+  - EXManifests (0.16.5):
     - ExpoModulesCore
-  - EXManifests/Tests (0.16.4):
+  - EXManifests/Tests (0.16.5):
     - ExpoModulesCore
     - ExpoModulesTestCore
-  - EXNotifications (0.31.1):
+  - EXNotifications (0.31.2):
     - ExpoModulesCore
-  - EXNotifications/Tests (0.31.1):
+  - EXNotifications/Tests (0.31.2):
     - ExpoModulesCore
     - ExpoModulesTestCore
-  - Expo (53.0.8):
+  - Expo (53.0.9):
     - DoubleConversion
     - ExpoModulesCore
     - glog
@@ -411,11 +411,11 @@ PODS:
     - ExpoModulesCore
   - ExpoAsset (11.1.5):
     - ExpoModulesCore
-  - ExpoAudio (0.4.4):
+  - ExpoAudio (0.4.5):
     - ExpoModulesCore
   - ExpoBackgroundFetch (13.1.5):
     - ExpoModulesCore
-  - ExpoBackgroundTask (0.2.6):
+  - ExpoBackgroundTask (0.2.7):
     - ExpoModulesCore
   - ExpoBattery (9.1.4):
     - ExpoModulesCore
@@ -436,7 +436,7 @@ PODS:
   - ExpoClipboard/Tests (7.1.4):
     - ExpoModulesCore
     - ExpoModulesTestCore
-  - ExpoContacts (14.2.3):
+  - ExpoContacts (14.2.4):
     - ExpoModulesCore
   - ExpoCrypto (14.1.4):
     - ExpoModulesCore
@@ -446,9 +446,9 @@ PODS:
     - ExpoModulesCore
   - ExpoDomWebView (0.1.4):
     - ExpoModulesCore
-  - ExpoFileSystem (18.1.9):
+  - ExpoFileSystem (18.1.10):
     - ExpoModulesCore
-  - ExpoFileSystem/Tests (18.1.9):
+  - ExpoFileSystem/Tests (18.1.10):
     - ExpoModulesCore
     - ExpoModulesTestCore
   - ExpoFont (13.3.1):
@@ -473,7 +473,7 @@ PODS:
     - SDWebImageAVIFCoder (~> 0.11.0)
     - SDWebImageSVGCoder (~> 1.7.0)
     - SDWebImageWebPCoder (~> 0.14.6)
-  - ExpoImageManipulator (13.1.6):
+  - ExpoImageManipulator (13.1.7):
     - EXImageLoader
     - ExpoModulesCore
     - SDWebImageWebPCoder
@@ -486,7 +486,7 @@ PODS:
     - ExpoModulesCore
   - ExpoLinearGradient (14.1.4):
     - ExpoModulesCore
-  - ExpoLinking (7.1.4):
+  - ExpoLinking (7.1.5):
     - ExpoModulesCore
   - ExpoLivePhoto (0.1.4):
     - ExpoModulesCore
@@ -494,11 +494,11 @@ PODS:
     - ExpoModulesCore
   - ExpoLocalization (16.1.5):
     - ExpoModulesCore
-  - ExpoLocation (18.1.4):
+  - ExpoLocation (18.1.5):
     - ExpoModulesCore
   - ExpoMailComposer (14.1.4):
     - ExpoModulesCore
-  - ExpoMaps (0.9.9):
+  - ExpoMaps (0.10.0):
     - ExpoModulesCore
   - ExpoMediaLibrary (17.1.6):
     - ExpoModulesCore
@@ -509,7 +509,7 @@ PODS:
     - React-Core
   - ExpoMeshGradient (0.3.4):
     - ExpoModulesCore
-  - ExpoModulesCore (2.3.12):
+  - ExpoModulesCore (2.3.13):
     - DoubleConversion
     - glog
     - hermes-engine
@@ -534,7 +534,7 @@ PODS:
     - ReactCommon/turbomodule/bridging
     - ReactCommon/turbomodule/core
     - Yoga
-  - ExpoModulesCore/Tests (2.3.12):
+  - ExpoModulesCore/Tests (2.3.13):
     - DoubleConversion
     - ExpoModulesTestCore
     - glog
@@ -608,7 +608,7 @@ PODS:
     - ExpoModulesCore
   - ExpoSplashScreen (0.30.8):
     - ExpoModulesCore
-  - ExpoSQLite (15.2.9):
+  - ExpoSQLite (15.2.10):
     - ExpoModulesCore
   - ExpoStoreReview (8.1.5):
     - ExpoModulesCore
@@ -620,7 +620,7 @@ PODS:
     - ExpoModulesCore
   - ExpoUI (0.1.1-alpha.7):
     - ExpoModulesCore
-  - ExpoVideo (2.1.8):
+  - ExpoVideo (2.1.9):
     - ExpoModulesCore
   - ExpoVideoThumbnails (9.1.3):
     - ExpoModulesCore
@@ -631,7 +631,7 @@ PODS:
   - EXTaskManager (13.1.5):
     - ExpoModulesCore
     - UMAppLoader
-  - EXUpdates (0.28.12):
+  - EXUpdates (0.28.13):
     - DoubleConversion
     - EASClient
     - EXManifests
@@ -661,7 +661,7 @@ PODS:
     - ReactCommon/turbomodule/bridging
     - ReactCommon/turbomodule/core
     - Yoga
-  - EXUpdates/Tests (0.28.12):
+  - EXUpdates/Tests (0.28.13):
     - DoubleConversion
     - EASClient
     - EXManifests
@@ -3597,26 +3597,26 @@ EXTERNAL SOURCES:
 
 SPEC CHECKSUMS:
   BenchmarkingModule: a97859cac8efb2f5411b2052e61841b349813a4a
-  boost: 1dca942403ed9342f98334bf4c3621f011aa7946
-  DoubleConversion: f16ae600a246532c4020132d54af21d0ddb2a385
+  boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90
+  DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb
   EASClient: 83423c51dde4c5504cb4186e1f39728273ed334b
   EXApplication: b28de982d44768fc593de9d19ca5a7a0e49685b1
   EXAV: 0809cbb31eba2111d5413f2dbb547ba9727478ee
   EXConstants: be238322d57d084dc055dbd5d6fe6479510504ce
   EXImageLoader: ab4fcf9240cf3636a83c00e3fc5229d692899428
   EXJSONUtils: 1d3e4590438c3ee593684186007028a14b3686cd
-  EXManifests: 2916c0982e95ada805b23f21bc89b3ad69ee47b2
-  EXNotifications: eb08abae61f4eba2dcd9460d6b9e5bd38371db98
-  Expo: 54adb30ffa0a086c1a4bb87364d69b7917caeb49
+  EXManifests: 75cba7539b60676be1911d024252a11b846085ed
+  EXNotifications: f0f1c97d04f06c51ea073d7b2396431e5611c1ea
+  Expo: 22dc35ce67dc330d6a2d80598f29c654fe276830
   expo-dev-client: b32e7e9c0a420a5256e38b12e8eebbf14a7031ed
   expo-dev-launcher: d506f26639ee2676977c4a8c47668a77d2d09d23
   expo-dev-menu: 2aa06bd228fe6a52e2276b71c59b90a8ec88c8a3
   expo-dev-menu-interface: 609c35ae8b97479cdd4c9e23c8cf6adc44beea0e
   ExpoAppleAuthentication: 7e358fcbcbacb7685cddb0bbeede0acd677e58f6
   ExpoAsset: 3ea3275cca6a7793b3d36fbf1075c590f803fbcb
-  ExpoAudio: 004327190053b219b463ee159a5b18f4652246d9
+  ExpoAudio: 58670fa530972e56145c4f26dee8bc39416ed78b
   ExpoBackgroundFetch: 76c48b3cd9a4ee46e5267614a30fac804de6f33e
-  ExpoBackgroundTask: fdbdb8915935ebbfd42a5eb221fe18f68b1a0cdc
+  ExpoBackgroundTask: 9296d983f3d612359419e015ded65ebe9de30ba2
   ExpoBattery: 2bdb40a8943dae1cbab23ccaaab09d0cc78de0ae
   ExpoBlur: 5d95f7ca771a0f3b9618466525dd68e46dc95f3a
   ExpoBrightness: 05e750736f8886dcf235212b0caf85b0f605fc88
@@ -3624,31 +3624,31 @@ SPEC CHECKSUMS:
   ExpoCamera: e88fc30631e63e5504ce19d52c563a6ec49e17d2
   ExpoCellular: 040f1a7a3dc3a6f573f2b077a7911bdbe3aeb923
   ExpoClipboard: c187b3101e5f38cce4c6321788e0047f1c29e152
-  ExpoContacts: 7db88e1f2536008e0363233f0c07d39563dc43a9
+  ExpoContacts: 870a98e359ee83ab9fa15eee40c66d15731747a8
   ExpoCrypto: fc94a8865ce0e06c68c10c3993f9ac9a6424d0c2
   ExpoDevice: 7a961caede6638aa0d37d0d3aa884ab957a2e3d3
   ExpoDocumentPicker: d1bb0c63fc686a74455bd7c2cd54545fa6231b66
   ExpoDomWebView: d97348ddd1e1981e30f052d58a4bcb7bfbb737f5
-  ExpoFileSystem: ff47f2208da552fbee872dedc4e74fb7c6ac5907
+  ExpoFileSystem: 3a98ca2a6f13674ecfd97327d1b44a8ace444cbd
   ExpoFont: 312c73403bbd4f98e1d6a5330641a56292583cd2
   ExpoGL: 8f7f43291e400621ef9aeb7af347816c2051ddc7
   ExpoHaptics: 68c215e070f660e0a29c45dcda4f60eeff08aefb
   ExpoImage: ef8b25fddd3613a0bbdb2936d0583bc6588197dd
-  ExpoImageManipulator: c0591a8b29f6c452a08f81c9c3af67bb8fcabb8c
+  ExpoImageManipulator: 094b748056f2654d5d7813370c910e20ef3d79b4
   ExpoImagePicker: d2fff488a0738343a3cc21e98544ee9feafaa0e6
   ExpoInsights: 58e0fb0aa39cabc674cf950942d241903fc94406
   ExpoKeepAwake: e8dedc115d9f6f24b153ccd2d1d8efcdfd68a527
   ExpoLinearGradient: 42e58f6db5ebc20b6fbbf7d31013264644ab12a4
-  ExpoLinking: d1d3b9a60b1423b0ddd6c6408710dccf62c2b092
+  ExpoLinking: 5d151d4a497d7e375308602f0a89b4e8acf7b5f8
   ExpoLivePhoto: b47b0598f335a979749ec76d4b3e5a4f9fa84150
   ExpoLocalAuthentication: fd8b38cdb709f6c327995668223529763619a5c6
   ExpoLocalization: 7cd94f24bc3ff2f263cb4258fe1e86a97bc1ea64
-  ExpoLocation: 59f4ad84a89c573224200bec7d6c6c727f2dde8a
+  ExpoLocation: afc197fce1045ac7325f095b0c149308e1653aab
   ExpoMailComposer: e0340cff1246b9c9c493f9a0f9549d92c53d7950
-  ExpoMaps: 3502d1cd3cae67f8128546928bc8359b4dbb5bff
+  ExpoMaps: f7f4cd0a94ca57eed995a4b749f757f2c716a5fe
   ExpoMediaLibrary: ad61cd80ca07da02be3d676e3d9b04b311a82c2c
   ExpoMeshGradient: ee97f0bfd80356910ca4fc2b67663ea0d9e14a41
-  ExpoModulesCore: 0bf5158ae9fb71e575582a8a48dbd26ced42f306
+  ExpoModulesCore: b57f1f9dbf35e11a01ac115ded48edd14dcd9b47
   ExpoModulesTestCore: c87ba2da38070e3483a3049453a4dc898b972eb2
   ExpoNetwork: 9fdbef259f313a1ba7ede5fa977ee3dfed6fe653
   ExpoPrint: 187f43f5d16bc8db93fb6609707ed40b8e90d3a6
@@ -3660,23 +3660,23 @@ SPEC CHECKSUMS:
   ExpoSMS: de195632beeb7ef00556750da10da667596d8967
   ExpoSpeech: fceabf6bf31aa9530ef0696e6793571edb702068
   ExpoSplashScreen: c39151354ff0fa6d0f5e7dde07a234abd5550e69
-  ExpoSQLite: ab4989b9254585dd5bbd3eb1476f3888bbbe4e43
+  ExpoSQLite: c092c9454ad72ba09e29c494470a4fe41996f741
   ExpoStoreReview: bed43bea90a5876a6a480504f95fea1521dacaa7
   ExpoSymbols: b5dbeee7d8d901d15016d4084a7096b64644e3bb
   ExpoSystemUI: 5ae7571742a69d0fc29145b6512f53879a3f42e5
   ExpoTrackingTransparency: 843029c42d70de59bb0503f6fc747b9d2fe67f7b
   ExpoUI: 4a03c3af5dd55144c788dfa3370bd244c21645ec
-  ExpoVideo: be63e187c554b3f346f27eb4d334af312769bca7
+  ExpoVideo: 54ce43735b4ceb6b3828e3eec3b750b0fe10314c
   ExpoVideoThumbnails: 4280333bee3bd4d69b3b139bd50a8b7c967095ae
   ExpoWebBrowser: 1051486eb45a2f4d1ee075712604f43f3009f90e
   EXStructuredHeaders: 32bec6771c2db18c4cd47cecae530d1d06cdf972
   EXTaskManager: 0128b9f39a088b0c762d8d1c42017e6d44200b29
-  EXUpdates: f731d1b48ef76c4985757d7eb4a04b061f771edf
+  EXUpdates: 581f73524beb53c1c46052b776a130743be28507
   EXUpdatesInterface: 64f35449b8ef89ce08cdd8952a4d119b5de6821d
   fast_float: 06eeec4fe712a76acc9376682e4808b05ce978b6
   FBLazyVector: 84b955f7b4da8b895faf5946f73748267347c975
   fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd
-  glog: 08b301085f15bcbb6ff8632a8ebaf239aae04e6a
+  glog: 5683914934d5b6e4240e497e0f4a3b42d1854183
   hermes-engine: 314be5250afa5692b57b4dd1705959e1973a8ebe
   libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7
   libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f
diff --git a/apps/expo-go/ios/Exponent.xcodeproj/project.pbxproj b/apps/expo-go/ios/Exponent.xcodeproj/project.pbxproj
index 7b6dba2731ad30..1d01fc089d1119 100644
--- a/apps/expo-go/ios/Exponent.xcodeproj/project.pbxproj
+++ b/apps/expo-go/ios/Exponent.xcodeproj/project.pbxproj
@@ -4,6 +4,7 @@
 	classes = {
 	};
 	objectVersion = 77;
+	objectVersion = 54;
 	objects = {
 
 /* Begin PBXBuildFile section */
@@ -455,6 +456,17 @@
 			path = Notifications;
 			sourceTree = "<group>";
 		};
+		2D1A6CC92D9B38910007E94A /* Notifications */ = {
+			isa = PBXFileSystemSynchronizedRootGroup;
+			exceptions = (
+			);
+			explicitFileTypes = {
+			};
+			explicitFolders = (
+			);
+			path = Notifications;
+			sourceTree = "<group>";
+		};
 /* End PBXFileSystemSynchronizedRootGroup section */
 
 /* Begin PBXFrameworksBuildPhase section */
diff --git a/apps/expo-go/ios/Podfile.lock b/apps/expo-go/ios/Podfile.lock
index 3c29c220eb50d1..4e1e678efa5c14 100644
--- a/apps/expo-go/ios/Podfile.lock
+++ b/apps/expo-go/ios/Podfile.lock
@@ -3440,9 +3440,9 @@ EXTERNAL SOURCES:
     :path: "../../../react-native-lab/react-native/packages/react-native/ReactCommon/yoga"
 
 SPEC CHECKSUMS:
-  boost: 1dca942403ed9342f98334bf4c3621f011aa7946
+  boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90
   CocoaLumberjack: 2f44e60eb91c176d471fdba43b9e3eae6a721947
-  DoubleConversion: f16ae600a246532c4020132d54af21d0ddb2a385
+  DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb
   EASClient: 83423c51dde4c5504cb4186e1f39728273ed334b
   EXApplication: b28de982d44768fc593de9d19ca5a7a0e49685b1
   EXAV: 0809cbb31eba2111d5413f2dbb547ba9727478ee
@@ -3521,13 +3521,13 @@ SPEC CHECKSUMS:
   FirebaseRemoteConfigInterop: 85bdce8babed7814816496bb6f082bc05b0a45e1
   FirebaseSessions: f5c6bfeb66a7202deaf33352017bb6365e395820
   fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd
-  glog: 08b301085f15bcbb6ff8632a8ebaf239aae04e6a
+  glog: 5683914934d5b6e4240e497e0f4a3b42d1854183
   Google-Maps-iOS-Utils: 66d6de12be1ce6d3742a54661e7a79cb317a9321
   GoogleAppMeasurement: 8a82b93a6400c8e6551c0bcd66a9177f2e067aed
   GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
   GoogleMaps: 8939898920281c649150e0af74aa291c60f2e77d
   GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
-  hermes-engine: 23516557c1f8951dee5152917a6027e52f3347f3
+  hermes-engine: eb1dc2409bfbd008988ea7e3473594bc1eb33fbe
   libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7
   libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f
   libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
@@ -3539,7 +3539,7 @@ SPEC CHECKSUMS:
   PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
   PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
   Quick: 83e25bf349dd84f894b024f48033274512d6129b
-  RCT-Folly: 36fe2295e44b10d831836cc0d1daec5f8abcf809
+  RCT-Folly: e78785aa9ba2ed998ea4151e314036f6c49e6d82
   RCTDeprecation: 83ffb90c23ee5cea353bd32008a7bca100908f8c
   RCTRequired: eb7c0aba998009f47a540bec9e9d69a54f68136e
   RCTTypeSafety: 659ae318c09de0477fd27bbc9e140071c7ea5c93
diff --git a/packages/expo-modules-core/CHANGELOG.md b/packages/expo-modules-core/CHANGELOG.md
index 0a608d23b97b9b..1b074a3eeef618 100644
--- a/packages/expo-modules-core/CHANGELOG.md
+++ b/packages/expo-modules-core/CHANGELOG.md
@@ -12,6 +12,8 @@
 
 ### 🐛 Bug fixes
 
+- [iOS] Call `createRootViewController` from the `ExpoReactNativeFactoryDelegate`. ([#36787](https://github.com/expo/expo/pull/36787) by [@alanjhughes](https://github.com/alanjhughes))
+
 ### 💡 Others
 
 ## 2.3.13 — 2025-05-08
diff --git a/packages/expo-modules-core/ios/ReactDelegates/ExpoReactDelegate.swift b/packages/expo-modules-core/ios/ReactDelegates/ExpoReactDelegate.swift
index 6e7e489fff6d0b..59e5ef2c351987 100644
--- a/packages/expo-modules-core/ios/ReactDelegates/ExpoReactDelegate.swift
+++ b/packages/expo-modules-core/ios/ReactDelegates/ExpoReactDelegate.swift
@@ -45,7 +45,7 @@ public class ExpoReactDelegate: NSObject {
   @objc
   public func createRootViewController() -> UIViewController {
     return self.handlers.lazy
-      .compactMap { $0.createRootViewController(reactDelegate: self) }
+      .compactMap { $0.createRootViewController() }
       .first(where: { _ in true }) ?? UIViewController()
   }
 }
diff --git a/packages/expo-modules-core/ios/ReactDelegates/ExpoReactDelegateHandler.swift b/packages/expo-modules-core/ios/ReactDelegates/ExpoReactDelegateHandler.swift
index 1d2e940130f25c..c7a22e44daf766 100644
--- a/packages/expo-modules-core/ios/ReactDelegates/ExpoReactDelegateHandler.swift
+++ b/packages/expo-modules-core/ios/ReactDelegates/ExpoReactDelegateHandler.swift
@@ -35,7 +35,7 @@ open class ExpoReactDelegateHandler: NSObject {
    Otherwise return nil.
    */
   @objc
-  open func createRootViewController(reactDelegate: ExpoReactDelegate) -> UIViewController? {
+  open func createRootViewController() -> UIViewController? {
     return nil
   }
 }
diff --git a/packages/expo-screen-orientation/CHANGELOG.md b/packages/expo-screen-orientation/CHANGELOG.md
index a6674b42cbce62..f30312f2377d7c 100644
--- a/packages/expo-screen-orientation/CHANGELOG.md
+++ b/packages/expo-screen-orientation/CHANGELOG.md
@@ -8,6 +8,8 @@
 
 ### 🐛 Bug fixes
 
+- [iOS] Call `createRootViewController` from the `ExpoReactNativeFactoryDelegate`. ([#36787](https://github.com/expo/expo/pull/36787) by [@alanjhughes](https://github.com/alanjhughes))
+
 ### 💡 Others
 
 ## 8.1.6 — 2025-05-06
diff --git a/packages/expo-screen-orientation/ios/ScreenOrientationReactDelegateHandler.swift b/packages/expo-screen-orientation/ios/ScreenOrientationReactDelegateHandler.swift
index be6c92c45db5e4..daf743717bcf55 100644
--- a/packages/expo-screen-orientation/ios/ScreenOrientationReactDelegateHandler.swift
+++ b/packages/expo-screen-orientation/ios/ScreenOrientationReactDelegateHandler.swift
@@ -4,7 +4,7 @@ import ExpoModulesCore
 
 @objc(EXScreenOrientationReactDelegateHandler)
 public class ScreenOrientationReactDelegateHandler: ExpoReactDelegateHandler {
-  public override func createRootViewController(reactDelegate: ExpoReactDelegate) -> UIViewController? {
+  public override func createRootViewController() -> UIViewController? {
     return ScreenOrientationViewController(defaultScreenOrientationFromPlist: ())
   }
 }
diff --git a/packages/expo/CHANGELOG.md b/packages/expo/CHANGELOG.md
index 7cbdb3ff2d7538..861c9d2fdafa43 100644
--- a/packages/expo/CHANGELOG.md
+++ b/packages/expo/CHANGELOG.md
@@ -8,6 +8,8 @@
 
 ### 🐛 Bug fixes
 
+- [iOS] Call `createRootViewController` from the `ExpoReactNativeFactoryDelegate`. ([#36787](https://github.com/expo/expo/pull/36787) by [@alanjhughes](https://github.com/alanjhughes))
+
 ### 💡 Others
 
 - Disable default timeout for `expo/fetch` requests on iOS. ([#36838](https://github.com/expo/expo/pull/36838) by [@kudo](https://github.com/kudo))
diff --git a/packages/expo/ios/AppDelegates/ExpoReactNativeFactoryDelegate.swift b/packages/expo/ios/AppDelegates/ExpoReactNativeFactoryDelegate.swift
index 901e335158272c..d17a2f8c664ce8 100644
--- a/packages/expo/ios/AppDelegates/ExpoReactNativeFactoryDelegate.swift
+++ b/packages/expo/ios/AppDelegates/ExpoReactNativeFactoryDelegate.swift
@@ -4,4 +4,10 @@ open class ExpoReactNativeFactoryDelegate: RCTDefaultReactNativeFactoryDelegate
   open override func customize(_ rootView: UIView) {
     ExpoAppDelegateSubscriberRepository.subscribers.forEach { $0.customizeRootView?(rootView) }
   }
+
+  open override func createRootViewController() -> UIViewController {
+    return ExpoAppDelegateSubscriberRepository.reactDelegateHandlers.lazy
+      .compactMap { $0.createRootViewController() }
+      .first(where: { _ in true }) ?? UIViewController()
+  }
 }


Reviews:
user: login: Kudo
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-10T05:37:07Z
user: login: lukmccall
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-10T14:47:32Z

Review comments:
diff_hunk: @@ -35,7 +35,7 @@ open class ExpoReactDelegateHandler: NSObject {
    Otherwise return nil.
    */
   @objc
-  open func createRootViewController(reactDelegate: ExpoReactDelegate) -> UIViewController? {
+  open func createRootViewController() -> UIViewController? {
path: packages/expo-modules-core/ios/ReactDelegates/ExpoReactDelegateHandler.swift
user: login: Kudo
body: fwiw, the original design to pass ExpoReactDelegate for each handlers is for callsite to get correct setup. e.g. in updates when we recreate the root view, we have to use ExpoReactDelegate to get correct root view controller from expo-splash-screen: https://github.com/expo/expo/blob/c3a83979d5e1103d3d259ea537823a3ec3972fa6/packages/expo-updates/ios/EXUpdates/ReactDelegateHandler/ExpoUpdatesReactDelegateHandler.swift#L89.

though the case is not being used here for the `createRootViewController` handler. just share the insight and open to you for making the decision.
created_at: 2025-05-10T05:36:52Z
author_association: CONTRIBUTOR

PR comments:
user: login: expo-bot
created_at: 2025-05-09T22:01:40Z
body: <!-- pr-labeler comment -->
The Pull Request introduced fingerprint changes against the base commit: 94c6a80cee8226387fb54187b33f625c78fcaab8
<details><summary>Fingerprint diff</summary>

```json
[
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../node_modules/expo",
      "reasons": [
        "rncoreAutolinkingAndroid",
        "rncoreAutolinkingIos"
      ],
      "hash": "92af40c532d2dd615af7ee2212e3bdab965c221e"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../node_modules/expo",
      "reasons": [
        "rncoreAutolinkingAndroid",
        "rncoreAutolinkingIos"
      ],
      "hash": "d90789d70a1b5287c3ed8811e8e2a0fc2f4b731f"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid",
        "expoConfigPlugins",
        "expoConfigPlugins"
      ],
      "hash": "b2ef1fffb8ec15bd3302a9828665e4e8fe89a9df"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid",
        "expoConfigPlugins",
        "expoConfigPlugins"
      ],
      "hash": "9d3948ba87f1e32314e90f76b97c34cb819cccc0"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-modules-core",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "9af9a4348567c73f30742561d0646e5115779171"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-modules-core",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "7b6f9b66f14362d336bd721f8dac6b077c6ef08a"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-screen-orientation/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "de32c4b11ae66db732f613028c7d63d0c0715d41"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-screen-orientation/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "fe719d26c9ce72b2d4b516ac2f78e5d87882c495"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "ios",
      "reasons": [
        "bareNativeDir"
      ],
      "hash": "6a68cbe6b6088f538891a1696f3d16e2e8c738bf"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "ios",
      "reasons": [
        "bareNativeDir"
      ],
      "hash": "b5fbe56e20f46785d02f1a66b038ef2189b78483"
    }
  }
]
```

</details>

---
*Generated by [PR labeler](https://github.com/expo/expo/actions/workflows/pr-labeler.yml) 🤖*

author_association: COLLABORATOR
user: login: github-actions[bot]
created_at: 2025-05-10T05:11:24Z
body: Subscribed to pull request
| File Patterns | Mentions |
| - | - |
| packages/expo/\*\* | @ide, @lukmccall, @brentvatne |
| packages/expo-modules-core/\*\* | @kudo, @lukmccall |
| packages/expo-screen-orientation/\*\* | @lukmccall |

Generated by [CodeMention](https://github.com/expo/expo/actions/workflows/codemention.yaml)
<!-- codemention header -->
author_association: CONTRIBUTOR
user: login: jacobgreenberg
created_at: 2025-06-02T14:42:33Z
body: How you update to/install this patch? 
author_association: NONE