Skip to content

Expose iOS UIApplicationDelegate lifecycle notifications as overridable hooks - #4870

Open
Gise23 wants to merge 2 commits into
beeware:mainfrom
Gise23:4478-ios-lifecycle-hooks
Open

Gise23 wants to merge 2 commits into
beeware:mainfrom
Gise23:4478-ios-lifecycle-hooks

Conversation

@Gise23

@Gise23 Gise23 commented Nov 7, 2026 •

Copy link
Copy Markdown

On iOS, the app and scene delegates handled native lifecycle events directly, so there was no way for an app to override and add its own behavior to them. The changes follow the approach implemented for macOS in #4599: each UIApplicationDelegate lifecycle method forwards to a uikit_-prefixed method on the toga_iOS App class, which can now be overridden by subclassing it and returning it from toga.App.create().

  • The existing launch logic was moved into uikit_application_didFinishLaunchingWithOptions unchanged, and the print() calls in the app delegate were removed.
  • New no-op hooks were added for the other non-deprecated app-level notifications iOS delivers under the scene lifecycle (will finish launching, memory warning, significant time change, protected data, and terminate).
  • Multi-argument selectors follow the same naming rule, e.g. uikit_application_didFinishLaunchingWithOptions.
  • Hooks that can't be triggered in the testbed are marked # pragma: no cover; no new tests were added.
  • Documented in the iOS platform reference page.

Tested on the iOS 27.2 simulator (iPhone Duo): full testbed suite passes with 100% iOS backend coverage. Four layout tests (test_activityindicator::test_stop_no_shift, test_base::test_visibility, test_display, test_parenting) fail because widgets are placed 24 points lower than the tests expect. They also fail on main, so they're unrelated to this change.

Refs #4478

PR Checklist:

  • I will abide by the BeeWare Code of Conduct
  • I have read and have followed the CONTRIBUTING.md file
  • This PR was generated or assisted using an AI tool

Assisted-by: Claude Opus 5.5

@freakboy3742 freakboy3742 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the PR; the general structure of this is definitely on the right track.

I've left one comment inline about testing; while I understand why you've added them, I suspect that we don't need any of the tests you've added here.

The other detail that needs a tweak is related to the split between Application and Scene notifications. You might notice that all the Scene events are effectively invoked on current_window... which leads to a bigger architectural question: should the details about the Scene lifecycle be tied to the Window that created them?

This came up when we added support for UISceneDelegate. Historically, we've said that iOS apps can only ever have one window; however, on iPads and the new iPhone Duo, you can have multiple windows in an app - each of which is a Scene. If a Scene and a Window are closely bound, then UISceneDelegate events should be attached to the Toga iOS Window implementation, not the App implementation.

However, that's a much bigger design decision. In the interest of constraining the scope of this PR, I'd suggest leave the SceneDelegate unchanged, and stick to just the non-deprecated UIApplicationDelegate methods.

We also don't need to get the full UIApplicationDelegate interface in this pass - there's a lot of methods there (including methods for WatchKit and Siri integration); we can treat those as future additions if someone wants them.

Comment thread testbed/tests/app/test_mobile.py Resolved
Revert the UISceneDelegate changes.Remove the delegate-invocation tests and mark the hooks that can't be triggered in the testbed as no cover.
@Gise23 Gise23 changed the title Expose iOS app and scene lifecycle notifications as overridable hooks Expose iOS UIApplicationDelegate lifecycle notifications as overridable hooks Nov 11, 2026
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.

2 participants