question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Handler deprecation/versioning strategy

See original GitHub issue

Description

A number of scenarios can occur that require us to move to new handlers. There are cases where the platform owners (iOS/Android/WinUI) will introduce new controls that users want to use. Sometimes we are forced to migrate to these new controls in order for Apple to continue letting users publish to the store. For example, in Xamarin.Forms we had to remove all references to UIWebView and recently we modified all of our Android input fields to inherit from a specific base class otherwise Android would stop lettings us published to the store. We try not to break users in unexpected and undesirable ways but in order for the platform to evolve and for apps to continue functioning we have to deprecate and sometimes remove.

General strategy

The current plan will be to follow a similar pattern as windows and just append an incrementing number to new handlers. If we migrate one platform to Handler2 we will create a Handler2 version on all platforms. The Handler and Handler2 for the untouched platforms will retain the same behavior as one another. Example can be seen here.

If we were to only migrate the Windows handler to Handler2 that would make the xplat APIs confusing


#if WINDOWS
     SwipeViewHandler2.Mapper
#else     
     SwipeViewHandler.Mapper
#endif

vs

     SwipeViewHandler2.Mapper

How do I opt in for these new handlers?

By default, users will need to opt-in to the new handlers. The mechanisms around this still need to be discussed, but it will almost definitely be some sort of builder extension method.

builder.UseMaui<App>()
           .UseLatestFeatures()

We can possibly break this out to specific handlers as well for discovery purposes. This also lets us document the extension method itself to indicate what opting into this handler includes.

builder.UseMaui<App>()
           .UseButtonHandler2()

Users can also manually opt into the new handlers through handler registration

builder.UseMaui<App>()
           .ConfigureMauiHandlers(handlers =>
           {
                      handlers.AddHandler<SwipeView, SwipeViewHandler2>
           });

If users only want to opt into the new handler on a single platform they can. If they have a lot of code written against SwipeViewHandler.Mapper on Android and only care about updating Windows. Or maybe we’ve changed SwipeViewHandler on two platforms but they only want to opt into the Windows one.

builder.UseMaui<App>()
#if WINDOWS
           .UseButtonHandler2()
#endif

or

builder.UseMaui<App>()
           .ConfigureMauiHandlers(handlers =>
           {
#if WINDOWS
                      handlers.AddHandler<SwipeView, SwipeViewHandler2>
#endif
           });

Additional Notes

  • New handlers will not inherit from the previous handlers. There should be nothing that connects the two handlers together. Each handler should be able to exist independently of each other.
  • Handler interfaces will not implement previous versions
    • With windows, numbered interfaces are used to add behavior, but for this scenario we are implementing a completely new handler. ISwipeViewHandler and ISwipeViewHandler2 will have no overlap. We need to be able to delete ISwipeViewHandler without breaking ISwipeViewHandler2

Alternate suggestion to Handler<Num>

Associate handlers with the .NET release they were implemented in. This gives a bit of clarity to where the handlers came into existence but could also lead to a number of confusions

Cons:

  • We may have issues figuring out what handlers are actually being used as technically any library can request v1 or v2 at any point during the setup.
  • If we have a net8 namespace, people may not think that net8 works in net9 or expect all versions of handlers to have a related namespace.
  • There may be code ambiguity as depending on who/what adds a namespace the type is the same yet is actually different - further aggravated with the VS IDE adding random namespaces in a copy-paste.

Obsoleting Handlers

These scenarios will be a bit case by case.

Platform forces us to deprecate delete

There are some cases where the platform (iOS, Android) forces our hand, and we have to delete/break code based on the requirements of those platforms.

Platform offers a new control

As the platforms themselves evolve new types of controls are created for existing UI concepts (i.e. datepickers, timepickers, entries, etc…). In order for us to stay current we need to provide users with the most modern experience. The timeline of deprecating/deleting older handlers here will depend on the requirements of the platform. If enough time has passed and the old version of a DatePicker is no longer recommended or used by Apple then we will stop actively maintaining and remove the Handler

We’ve implemented what we feel is a better version then what the platform offers

These cases will most likely be pretty rare as it’s a lot of work to maintain custom built controls. One scenario that’s currently active is the SwipeView control https://github.com/dotnet/maui/pull/11229. We have a custom implementation that enables mouse interactions. If we pull this PR in, we will most likely need to maintain both handlers for some time until we can confidently say that the new implementation is a 100 percent accurate stand in for the obsolete handler. There is a decent change that when this happens, we will be maintaining both handlers for a number of years.

Will you ever delete handlers?

If we’ve deemed that users need to move all new code to a new handler, then we will obsolete the old handler for a major release cycle to allow time to migrate and then remove the handler.

Current optimism indicates that we will move any obsolete handlers to Compatibility unless it’s a scenario where the platform is no longer compatible with that Handler. For example, on Android you’re required to implement AppCompatEditText so if we had any handlers that weren’t using AppCompatEditText we would just delete these because our hand is forced by Google.

Examples

Currently we have a PR to implement a new SwipeViewHandler https://github.com/dotnet/maui/pull/11229 that is custom built and enables more features than the WinUI SwipeView. Once/if the new handler reaches 100 percent feature parity with SwipeViewHandler then we can obsolete SwipeViewHandler

Issue Analytics

  • State:open
  • Created 6 months ago
  • Comments:10 (1 by maintainers)

github_iconTop GitHub Comments

3reactions
Dreamescapercommented, May 15, 2023

You probably need to think how to be able to “freeze” handler versions during the project creation. I.e. when I create a project, the latest recommended handlers should be used (not simply a V1). But when a new handler version is released, previously created project shouldn’t migrate there automatically (therefore you can’t simply use UseLatestFeatures in the project template).

3reactions
juwenscommented, May 16, 2023

Just imagine, what amount of effort could be saved for the Maui team, and also for developers using MAUI, if they switch to drawn controls. Not constantly needing to adjust to changed platform controls or incomplete/buggy handlers. Simply continuously improving/enhancing existing controls. If only there would be a person at MSFT who peruses this goal and created a prototype.

Details

https://github.com/dotnet/Microsoft.Maui.Graphics.Controls

Read more comments on GitHub >

github_iconTop Results From Across the Web

java - What do I use now that Handler() is deprecated?
The deprecated function is that constructor for Handler. Use Handler(Looper.myLooper()) .postDelayed(runnable, delay) instead.
Read more >
How to Smartly Sunset and Deprecate APIs
This usually means that a new version has been created, or the underlying business supporting the API is no longer intending on supporting...
Read more >
kataras/versioning: :new: API Versioning for Go
Just call the Group#Deprecated(versioning.DeprecationOptions) on the group you want to notify your API consumers that this specific version is deprecated.
Read more >
Handler | Android Developers
This constructor is deprecated. Implicitly choosing a Looper during Handler construction can lead to bugs where operations are silently lost (if the Handler...
Read more >
How to Manage API Version Deprecation Effectively
In this article, we'll explore some best practices and tips for managing API version deprecation in a user-friendly and transparent way.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found