Avalonia should support iOS Background App Refresh
Is your feature request related to a problem? Please describe.
Currently, Avalonia stable does not fully support Background App Refresh on iOS. This issue is twofold:
- There is no Avalonia API for Background App Refresh.
- The current Avalonia.iOS implementation does not properly handle background app launch as described in official Apple documentation.
Describe the solution you'd like
A proper implementation of Avalonia support for iOS Background App Refresh would tick the following boxes:
- Avalonia API is extended to hide low level implementation details for background app launch.
- iOS Metal backend follows Apple Developer guidelines for apps moving to the background.
AvaloniaAppDelegate<TApp>class is modified to reflect nuance of foreground vs. background application invocations.
Describe alternatives you've considered
I've tried to just use the iOS Background App Refresh APIs directly via Xamarin.iOS, but this doesn't work properly due to the reasons outlined above. Direct support at the library level is necessary for a complete implementation of this common iOS app feature.
Additional context
I'm looking to implement this feature myself. I opened this issue in hopes of discussing the new API(s) with the core team and reaching some kind of consensus before diving in 😁
Specifically background/foreground events are accessible from Avalonia via https://docs.avaloniaui.net/docs/concepts/services/activatable-lifetime#handling-app-entering-and-exiting-background-state
Implemented via these notifications https://github.com/AvaloniaUI/Avalonia/blob/513d1d96ecdcb121b160b81d412e4ea785c3daae/src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs#L21-L22
@maxkatz6 Yes, I'm aware of the existing APIs for observing application transitions between the foreground and the background. However, they are incomplete. Specifically, when an app using Background App Refresh is launched by iOS directly into the background, it uses didFinishLaunchingWithOptions just like it does for a user-initiated foreground invocation. To directly quote Apple documentation on the subject:
If your app isn’t running when an event arrives, the system launches the app and moves it directly to the background, following this sequence:
- The system launches the app and follows the initialization sequence described in About the app launch sequence.
- UIKit calls the app delegate’s applicationDidEnterBackground: method. ...
This is problematic because the way Avalonia currently handles application launch, the Metal backend is erroneously initialized during background fetch, which then causes rendering issues once the app transitions into the foreground. A correct implementation would decouple initialization of the Metal backend from application launch, and instead depend on foreground transition notifications to know when we can safely bootstrap the renderer.
In my opinion this would also include exposing this nuance through virtual methods in the AvaloniaAppDelegate<TApp> base class so that savvy developers can override this functionality when necessary.
Let me know your thoughts!