Skip to content

Add UIScene lifecycle support (#6, #74)#77

Open
segidev wants to merge 1 commit into
bhagat-techind:mainfrom
segidev:add-uiscene-support
Open

Add UIScene lifecycle support (#6, #74)#77
segidev wants to merge 1 commit into
bhagat-techind:mainfrom
segidev:add-uiscene-support

Conversation

@segidev
Copy link
Copy Markdown

@segidev segidev commented May 11, 2026

Apple is requiring iOS apps to adopt the UISceneDelegate lifecycle, and Flutter 3.38+ makes it the default for new and migrated apps (see docs.flutter.dev/to/uiscene-migration). Once a host app turns on UIApplicationSceneManifest, the existing application(_:open:) / application(_:didFinishLaunchingWithOptions:) hooks in this plugin are no-ops — share URLs never reach the Dart side.

This PR teaches the plugin to participate in the new scene lifecycle.

What changed

  • SwiftFlutterSharingIntentPlugin now conforms to FlutterSceneLifeCycleDelegate and is registered via registrar.addSceneDelegate(instance) alongside the existing addApplicationDelegate(instance) call, so the plugin keeps working under both lifecycles.
  • New scene methods mirror the existing AppDelegate hooks:
    • scene(_:willConnectTo:options:) — captures the cold-launch share URL from connectionOptions.urlContexts / userActivities and primes initialSharing.
    • scene(_:openURLContexts:) — handles warm shares.
    • scene(_:continue:) — handles NSUserActivity continuations.
  • All three return Bool (true when the plugin consumed the URL) so FlutterSceneDelegate knows it doesn't need to forward the URL to the engine's deep-link channel.
  • pubspec.yaml: bumped minimum Flutter to >=3.38.0 and Dart SDK to >=3.10.0 (required for the FlutterSceneLifeCycleDelegate protocol).
  • CHANGELOG.md: new 2.1.0 entry.
  • README.md: short "UIScene lifecycle (Flutter 3.38+)" section under the iOS setup steps.

Closes

Migration notes for host apps

The plugin handles share URLs natively under UIScene — no extra wiring needed for that. However, when an app adopts UIScene:

  1. Plugin registration must move from application(_:didFinishLaunchingWithOptions:) into didInitializeImplicitFlutterEngine(_:) on a FlutterImplicitEngineDelegate-conforming AppDelegate. window.rootViewController is not available at didFinishLaunching time anymore.
  2. If you previously had a custom application(_:open:) override that called SwiftFlutterSharingIntentPlugin.instance.application(...), you can remove it — the new scene(_:openURLContexts:) does the equivalent.
  3. Apps with a custom Flutter router (GoRouter, Navigator 2.0, etc.) may still see share-scheme URLs reach the router on some engine versions; the README shows the one-line redirect filter that solves it.

Testing

  • Existing Dart tests still pass (flutter test — 4/4 green). No Dart API surface changed.
  • Manually verified on iPhone 17 (iOS 26.4.2) + Flutter 3.41.9:
    • Cold launch (app killed) — share PDF from Gmail / Files → app opens, getInitialSharing returns the file, share handler fires.
    • Warm share (app in background) — same flow via getMediaStream.
    • No regression on the legacy UIApplicationDelegate path (verified by leaving addApplicationDelegate in place).

No new native test target was added — UIScene, UISceneSession, and UIOpenURLContext cannot be constructed in XCTest, so the new scene callbacks are only manually verifiable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant