Skip to content

feat: Add UIScene life cycle support#405

Open
csbence10 wants to merge 1 commit into
ABausG:mainfrom
csbence10:main
Open

feat: Add UIScene life cycle support#405
csbence10 wants to merge 1 commit into
ABausG:mainfrom
csbence10:main

Conversation

@csbence10
Copy link
Copy Markdown

feat: add UIScene support for widget launch URLs on iOS

Description

Adds iOS 13+ UIScene lifecycle support so that widget launch URLs are handled when the app uses a scene-based lifecycle (e.g. default Flutter iOS template with SceneDelegate).

Existing behavior: Widget taps were delivered only via UIApplicationDelegate (application(_:didFinishLaunchingWithOptions:) and application(_:open:options:)). Apps that rely on UISceneDelegate for URL handling did not receive these URLs.

Changes:

  • HomeWidgetPlugin+SceneDelegate.swift: Implement FlutterSceneLifeCycleDelegate with scene(_:willConnectToSession:options:) (initial launch URL from connectionOptions.urlContexts) and scene(_:openURLContexts:) (URL when app is already running). This mirrors the existing AppDelegate URL handling so initiallyLaunchedFromHomeWidget and the updates stream work for scene-based apps.
  • HomeWidgetPlugin.swift: Register the plugin as a scene delegate via addSceneDelegate: on the registrar (using the same runtime responds(to:) / perform pattern as addApplicationDelegate: for backward compatibility). Only registers on iOS 13+ and when the registrar supports it. isWidgetUrl(url:) is made internal so the scene delegate extension can reuse it.

No Dart API changes. AppDelegate-based apps continue to work unchanged.

Checklist

  • I have updated/added tests for ALL new/updated/fixed functionality.
  • I have updated/added relevant documentation and added code (documentation) comments where necessary.
  • I have updated/added relevant examples in example or documentation.

Breaking Change?

  • Yes, this PR is a breaking change.
  • No, this PR is not a breaking change.

Related Issues

#399

@docs-page
Copy link
Copy Markdown

docs-page Bot commented Mar 7, 2026

To view this pull requests documentation preview, visit the following URL:

docs.page/abausg/home_widget~405

Documentation is deployed and generated using docs.page.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 7, 2026

Walkthrough

This change adds iOS 13+ scene lifecycle support to HomeWidgetPlugin by implementing the FlutterSceneLifeCycleDelegate protocol through a new extension. It handles scene connection and URL context events to detect and track widget URLs.

Changes

Cohort / File(s) Summary
Scene Lifecycle Delegate
packages/home_widget/ios/home_widget/Sources/home_widget/HomeWidgetPlugin+SceneDelegate.swift
New extension implementing two scene delegate methods: scene(_:willConnectTo:options:) to detect widget URLs on app launch and scene(_:openURLContexts:) to handle subsequent widget URL events. Both methods iterate through URL contexts to identify and store widget URLs.
Plugin Base Implementation
packages/home_widget/ios/home_widget/Sources/home_widget/HomeWidgetPlugin.swift
Increased visibility of initialUrl and latestUrl properties from private to internal, and made isWidgetUrl() method internal to support the new scene delegate extension. Added conditional scene delegate registration during plugin initialization for iOS 13+.

Sequence Diagram(s)

sequenceDiagram
    participant iOS as iOS System
    participant Scene as Scene Delegate
    participant Plugin as HomeWidgetPlugin
    participant State as Plugin State

    iOS->>Scene: App launches/scene connects
    Scene->>Plugin: scene(_:willConnectTo:options:)
    Plugin->>Plugin: Check connectionOptions.urlContexts
    Plugin->>Plugin: Detect widget URLs via isWidgetUrl()
    Plugin->>State: Set initialUrl & latestUrl from first match
    Plugin-->>Scene: Return Bool result

    iOS->>Scene: User opens widget URL
    Scene->>Plugin: scene(_:openURLContexts:)
    Plugin->>Plugin: Iterate URLContexts
    Plugin->>Plugin: Check if widget URL via isWidgetUrl()
    Plugin->>State: Update latestUrl on match
    Plugin-->>Scene: Return Bool result
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related issues

  • Add UIScene life cycle support #399: Directly addresses the requested "Add UIScene life cycle support" feature by implementing scene delegate methods for handling widget URLs on iOS 13+.
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: Add UIScene life cycle support' is clear and concise, accurately capturing the main change of adding iOS UIScene lifecycle support.
Description check ✅ Passed The description provides comprehensive details on existing behavior, the motivation for changes, implementation details for both files, and confirms no breaking changes or Dart API changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@csbence10 csbence10 changed the title Add UIScene life cycle support feat: Add UIScene life cycle support Mar 7, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/home_widget/ios/home_widget/Sources/home_widget/HomeWidgetPlugin+SceneDelegate.swift (1)

11-21: Consider whether returning false is the intended behavior.

The method always returns false (line 21), even when a widget URL is successfully handled. The parallel application(_:didFinishLaunchingWithOptions:) returns true. While the return value semantics may differ between these delegate protocols, confirm this is intentional for FlutterSceneLifeCycleDelegate.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/home_widget/ios/home_widget/Sources/home_widget/HomeWidgetPlugin`+SceneDelegate.swift
around lines 11 - 21, The method currently always returns false even when a
widget URL is handled; update the return to reflect whether a widget URL was
found and handled: iterate connectionOptions?.urlContexts as you do, set
initialUrl and latestUrl when isWidgetUrl(url:) matches, and then return true
after handling (or return a boolean flag like handled that is true when you
break on a widget URL and false otherwise) so the method's Bool return
communicates that the scene handled a widget URL.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@packages/home_widget/ios/home_widget/Sources/home_widget/HomeWidgetPlugin`+SceneDelegate.swift:
- Around line 11-21: The method currently always returns false even when a
widget URL is handled; update the return to reflect whether a widget URL was
found and handled: iterate connectionOptions?.urlContexts as you do, set
initialUrl and latestUrl when isWidgetUrl(url:) matches, and then return true
after handling (or return a boolean flag like handled that is true when you
break on a widget URL and false otherwise) so the method's Bool return
communicates that the scene handled a widget URL.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 682a3b55-a608-4bb0-9b20-b6d0d089292c

📥 Commits

Reviewing files that changed from the base of the PR and between fa7453a and cce4168.

📒 Files selected for processing (2)
  • packages/home_widget/ios/home_widget/Sources/home_widget/HomeWidgetPlugin+SceneDelegate.swift
  • packages/home_widget/ios/home_widget/Sources/home_widget/HomeWidgetPlugin.swift

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (fa7453a) to head (cce4168).

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #405   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            3         3           
  Lines          115       115           
=========================================
  Hits           115       115           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Owner

@ABausG ABausG left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good thanks! Just the nit comment as well as the formatting issue!

if isWidgetUrl(url: url) {
initialUrl = url
latestUrl = url
break
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See nitpicker comment from CodeRabbit:
#405 (review)

not sure if it would be sensible to return true here to match the previous logic as well as the other function

@nafiskabbo
Copy link
Copy Markdown

Please approve this pr as it's affecting the Appstore new releases

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.

3 participants