Redesign OnPlatform RRS feed

  • Question

  • User1004 posted


    The current OnPlaform implementation is not easily extendable if we don’t want it to become an API mess. Also, it is impossible for a 3rd party Platform creator to implement and use OnPlatform without having our approval.

    Important things to care about

    • We do not want to break API or ABI usage
    • TargetPlatform is used in Device.OnPlatfom(), in OnPlatform<T>, in xmlns definition

    Proposed change (first try): Fun with Flags

    • Deprecate Device.OnPlatform(). Our users are smart enough to write switch statement in code.
    • Change the TargetPlatform enum to be a [Flags]. That will allow one to write a statement for multiple platforms. We will achieve ABI stability by reserving the 3 first bits of the enum for legacy usage, and API stability by keeping the same names: ``` [Flags] public enum TargetPlatform { // 3 first bits reserved for legacy use iOS = 1<<3, Android = 1<<4, WinPhone = 1<<5, Windows = 1<<6,

      // 24 first bits reserved for future usage
      // use any number from 1<24 to 1<30 for your own platform
      Other = 1<<31,

      } ```

    • change the OnPlatform<T> xaml utility class so it supports the following syntax. The legacy properties will stay, but will be deprecated <OnPlatform x:TypeArguments=“x:String”> <On Platform=“iOS”>iOS</On> <On Platform=“Android|Windows”>androidOrWindows</On> <On Platform=“0x1000000”>myAwesomePlatform</On> </OnPlatform>
    • change both Xaml parser so they support enum values as ints, hexes or binary literals (c# 7, I’m ready) with or without _ as digit separator
    • change whatever is required to XamlNativeView keeps working


    Compiled code using if (Device.OS == TargetPlatform.iOS) won’t work anymore. Setting Device.OS to 1<<1 | iOS won’t fix it, because of the ==

    Discussion (with self)

    I can’t say how much I love this technical hack, and the fact that it uses [Flags], but the slight regression is a no go, as it’ll be a nightmare to debug.

    Proposed Change (second try): Magic Strings

    • Deprecate TargetPlatform and Device.OnPlatform (after reverting the Tizen addition). Suggest our users to use a switch statement on RuntimePlatform instead
    • Add a new string property to Device: something like RuntimePlatform
    • Add string consts for known platforms
    • in OnPlatform<T>, deprecate properties, allow this syntax: <OnPlatform x:TypeArguments=“x:String”> <On Platform=“iOS”>iOS</On> <On Platform=“Android>android</On> <On Platform=“3rdPartyPlat”>myAwesomePlatform</On> </OnPlatform>
    • change whatever is required to XamlNativeView keeps working

    We might want to make sure xaml intellisense suggest the right names for the Platform property, to avoid typos.

    Backward Compatibility Story

    • when setting RuntimePlatform to any known value, we will set Device.OS to the correct TagetPlatform value, and use TargetPlatform.Other in any other case.
    Thursday, December 15, 2016 9:12 AM

All replies

  • User352 posted

    Method 2 seems the most sane.

    Thursday, December 15, 2016 6:51 PM
  • User76916 posted

    As another option for the Flags idea. Since WinPhone is only used by Windows Silverlight, which is deprecated and Windows 8.1 RT and UWP are both using Windows. Why not just drop WinPhone.

    Then we have iOS = 1, Android = 2, Windows = 4

    Which means we could use flags.

    Since I think I might have been only 1 of very few people to ever use XF with Windows SL and WinRT. Even I don't use those platforms anymore, that should be saying something :)

    Thursday, December 15, 2016 11:16 PM
  • User352 posted

    The problem with moving to a flags enum is that we cant enable external parties to play nice with it. :/

    Thursday, December 15, 2016 11:31 PM
  • User28549 posted

    I like the idea of using the enum but as an Enumeration Class whereby the class can be extended beyond the capabilities of an enum, however... I'm not sure how it would work with [Flag]s.


    Tuesday, December 20, 2016 7:25 AM
  • User1004 posted

    We will go with strings. We can have the benefits of the [Flags] quite easily, both in code as the switch statement allows multiple case switch (platform) { case "iOS": case "Android": return "iOS or android"; break; }

    and in Xaml, as we could make the language support <OnPlatform x:TypeArguments=“x:String”> <On Platform=“iOS,Android”>iOS or Android</On> <On Platform=“3rdPartyPlat”>myAwesomePlatform</On> </OnPlatform>

    Tuesday, December 20, 2016 4:59 PM
  • User352 posted

    +1 for second try outlined in OP with modifications as specified by Stephane

    Tuesday, December 20, 2016 7:26 PM
  • User1004 posted

    see https://github.com/xamarin/Xamarin.Forms/pull/658

    Thursday, December 22, 2016 9:41 AM