Skip to content

Commit 9c54321

Browse files
committed
feat: formatting of the RFC
1 parent 8462aee commit 9c54321

File tree

1 file changed

+33
-33
lines changed

1 file changed

+33
-33
lines changed

proposals/0000-ios-scenedelegate-and-resizing.md

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
---
2-
title: \[iOS\] Migration to SceneDelegate
2+
title: iOS Migration to SceneDelegate
33
author:
44
- artus9033
55
date: 16.12.2025
66
---
77

8-
# RFC0000: [iOS] Migration to SceneDelegate
8+
# RFC0000: [iOS] Migration to `SceneDelegate`
99

1010
## Summary
1111

12-
iOS26 introduced deprecation of many UIApplication APIs and made SceneDelegate API the preferred one, notifying programmers with a warning that "UIScene lifecycle will soon be required". In future versions of iOS, SceneDelegate [is going to be the only supported API](https://developer.apple.com/documentation/technotes/tn3187-migrating-to-the-uikit-scene-based-life-cycle#:~:text=Failure%20to%20adopt%20will%20result%20in%20an%20assert%20in%20the%20future.) and therefore we need to start migrating to it.
12+
iOS26 introduced deprecation of many UIApplication APIs and made `SceneDelegate` API the preferred one, notifying programmers with a warning that "UIScene lifecycle will soon be required". In future versions of iOS, `SceneDelegate` [is going to be the only supported API](https://developer.apple.com/documentation/technotes/tn3187-migrating-to-the-uikit-scene-based-life-cycle#:~:text=Failure%20to%20adopt%20will%20result%20in%20an%20assert%20in%20the%20future.) and therefore we need to start migrating to it.
1313

1414
![](assets/0000-ios-deprecation-warning.png)
1515

16-
It is possible to perform dynamic window resizing both via stage manager (split view) and freely via the bottom-right corner handle. SceneDelegate with proper configuration in Info.plist can enable the multi-window capability for iPadOS, which would require adjustments in RN code and RN libraries code to accommodate such design. Such a change would be large and shall be addressed in a separate RFC. The scope of this RFC is to cover a single resizable window (single instance of a given RN app), yielding the assumption that UIApplicationSupportsMultipleScenes **must not** be set to true at the moment. This RFC will bring in an additive change that should allow for adoption of a new SceneDelegate entrypoint while also allowing for (deprecated) usage of AppDelegate. Also, the @react-native-community/template and packages/rn-tester should be migrated to implement the SceneDelegate API.
16+
It is possible to perform dynamic window resizing both via stage manager (split view) and freely via the bottom-right corner handle. `SceneDelegate` with proper configuration in `Info.plist` can enable the multi-window capability for iPadOS, which would require adjustments in RN code and RN libraries code to accommodate such design. Such a change would be large and shall be addressed in a separate RFC. The scope of this RFC is to cover a single resizable window (single instance of a given RN app), yielding the assumption that `UIApplicationSupportsMultipleScenes` **must not** be set to true at the moment. This RFC will bring in an additive change that should allow for adoption of a new `SceneDelegate` entrypoint while also allowing for (deprecated) usage of `AppDelegate`. Also, the `@react-native-community/template` and `packages/rn-tester` should be migrated to implement the `SceneDelegate` API.
1717

1818
One related aspect not covered by this RFC is the performance of useWindowDimensions hook, which during intensive resizing of the application behaves suboptimal. This matter shall be addressed in a separate RFC.
1919

2020
The idea proposed in this RFC is to:
2121

22-
1) migrate from AppDelegate to SceneDelegate
23-
2) educate on the need to migrate existing apps to adopt SceneDelegate
22+
1) migrate from `AppDelegate` to `SceneDelegate`
23+
2) educate on the need to migrate existing apps to adopt `SceneDelegate`
2424

2525
## Basic example
2626

@@ -34,15 +34,15 @@ Support for iOS scene lifecycle APIs that are the current preferred approach for
3434

3535
As an example, the following key APIs are already deprecated:
3636

