Skip to content

Commit 6e31a22

Browse files
vashworthsfshaza2
andauthored
Update plugin migration instructions (#12591)
_Description of what this PR is changing or adding, and why:_ This change moves the plugin migration guide to the bottom so app migrations are first. This also adds a warning that plugin APIs are not available on stable yet. _Issues fixed by this PR (if any):_ _PRs or commits this PR depends on (if any):_ ## Presubmit checklist - [x] If you are unwilling, or unable, to sign the CLA, even for a _tiny_, one-word PR, please file an issue instead of a PR. - [x] If this PR is not meant to land until a future stable release, mark it as draft with an explanation. - [x] This PR follows the [Google Developer Documentation Style Guidelines](https://developers.google.com/style)—for example, it doesn't use _i.e._ or _e.g._, and it avoids _I_ and _we_ (first-person pronouns). - [x] This PR uses [semantic line breaks](https://github.com/dart-lang/site-shared/blob/main/doc/writing-for-dart-and-flutter-websites.md#semantic-line-breaks) of 80 characters or fewer. --------- Co-authored-by: Shams Zakhour <[email protected]>
1 parent 5ca9e04 commit 6e31a22

File tree

1 file changed

+134
-118
lines changed

1 file changed

+134
-118
lines changed

src/content/release/breaking-changes/uiscenedelegate.md

Lines changed: 134 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ the following:
3131
To use the UIScene lifecycle with Flutter, migrate the following support:
3232
* All Flutter apps that support iOS - See the [migration guide for Flutter
3333
apps](/release/breaking-changes/uiscenedelegate/#migration-guide-for-flutter-apps)
34-
* Flutter plugins that use iOS application lifecycle events - See the [migration
35-
guide for
36-
plugins](/release/breaking-changes/uiscenedelegate/#migration-guide-for-flutter-plugins)
3734
* Flutter embedded in iOS native apps - See the [migration guide for adding
3835
Flutter to an existing
3936
app](/release/breaking-changes/uiscenedelegate/#migration-guide-for-adding-flutter-to-existing-app-add-to-app)
37+
* Flutter plugins that use iOS application lifecycle events - See the [migration
38+
guide for
39+
plugins](/release/breaking-changes/uiscenedelegate/#migration-guide-for-flutter-plugins)
4040

4141
Migrating to UIScene shifts the AppDelegate's role—the UI lifecycle is
4242
now handled by the UISceneDelegate. The AppDelegate
@@ -270,121 +270,6 @@ For Objective-C projects, create a `SceneDelegate.h` and `SceneDelegate.m`:
270270
Info.plist from `FlutterSceneDelegate` to
271271
`$(PRODUCT_MODULE_NAME).SceneDelegate`.
272272

273-
## Migration guide for Flutter plugins
274-
275-
Not all plugins use lifecycle events. If your plugin does, though, you will
276-
need to migrate to UIKit's scene-based lifecycle.
277-
278-
1. Adopt the `FlutterSceneLifeCycleDelegate` protocol
279-
280-
```swift diff
281-
- public final class MyPlugin: NSObject, FlutterPlugin {
282-
+ public final class MyPlugin: NSObject, FlutterPlugin, FlutterSceneLifeCycleDelegate {
283-
```
284-
285-
```objc diff
286-
- @interface MyPlugin : NSObject<FlutterPlugin>
287-
+ @interface MyPlugin : NSObject<FlutterPlugin, FlutterSceneLifeCycleDelegate>
288-
```
289-
290-
2. Registers the plugin as a receiver of `UISceneDelegate` calls.
291-
292-
To continue supporting apps that have not migrated to the UIScene lifecycle yet,
293-
you might consider remaining registered to the App Delegate and keeping the App
294-
Delegate events as well.
295-
296-
```swift diff
297-
public static func register(with registrar: FlutterPluginRegistrar) {
298-
...
299-
registrar.addApplicationDelegate(instance)
300-
+ registrar.addSceneDelegate(instance)
301-
}
302-
```
303-
304-
```objc diff
305-
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
306-
...
307-
[registrar addApplicationDelegate:instance];
308-
+ [registrar addSceneDelegate:instance];
309-
}
310-
```
311-
312-
3. Add one or more of the following scene events that are needed for your
313-
plugin.
314-
315-
Most App Delegate UI events have a 1-to-1 replacement. To see details on each
316-
event, visit Apple's documentation on
317-
[UISceneDelegate]({{site.apple-dev}}/documentation/uikit/uiscenedelegate)
318-
and
319-
[UIWindowSceneDelegate]({{site.apple-dev}}/documentation/uikit/uiwindowscenedelegate).
320-
321-
322-
```swift
323-
public func scene(
324-
_ scene: UIScene,
325-
willConnectTo session: UISceneSession,
326-
options connectionOptions: UIScene.ConnectionOptions?
327-
) -> Bool { }
328-
329-
public func sceneDidDisconnect(_ scene: UIScene) { }
330-
331-
public func sceneWillEnterForeground(_ scene: UIScene) { }
332-
333-
public func sceneDidBecomeActive(_ scene: UIScene) { }
334-
335-
public func sceneWillResignActive(_ scene: UIScene) { }
336-
337-
public func sceneDidEnterBackground(_ scene: UIScene) { }
338-
339-
public func scene(
340-
_ scene: UIScene,
341-
openURLContexts URLContexts: Set<UIOpenURLContext>
342-
) -> Bool { }
343-
344-
public func scene(_ scene: UIScene, continue userActivity: NSUserActivity)
345-
-> Bool { }
346-
347-
public func windowScene(
348-
_ windowScene: UIWindowScene,
349-
performActionFor shortcutItem: UIApplicationShortcutItem,
350-
completionHandler: @escaping (Bool) -> Void
351-
) -> Bool { }
352-
```
353-
354-
```objc
355-
- (BOOL)scene:(UIScene*)scene
356-
willConnectToSession:(UISceneSession*)session
357-
options:(nullable UISceneConnectionOptions*)connectionOptions;
358-
359-
- (void)sceneDidDisconnect:(UIScene*)scene { }
360-
361-
- (void)sceneWillEnterForeground:(UIScene*)scene { }
362-
363-
- (void)sceneDidBecomeActive:(UIScene*)scene { }
364-
365-
- (void)sceneWillResignActive:(UIScene*)scene { }
366-
367-
- (void)sceneDidEnterBackground:(UIScene*)scene { }
368-
369-
- (BOOL)scene:(UIScene*)scene openURLContexts:(NSSet<UIOpenURLContext*>*)URLContexts { }
370-
371-
- (BOOL)scene:(UIScene*)scene continueUserActivity:(NSUserActivity*)userActivity { }
372-
373-
- (BOOL)windowScene:(UIWindowScene*)windowScene
374-
performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem
375-
completionHandler:(void (^)(BOOL succeeded))completionHandler { }
376-
```
377-
378-
4. Move launch logic from `application:willFinishLaunchingWithOptions:` and
379-
`application:didFinishLaunchingWithOptions:` to
380-
`scene:willConnectToSession:options:`.
381-
382-
Despite `application:willFinishLaunchingWithOptions:` and
383-
`application:didFinishLaunchingWithOptions:` not being deprecated, after
384-
migrating to UIScene lifecycle, the launch options will be `nil`. Any logic
385-
performed here related to the launch options should be moved to the
386-
`scene:willConnectToSession:options:` event.
387-
388273
## Migration guide for adding Flutter to existing app (Add to App)
389274

390275
Similar to the `FlutterAppDelegate`, the `FlutterSceneDelgate` is recommended
@@ -689,6 +574,137 @@ sceneLifeCycleDelegate.unregisterSceneLifeCycle(with: flutterEngine)
689574
[self.sceneLifeCycleDelegate unregisterSceneLifeCycleWithFlutterEngine:self.flutterEngine];
690575
```
691576

577+
## Migration guide for Flutter plugins
578+
579+
Not all plugins use lifecycle events. If your plugin does, though, you will
580+
need to migrate to UIKit's scene-based lifecycle.
581+
582+
1. Update the Dart and Flutter SDK versions in your pubspec.yaml
583+
584+
```yaml
585+
environment:
586+
sdk: ^3.10.0-290.1.beta
587+
flutter: ">=3.38.0-0.1.pre"
588+
```
589+
590+
:::warning
591+
The below Flutter APIs are available in the 3.38.0-0.1.pre beta, but are not
592+
yet available on stable. You might consider publishing a
593+
[prerelease](https://dart.dev/tools/pub/publishing#publishing-prereleases) or
594+
[preview](https://dart.dev/tools/pub/publishing#publish-preview-versions)
595+
version of your plugin to migrate early.
596+
:::
597+
598+
2. Adopt the `FlutterSceneLifeCycleDelegate` protocol
599+
600+
```swift diff
601+
- public final class MyPlugin: NSObject, FlutterPlugin {
602+
+ public final class MyPlugin: NSObject, FlutterPlugin, FlutterSceneLifeCycleDelegate {
603+
```
604+
605+
```objc diff
606+
- @interface MyPlugin : NSObject<FlutterPlugin>
607+
+ @interface MyPlugin : NSObject<FlutterPlugin, FlutterSceneLifeCycleDelegate>
608+
```
609+
610+
3. Registers the plugin as a receiver of `UISceneDelegate` calls.
611+
612+
To continue supporting apps that have not migrated to the UIScene lifecycle yet,
613+
you might consider remaining registered to the App Delegate and keeping the App
614+
Delegate events as well.
615+
616+
```swift diff
617+
public static func register(with registrar: FlutterPluginRegistrar) {
618+
...
619+
registrar.addApplicationDelegate(instance)
620+
+ registrar.addSceneDelegate(instance)
621+
}
622+
```
623+
624+
```objc diff
625+
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
626+
...
627+
[registrar addApplicationDelegate:instance];
628+
+ [registrar addSceneDelegate:instance];
629+
}
630+
```
631+
632+
4. Add one or more of the following scene events that are needed for your
633+
plugin.
634+
635+
Most App Delegate UI events have a 1-to-1 replacement. To see details for each
636+
event, visit Apple's documentation on
637+
[`UISceneDelegate`][] and [`UIWindowSceneDelegate`][].
638+
639+
[`UISceneDelegate`]: {{site.apple-dev}}/documentation/uikit/uiscenedelegate
640+
[`UIWindowSceneDelegate`]: {{site.apple-dev}}/documentation/uikit/uiwindowscenedelegate
641+
642+
643+
```swift
644+
public func scene(
645+
_ scene: UIScene,
646+
willConnectTo session: UISceneSession,
647+
options connectionOptions: UIScene.ConnectionOptions?
648+
) -> Bool { }
649+
650+
public func sceneDidDisconnect(_ scene: UIScene) { }
651+
652+
public func sceneWillEnterForeground(_ scene: UIScene) { }
653+
654+
public func sceneDidBecomeActive(_ scene: UIScene) { }
655+
656+
public func sceneWillResignActive(_ scene: UIScene) { }
657+
658+
public func sceneDidEnterBackground(_ scene: UIScene) { }
659+
660+
public func scene(
661+
_ scene: UIScene,
662+
openURLContexts URLContexts: Set<UIOpenURLContext>
663+
) -> Bool { }
664+
665+
public func scene(_ scene: UIScene, continue userActivity: NSUserActivity)
666+
-> Bool { }
667+
668+
public func windowScene(
669+
_ windowScene: UIWindowScene,
670+
performActionFor shortcutItem: UIApplicationShortcutItem,
671+
completionHandler: @escaping (Bool) -> Void
672+
) -> Bool { }
673+
```
674+
675+
```objc
676+
- (BOOL)scene:(UIScene*)scene
677+
willConnectToSession:(UISceneSession*)session
678+
options:(nullable UISceneConnectionOptions*)connectionOptions { }
679+
680+
- (void)sceneDidDisconnect:(UIScene*)scene { }
681+
682+
- (void)sceneWillEnterForeground:(UIScene*)scene { }
683+
684+
- (void)sceneDidBecomeActive:(UIScene*)scene { }
685+
686+
- (void)sceneWillResignActive:(UIScene*)scene { }
687+
688+
- (void)sceneDidEnterBackground:(UIScene*)scene { }
689+
690+
- (BOOL)scene:(UIScene*)scene openURLContexts:(NSSet<UIOpenURLContext*>*)URLContexts { }
691+
692+
- (BOOL)scene:(UIScene*)scene continueUserActivity:(NSUserActivity*)userActivity { }
693+
694+
- (BOOL)windowScene:(UIWindowScene*)windowScene
695+
performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem
696+
completionHandler:(void (^)(BOOL succeeded))completionHandler { }
697+
```
698+
699+
5. Move launch logic from `application:willFinishLaunchingWithOptions:` and
700+
`application:didFinishLaunchingWithOptions:` to
701+
`scene:willConnectToSession:options:`.
702+
703+
Despite `application:willFinishLaunchingWithOptions:` and
704+
`application:didFinishLaunchingWithOptions:` not being deprecated, after
705+
migrating to the `UIScene` lifecycle, the launch options will be `nil`. Any logic
706+
performed here related to the launch options should be moved to the
707+
`scene:willConnectToSession:options:` event.
692708

693709
## Bespoke FlutterViewController usage
694710

0 commit comments

Comments
 (0)