-
Notifications
You must be signed in to change notification settings - Fork 3.5k
UIScene Migration documentation updates #13045
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -713,6 +713,19 @@ event, visit Apple's documentation on | |||||
| [`UISceneDelegate`]: {{site.apple-dev}}/documentation/uikit/uiscenedelegate | ||||||
| [`UIWindowSceneDelegate`]: {{site.apple-dev}}/documentation/uikit/uiwindowscenedelegate | ||||||
|
|
||||||
| | App Delegate Method | Scene Delegate Equivalent | | ||||||
| | :--- |:-----------------------------------------------------------------------------------------------------------------------------------------------------------| | ||||||
| | [`applicationDidBecomeActive`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622956-applicationdidbecomeactive) | [`sceneDidBecomeActive`](https://developer.apple.com/documentation/uikit/uiscenedelegate/3197915-scenedidbecomeactive) | | ||||||
| | [`applicationWillResignActive`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622950-applicationwillresignactive) | [`sceneWillResignActive`](https://developer.apple.com/documentation/uikit/uiscenedelegate/3197919-scenewillresignactive) | | ||||||
| | [`applicationWillEnterForeground`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623076-applicationwillenterforeground) | [`sceneWillEnterForeground`](https://developer.apple.com/documentation/uikit/uiscenedelegate/3197918-scenewillenterforeground) | | ||||||
| | [`applicationDidEnterBackground`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622997-applicationdidenterbackground) | [`sceneDidEnterBackground`](https://developer.apple.com/documentation/uikit/uiscenedelegate/3197917-scenedidenterbackground) | | ||||||
| | [`application:continueUserActivity:restorationHandler:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623072-application) | [`scene:continueUserActivity:`](https://developer.apple.com/documentation/uikit/uiscenedelegate/scene(_:continue:)) | | ||||||
| | [`application:performActionForShortcutItem:completionHandler:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/application(_:performactionfor:completionhandler:)) | [`windowScene:performActionForShortcutItem:completionHandler:`](https://developer.apple.com/documentation/uikit/uiwindowscenedelegate/3238088-windowscene) | | ||||||
| | [`application:openURL:options:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application) | [`scene:openURLContexts:`](https://developer.apple.com/documentation/uikit/uiscenedelegate/3238059-scene) | | ||||||
| | [`application:performFetchWithCompletionHandler:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623125-application) | [`BGAppRefreshTask`](https://developer.apple.com/documentation/backgroundtasks/bgapprefreshtask) | | ||||||
| | [`application:willFinishLaunchingWithOptions:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623032-application) | [`scene:willConnectToSession:options:`](https://developer.apple.com/documentation/uikit/uiscenedelegate/3197914-scene) | | ||||||
| | [`application:didFinishLaunchingWithOptions:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622921-application) | [`scene:willConnectToSession:options:`](https://developer.apple.com/documentation/uikit/uiscenedelegate/3197914-scene) | | ||||||
|
|
||||||
| <Tabs key="ios-language-switcher"> | ||||||
| <Tab name="Swift"> | ||||||
|
|
||||||
|
|
@@ -788,6 +801,85 @@ migrating to the `UIScene` lifecycle, the launch options will be `nil`. Any logi | |||||
| performed here related to the launch options should be moved to the | ||||||
| `scene:willConnectToSession:options:` event. | ||||||
|
|
||||||
|
|
||||||
| 6. [Optional] Migrate other deprecated APIs to support multiple scenes in the future. | ||||||
|
|
||||||
| | Deprecated API | UIScene Replacement | | ||||||
| |:---------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------| | ||||||
| | [`UIScreen mainScreen`](https://developer.apple.com/documentation/uikit/uiscreen/1617815-mainscreen) | `self.pluginRegistrar.viewController.view.window.windowScene.screen` | | ||||||
| | [`UIApplication keyWindow`](https://developer.apple.com/documentation/uikit/uiapplication/1622924-keywindow) | `self.pluginRegistrar.viewController.view.window.windowScene.keyWindow` | | ||||||
| | [`UIApplication windows`](https://developer.apple.com/documentation/uikit/uiapplication/1622975-windows) | `self.pluginRegistrar.viewController.view.window.windowScene.windows` | | ||||||
| | [`UIApplicationDelegate window`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/window) | `self.pluginRegistrar.viewController.view.window.windowScene.keyWindow` | | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of using https://developer.apple.com/documentation/uikit/uiwindowscene/screen?language=objc |
||||||
|
|
||||||
| First, create a new view provider with an instance method that holds a reference to your `FlutterPluginRegistrar`. | ||||||
|
|
||||||
| <Tabs key="ios-language-switcher"> | ||||||
| <Tab name="Objective-C"> | ||||||
|
|
||||||
| ```objc | ||||||
| @implementation YourFlutterViewProvider | ||||||
| - (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar { | ||||||
| self = [super init]; | ||||||
| if (self) { | ||||||
| _registrar = registrar; | ||||||
| } | ||||||
| return self; | ||||||
| } | ||||||
|
|
||||||
| - (UIViewController *)viewController { | ||||||
| return self.registrar.viewController; | ||||||
| } | ||||||
| @end | ||||||
| ``` | ||||||
|
|
||||||
| </Tab> | ||||||
| <Tab name="Swift"> | ||||||
|
|
||||||
| ```swift | ||||||
| final class ViewPresenterProvider: ViewPresenterProvider { | ||||||
| private let registrar: FlutterPluginRegistrar | ||||||
|
|
||||||
| init(registrar: FlutterPluginRegistrar) { | ||||||
| self.registrar = registrar | ||||||
| } | ||||||
|
|
||||||
| var viewPresenter: ViewPresenter? { | ||||||
| registrar.viewController | ||||||
| } | ||||||
| } | ||||||
| ``` | ||||||
| </Tab> | ||||||
| </Tabs> | ||||||
|
|
||||||
| Next, in your plugin’s `registerWithRegistrar` method, initialize your new view provider and pass it into your plugin instance. | ||||||
|
|
||||||
| <Tabs key="ios-language-switcher"> | ||||||
| <Tab name="Objective-C"> | ||||||
|
|
||||||
| ```objc diff | ||||||
| + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar { | ||||||
| - YourFlutterViewPlugin *instance = [[YourFlutterViewPlugin alloc] init]; | ||||||
| + YourFlutterViewProvider *viewProvider = [[YourFlutterViewProvider alloc] initWithRegistrar:registrar]; | ||||||
| +. YourFlutterViewPlugin *instance = [[YourFlutterViewPlugin alloc] initWithViewProvider:viewProvider]; | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is an extra period at the beginning of this line. This appears to be a typo and should be removed.
Suggested change
|
||||||
| SetUpFLTImagePickerApi(registrar.messenger, instance); | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| </Tab> | ||||||
| <Tab name="Swift"> | ||||||
|
|
||||||
| ```swift diff | ||||||
| public static func register(with registrar: FlutterPluginRegistrar) { | ||||||
| - let instance = FileSelectorPlugin() | ||||||
| + let instance = YourFlutterPlugin( | ||||||
| viewPresenterProvider: ViewPresenterProvider(registrar: registrar)) | ||||||
| YourFlutterPluginApiSetup.setUp(binaryMessenger: registrar.messenger(), api: instance) | ||||||
| } | ||||||
| ``` | ||||||
| </Tab> | ||||||
| </Tabs> | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think let's simplify this. Wrapping it in a ViewProvider is likely too verbose for an average developer. I'd say something like: Instead of accessing these APIs, you can access the ObjC @interface MyPlugin ()
+ @property(nonatomic, weak) NSObject<FlutterPluginRegistrar> *registrar;
+ - (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar;
@end
@implementation MyPlugin
+ - (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
+ self = [super init];
+ if (self) {
+ _registrar = registrar;
+ }
+ return self;
+ }
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
- MyPlugin *instance = [[MyPlugin alloc] init];
+ MyPlugin *instance = [[MyPlugin alloc] initWithRegistrar:registrar];
}
- (void)someMethod {
- UIScreen *screen = [UIScreen mainScreen];
+ UIScreen *screen = self.registrar.viewController.view.window.windowScene.screen;
- UIWindow *window = [UIApplication sharedApplication].delegate.window;
+ UIWindow *window = self.registrar.viewController.view.window;
- UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
+ if (@available(iOS 15.0, *)) {
+ UIWindow *keyWindow = self.registrar.viewController.view.window.windowScene.keyWindow;
+ } else {
+ for (UIWindow *window in self.registrar.viewController.view.window.windowScene.windows) {
+ if (window.isKeyWindow) {
+ UIWindow *keyWindow = window;
+ }
+ }
+ }
- NSArray<UIWindow *> *windows = [UIApplication sharedApplication].windows;
+ NSArray<UIWindow *> *windows = self.pluginRegistrar.viewController.view.window.windowScene.windows;
}Swift public class MyPlugin: NSObject, FlutterPlugin {
+ var registrar: FlutterPluginRegistrar
+ init(registrar: FlutterPluginRegistrar) {
+ self.registrar = registrar
+ }
public static func register(with registrar: FlutterPluginRegistrar) {
- let instance = MyPlugin()
+ let instance = MyPlugin(registrar: registrar)
}
func someMethod {
- let screen = UIScreen.main;
+ let screen = self.registrar.viewController?.view.window?.windowScene?.screen;
- let window = UIApplication.shared.delegate?.window;
+ let window = self.registrar.viewController?.view.window;
- let keyWindow = UIApplication.shared.keyWindow;
+ if #available(iOS 15.0, *) {
+ let keyWindow = self.registrar.viewController?.view.window?.windowScene?.keyWindow
+ } else {
+ let keyWindow = self.registrar.viewController?.view.window?.windowScene?.windows.filter({ $0.isKeyWindow }).first
+ }
- let windows = UIApplication.shared.windows;
+ let windows = self.registrar.viewController?.view.window?.windowScene?.windows;
}
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah i see, okay. |
||||||
|
|
||||||
|
|
||||||
| ## Bespoke FlutterViewController usage | ||||||
|
|
||||||
| For apps that use a `FlutterViewController` instantiated from Storyboards in | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://developer.apple.com/documentation/uikit/uiapplication/1622975-windows does not work