37-
- [application:continueUserActivity:restorationHandler:](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/applicationdidbecomeactive\(_:\)?language=objc) in favor of [scene(\_:continue:)](https://developer.apple.com/documentation/UIKit/UISceneDelegate/scene\(_:continue:\)) \- used by RCTLinkingManager
38-
- [application:openURL:options:](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/application\(_:open:options:\)?language=objc) in favor of [scene(\_:openURLContexts:)](https://developer.apple.com/documentation/uikit/uiscenedelegate/scene\(_:openurlcontexts:\)) \- used by RCTLinkingManager
37+
- [application:continueUserActivity:restorationHandler:](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/applicationdidbecomeactive\(_:\)?language=objc) in favor of [scene(\_:continue:)](https://developer.apple.com/documentation/UIKit/UI`SceneDelegate`/scene\(_:continue:\)) \- used by RCTLinkingManager
38+
- [application:openURL:options:](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/application\(_:open:options:\)?language=objc) in favor of [scene(\_:openURLContexts:)](https://developer.apple.com/documentation/uikit/ui`scenedelegate`/scene\(_:openurlcontexts:\)) \- used by RCTLinkingManager
3939
- non-UIScene lifecycle: [https://developer.apple.com/documentation/technotes/tn3187-migrating-to-the-uikit-scene-based-life-cycle](https://developer.apple.com/documentation/technotes/tn3187-migrating-to-the-uikit-scene-based-life-cycle) \- used by base application code
4040

4141
## Detailed design
4242

43-
### SceneDelegate `RCTReactNativeFactory` entrypoint
43+
### `SceneDelegate` `RCTReactNativeFactory` entrypoint
4444

45-
To support SceneDelegate lifecycle, a new entrypoint for RN application initialization should be provided in `RCTReactNativeFactory`, which would be invoked from SceneDelegate lifecycle methods. The existing entrypoint from AppDelegate would be kept for backwards compatibility, making this an additive change. An example code snippet of a `SceneDelegate` using React Native proposed in this RFC would be:
45+
To support `SceneDelegate` lifecycle, a new entrypoint for RN application initialization should be provided in `RCTReactNativeFactory`, which would be invoked from `SceneDelegate` lifecycle methods. The existing entrypoint from `AppDelegate` would be kept for backwards compatibility, making this an additive change. An example code snippet of a ``SceneDelegate`` using React Native proposed in this RFC would be:
4646

4747
```objc
4848
@interface SceneDelegate ()
@@ -85,45 +85,45 @@ To support SceneDelegate lifecycle, a new entrypoint for RN application initiali
8585
@end
8686
```
8787
88-
### Migration from AppDelegate to SceneDelegate
88+
### Migration from `AppDelegate` to `SceneDelegate`
8989
9090
Adoption of UIScene lifecycle requires the following actions:
9191
9292
* In application base code
93-
* migration from AppDelegate as the primary point of lifecycle-related logic to SceneDelegate; for backwards compatibility, RN public API integration points will still be compatible with AppDelegate approach for users that may not want to migrate immediately
94-
* invoke RN RCTLinkingManager methods from SceneDelegate:
95-
* scene:continueUserActivity:
96-
* scene:openURLContexts:
93+
* migration from `AppDelegate` as the primary point of lifecycle-related logic to `SceneDelegate`; for backwards compatibility, RN public API integration points will still be compatible with `AppDelegate` approach for users that may not want to migrate immediately
94+
* invoke RN `RCTLinkingManager` methods from `SceneDelegate`:
95+
* `scene:continueUserActivity:`
96+
* `scene:openURLContexts:`
9797
* update of the app's Info.plist to include a UIApplicationSceneManifest specifying the support and disabling multiple scenes capability
9898
* In React Native code:
99-
* migration of code that relies on launchOptions and deprecated UIApplicationLaunchOptions\* keys to UIScene lifecycle and UIScene.ConnectionOptions.userActivities
99+
* migration of code that relies on `launchOptions` and deprecated `UIApplicationLaunchOptions`\* keys to UIScene lifecycle and UIScene.ConnectionOptions.userActivities
100100
* In React Native code, RN native libraries’ code:
101101
* migration of app lifecycle methods from application\* to scene\* as per [https://developer.apple.com/documentation/technotes/tn3187-migrating-to-the-uikit-scene-based-life-cycle](https://developer.apple.com/documentation/technotes/tn3187-migrating-to-the-uikit-scene-based-life-cycle)
102-
* migration of code that relies on *any* *deprecated* AppDelegate-related APIs, which detailed description of is presented below
102+
* migration of code that relies on *any* *deprecated* `AppDelegate`-related APIs, which detailed description of is presented below
103103
104-
To enforce the user not to enable the UIApplicationSceneManifest.UIApplicationSupportsMultipleScenes capability in Info.plist, from now on, the following warning would be printed from RCTReactNativeFactory provided the user had enabled the multi-window capability:
104+
To enforce the user not to enable the `UIApplicationSceneManifest`.`UIApplicationSupportsMultipleScenes` capability in `Info.plist`, from now on, the following warning would be printed from `RCTReactNativeFactory` provided the user had enabled the multi-window capability:
105105
106106
![](assets/0000-console-warning-unsupported-configuration.png)
107107
108108
#### Migration: RN app template, RNTester
109109
110110
In case of the RN app template, the iOS boilerplate code is limited only to basic bootstrapping of the application. This implies adjustments to:
111111
112-
* `Info.plist` \- add support for SceneDelegate
113-
* `SceneDelegate.mm` \- implement the SceneDelegate
114-
* `AppDelegate.mm` \- move app bootstrap code from here to `SceneDelegate.mm`
112+
* `Info.plist` \- add support for `SceneDelegate`
113+
* ``SceneDelegate`.mm` \- implement the `SceneDelegate`
114+
* ``AppDelegate`.mm` \- move app bootstrap code from here to ``SceneDelegate`.mm`
115115
116116
#### Migration: inspect usages of `RCTReactNativeFactory`
117117
118-
Support methods for initializing React Native from `SceneDelegate`’s lifecycle methods.
118+
Support methods for initializing React Native from ``SceneDelegate``’s lifecycle methods.
119119
120120
#### Migration: `RCTLinkingManager`
121121
122-
The linking manager is using `AppDelegate` methods for handling URLs being opened at runtime. This needs to be migrated to SceneDelegate. To maintain backwards compatibility, we can implement both approaches and \- to ensure that only one is invoked at a given time \- conditionally check if the app is based on `AppDelegate` or has scenes to ensure only one listener handles the event. The Scene lifecycle options (`NSDictionary`) are adapted to the format of `AppDelegate` launchOptions (`NSDictionary` as well).
122+
The linking manager is using ``AppDelegate`` methods for handling URLs being opened at runtime. This needs to be migrated to `SceneDelegate`. To maintain backwards compatibility, we can implement both approaches and \- to ensure that only one is invoked at a given time \- conditionally check if the app is based on ``AppDelegate`` or has scenes to ensure only one listener handles the event. The Scene lifecycle options (`NSDictionary`) are adapted to the format of ``AppDelegate`` launchOptions (`NSDictionary` as well).
123123
124124
#### Migration: RCTDevLoadingView
125125
126-
The does not account for updating the overlay UIWindow constraints so it does not get resized along with the main window. The proposed fix is to update the constraints based on KVO observation of the main window’s frame.
126+
The does not account for updating the overlay `UIWindow` constraints so it does not get resized along with the main window. The proposed fix is to update the constraints based on KVO observation of the main window’s frame.
127127
128128
![](assets/0000-RCTDevLoadingView-width.png)
129129
![](assets/0000-RCTDevLoadingView-width-clipped.png)
@@ -132,42 +132,42 @@ The does not account for updating the overlay UIWindow constraints so it does no
132132
133133
Dimensions currently are exported as a constant. Such design does not fit the concept of resizable windows. To accommodate this, `RCTDeviceInfo` (iOS native module) should update its internal state variable upon changes to the frame so as to make `getConstants` return a value that is up-to-date at the time of invocation.
134134
135-
Dimensions (JS API) contains a `getConstants` method that wraps the native `getConstants` method and caches the result internally. The caching would now be obsolete (since the value may change in time), therefore the underlying native method should always be invoked. Moreover, the naming of the JS `getConstants` method in face of resizable windows may be misleading, since from now on the dimensions are not constant. Therefore, I propose a gradual adoption of a new method of same functionality, `getInfo()`, along with the deprecation of `getConstants()`, on the JS API side. A rough draft of the JS API changes would be:
135+
`Dimensions` (JS API) contains a `getConstants` method that wraps the native `getConstants` method and caches the result internally. The caching would now be obsolete (since the value may change in time), therefore the underlying native method should always be invoked. Moreover, the naming of the JS `getConstants` method in face of resizable windows may be misleading, since from now on the dimensions are not constant. Therefore, I propose a gradual adoption of a new method of same functionality, `getInfo()`, along with the deprecation of `getConstants()`, on the JS API side. A rough draft of the JS API changes would be:
136136
137137
![](assets/0000-nativedeviceinfo-api.png)
138138
139139
## Drawbacks
140140
141-
### Migration from AppDelegate to SceneDelegate
141+
### Migration from `AppDelegate` to `SceneDelegate`
142142
143143
- In React Native source and RNTester: will be covered by the PR following this RFC
144-
- In user RN applications using UIApplicationSupportsMultipleScenes=NO: adjusting Info.plist and the entrypoint according to the upgrade helper diff
145-
- In user RN applications using UIApplicationSupportsMultipleScenes=YES:
144+
- In user RN applications using `UIApplicationSupportsMultipleScenes=NO`: adjusting Info.plist and the entrypoint according to the upgrade helper diff
145+
- In user RN applications using `UIApplicationSupportsMultipleScenes=YES`:
146146
- Ones not using native code:
147-
- adjusting Info.plist and the entrypoint according to the upgrade helper diff
147+
- adjusting `Info.plist` and the entrypoint according to the upgrade helper diff
148148
- ensuring that consumed libraries work well in multi-instance setups
149149
- Ones using native code:
150150
- the above
151-
- migrating from AppDelegate lifecycle methods to UIScene lifecycle methods
151+
- migrating from `AppDelegate` lifecycle methods to `UIScene` lifecycle methods
152152
- inspecting usage of singletons & static fields to ensure they logically fit the multi-instance reality
153153
- In RN libraries:
154-
- migrating from AppDelegate lifecycle methods to UIScene lifecycle methods
154+
- migrating from `AppDelegate` lifecycle methods to `UIScene` lifecycle methods
155155
- inspecting usage of singletons & static fields to ensure they logically fit the multi-instance reality
156156
157157
## Alternatives
158158
What other designs have been considered? Why did you select your approach?
159159
160160
## Adoption strategy
161161
162-
This would be a breaking change for apps referencing AppDelegate-related APIs (such as lifecycle / obtaining the window instance) or using libraries that do so. For users that do not use the aforementioned, this change would not be breaking. Third-party libraries that made use of AppDelegate-related APIs should migrate to UIKit scenes-related APIs to work properly with multiple scenes.
162+
This would be a breaking change for apps referencing `AppDelegate`-related APIs (such as lifecycle / obtaining the window instance) or using libraries that do so. For users that do not use the aforementioned, this change would not be breaking. Third-party libraries that made use of `AppDelegate`-related APIs should migrate to UIKit scenes-related APIs to work properly with multiple scenes.
163163
164164
## How we teach this
165165
166166
For use cases not featuring native code, the migration should follow the RN upgrade helper diffs to adapt native app code.
167167
168168
For use cases featuring native code, the migration will additionally require migrating to UIKit scenes-related APIs.
169169
170-
We should also mention APIs referenced in RN code that were used with AppDelegate and were migrated as examples:
170+
We should also mention APIs referenced in RN code that were used with `AppDelegate` and were migrated as examples:
171171
172172
- `UIScreen.mainScreen.bounds.size` -> `RCTKeyWindow().bounds.frame.size`
173173
- `RCTSharedApplicatiorean.delegate.window` -> `RCTKeyWindow()`

0 commit comments

Comments
 (0)