Skip to content

Add Mac Catalyst TargetFrameworkIdentifier #44882

Closed

Description

@rolfbjarne

I'm implementing support for Mac Catalyst in Xamarin, and I've run into a question whether a new TFI should be created or not.

First a few facts:

  • Mac Catalyst is a blend of iOS and macOS (much more iOS than macOS though). We currently have two TFIs for these platforms, Xamarin.iOS and Xamarin.Mac respectively.
  • The API surface that we would bind in managed code in Mac Catalyst is not identical to neither Xamarin.iOS nor Xamarin.Mac: it would contain parts of Xamarin.iOS, parts of Xamarin.Mac, and potentially API that's in neither Xamarin.iOS nor Xamarin.Mac.
  • The native binaries (libmono, coreclr, etc.) have to be built specifically for Mac Catalyst. Binaries built for iOS or macOS won't work.

Adding a new TFI would have a few consequences:

  • We'd have to implement support for the new TFI to many other places. NuGet comes to mind, but I'm certain there are many other places I'm unaware of. We'd also have a new TFI for .NET 6 (for instance net6.0-catalyst).
  • Any existing NuGet for either Xamarin.iOS or Xamarin.Mac won't work.

Not adding a new TFI would also have a few consequences (say we re-use Xamarin.iOS):

  • It would not be possible to create a NuGet that uses any API in Mac Catalyst that isn't in Xamarin.iOS.

Design proposal dotnet/designs#174

Activity

  1. Dotnet-GitSync-Bot commented on Nov 18, 2020

    @Dotnet-GitSync-Bot
    Collaborator

    I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

  2. added and removed
    untriagedNew issue has not been triaged by the area owner
    on Nov 18, 2020
  3. added this to the 6.0.0 milestone on Nov 18, 2020
  4. marek-safar commented on Nov 18, 2020

    @marek-safar
    Contributor

    @terrajobst @ericstj @mhutch would you be in favour of adding a new TFM for this configuration

  5. Redth commented on Nov 18, 2020

    @Redth
    Member

    If we didn't add a new TFI, we could probably still reason about attempting to use API's with runtime exceptions.

    Given that Catalyst is much more similar to iOS, would we be able to swap out API binding references based on a project property? By default you get Xamarin.iOS.dll, but if you set <MacCatalyst>True</MacCatalyst>, we instead give you Xamarin.MacCatalyst.dll which has the superset of available API's? We could then use the existing API annotations on those bindings in roslyn analyzers to advise the user of things unavailable when building with -p:MacCatalyst=False. Then the iOS TFI could pivot based on that variable and build with the correct binding dll. We could also provide #define CATALYST based on the variable. The one disadvantage here is I'm not sure how nugets could provide anything but the MacCatalyst API superset of their assemblies to iOS/Catalyst developers. We could make the attribute available so they could proactively annotate their own API's around incompatibilities, but that feels sad.

    For NuGets, this would mean we can still consume existing assemblies targeting iOS, though I'm not sure if there's a great path to surfacing runtime errors if you try and call an API path in one of these existing assemblies that isn't implemented on Catalyst, beyond some unhandled exception lacking much context.

  6. rolfbjarne commented on Nov 19, 2020

    @rolfbjarne
    MemberAuthor

    Given that Catalyst is much more similar to iOS, would we be able to swap out API binding references based on a project property? By default you get Xamarin.iOS.dll, but if you set <MacCatalyst>True</MacCatalyst>, we instead give you Xamarin.MacCatalyst.dll which has the superset of available API's?

    Would that work with the IDEs and things like intellisense? Or would you get red squiggles whenever you tried to use a Catalyst only API?

  7. Redth commented on Nov 19, 2020

    @Redth
    Member

    Given that Catalyst is much more similar to iOS, would we be able to swap out API binding references based on a project property? By default you get Xamarin.iOS.dll, but if you set <MacCatalyst>True</MacCatalyst>, we instead give you Xamarin.MacCatalyst.dll which has the superset of available API's?

    Would that work with the IDEs and things like intellisense? Or would you get red squiggles whenever you tried to use a Catalyst only API?

    I think that is the intention, if you aren’t specifying catalyst, you don’t get the APIs to reference. Or are you thinking the IDE may not handle swapping references based on a property this way very well?

  8. rolfbjarne commented on Nov 19, 2020

    @rolfbjarne
    MemberAuthor

    Given that Catalyst is much more similar to iOS, would we be able to swap out API binding references based on a project property? By default you get Xamarin.iOS.dll, but if you set <MacCatalyst>True</MacCatalyst>, we instead give you Xamarin.MacCatalyst.dll which has the superset of available API's?

    Would that work with the IDEs and things like intellisense? Or would you get red squiggles whenever you tried to use a Catalyst only API?

    I think that is the intention, if you aren’t specifying catalyst, you don’t get the APIs to reference. Or are you thinking the IDE may not handle swapping references based on a property this way very well?

    It's the second part: I wonder if the IDE will handle the reference swap correctly.

  9. marek-safar commented on Nov 19, 2020

    @marek-safar
    Contributor

    What about the following? We keep an only a single version of APIs, we could keep calling it Xamarin.iOS. We annotate all APIs which are not available on the Catalyst with [UnsupportedOSPlatformAttribute ("osx")] attribute and rely on existing platform compatibility analyzer to take care of flagging the unavailable APIs to the developers.

  10. rolfbjarne commented on Nov 19, 2020

    @rolfbjarne
    MemberAuthor

    What about the following? We keep an only a single version of APIs, we could keep calling it Xamarin.iOS. We annotate all APIs which are not available on the Catalyst with [UnsupportedOSPlatformAttribute ("osx")] attribute and and rely on existing platform compatibility analyzer to take care of flagging the unavailable APIs to the developers.

    That could work.

    We'd also have to add all the macOS API (AppKit) that are available in Catalyst but not in iOS, and mark those with [UnsupportedOSPlatformAttribute ("iOS")].

    and rely on existing platform compatibility analyzer

    I assume there's a way to tell the platform compatibility analyzer which platform we're building for outside of the TFM?

  11. am11 commented on Nov 19, 2020

    @am11
    Member

    fwiw, currently the granularity chosen for shipping artifacts is 'package', such that, there is no concept of 'very similar' when it comes to a consumable package; slightly different is just another package. it has some benefit at the cost of a slightly scaled bandwidth usage (which is not an issue in this day and age). e.g. in .net 5, the difference between dotnet-sdk-linux-x64.tar.gz (linux glibc x64) and dotnet-sdk-linux-musl-x64.tar.gz (linux musl-libc x64) is about 13 binary files; out of total of 3100+ files, yet they are kept separate as it is easy to tag and reason about, imo (and it goes hand in hand with tfm mappings on engineering side of the house).

  12. filipnavara commented on Nov 19, 2020

    @filipnavara
    Member

    If you keep a single TFM how would I actually multi-target an app for both iOS and macOS in a single build?

  13. mhutch commented on Nov 19, 2020

    @mhutch
    Contributor

    @terrajobst @richlander

    My initial feeling is that we need a new TFM. But catalyst doesn't seem particularly descriptive and may end up seeming out of date in a few years. Maybe we should use net6.0-mac-catalyst? Or given we haven't shipped net6.0-mac yet, maybe we should use that for Catalyst and use net6.0-mac-cocoa for Xamarin.Mac?

  14. 52 remaining items

  15. Redth commented on Dec 3, 2020

    @Redth
    Member

    @coolbluewater sorry, let me be more clear, and then let's try to keep this issue related to the original intent of the conversation, which is, do we need another TFM or RID or ? for .NET 6 support of Catalyst.

    First of all, I wanted to be sure it was clear there is no Xamarin support coming to .NET 5 whatsoever. We will of course continue to support Xamarin.iOS, Xamarin.Mac, and Xamarin.Android using the existing mono based runtime and BCL in the interim. Originally it was planned for Xamarin to support .NET 5 but due to various external and internal factors it was decided and communicated some time ago to wait for .NET 6.

    As for Catalyst, we know there is a desire for it to be supported. I have been eager to be able to use Catalyst myself since it was announced. I've also been a very big advocate (aka real big pain!) for its support internally and have been working hard to see it happen, as I believe it makes a LOT of sense to use this as our approach for Xamarin.Forms to be supported on macOS going forward.

    @rolfbjarne has been working on adding support for Catalyst via the existing mono runtime and BCL which allows us to work on it in parallel to things needed in .NET6 for the effort (like this TFM/RID decision), however at this time we are not committing to making Catalyst a fully supported feature of the product until .NET 6. I don't see a reason why we wouldn't continue to release the work Rolf is doing for it as is, and perhaps even gate it as a preview or experimental feature so that anyone who cares to try it is welcome to, and may very well be successful with it, but fully supporting the scenario is another conversation with other implications. This may or may not change in the future.

  16. coolbluewater commented on Dec 3, 2020

    @coolbluewater

    @Redth, first off could you please describe your role?

    Edit: Ah, I see - I was using the term .net 5 generically to include everything pre-.net 6, while you are referring specifically to the non-mono implementation. A case of too many .nets. Does that help clarify what I meant?

  17. filipnavara commented on Dec 3, 2020

    @filipnavara
    Member

    .Net 5 is already released, and Xamarin runs atop it. So whatever you are saying needs to be more descriptive.

    No, it does not. At least not Xamarin.iOS/Mac/Android.

  18. coolbluewater commented on Dec 3, 2020

    @coolbluewater

    @filipnavara, see my edit above.

  19. Redth commented on Dec 3, 2020

    @Redth
    Member

    @coolbluewater I'm the engineering lead/manager of the Xamarin.Forms team (Maui, Essentials, SkiaSharp, and others). I'm also coordinating the Xamarin SDK effort for .NET 6 support. I'm also not a product manager. @davidortinau would be a good person to comment further on any Catalyst support pre .NET 6.

    So, yes I think using .NET 5 to indicate pre-.NET 6 is confusing especially in the context of Xamarin.

    Again, at this point there's no real commitment to release Catalyst support before .NET 6 as a supported feature. But of course since it's being worked on in the open, on top of the mono based Xamarin runtime/BCL, it may be usable with the disclaimer of "as-is".

  20. coolbluewater commented on Dec 3, 2020

    @coolbluewater

    @Redth, I understand your role now.

    Again, at this point there's no real commitment to release Catalyst support before .NET 6 as a supported feature.

    That's no more useful than your previous one-liner. And this really is the right place and time to discuss why engineering was unable (or chose not to) to deliver a Mac Catalyst implementation, and more importantly why it will take another whole year to have something usable.

    If you don't wish to discuss this that's your choice. But you've said nothing about the issues raised regarding the response to dotnet/macios#6210.

    What's being discussed here is completely on-topic, and is the context of the particular issue. Is quibbling about where the discussion occurs really more important to you than to just engage with this discussion as-is?

    Also - the build system for building Xamarin.iOS apps at this point is in fact .net 5, correct? That's what I was referred to when I stated this:

    Edit: the above assumes that the .net 6 multi-targetting build system will be a long time coming. On the other hand if it is already in good shape and can be made available to .net 5 in the near term, then of course that is the way to go.

    So I think that was the right terminology after all. What you're saying is a categorical "no" to having a dot release that includes what might be needed in the build system for Xamarin to support Mac Catalyst. But you haven't explained why.

    Microsoft (and now Xamarin) have made the mistake time and again of these gigantic releases that everyone has to wait for and that slip with near certainty. .net 5 => .net 6 was a case in point. (And please don't bring up the pandemic, Apple had its most innovative year in this period. Just anticipating your response; I am not given to sarcasm.)

    It seems to me that the build system ought to be a small, tight component that can ship on a dime, and that in itself needs only the most basic features of the runtime. If this isn't the case it seems that a high tech debt has built up that is crippling the rate at which you can move forward.

  21. filipnavara commented on Dec 3, 2020

    @filipnavara
    Member

    Also - the build system for building Xamarin.iOS apps at this point is in fact .net 5, correct?

    Nope. Not at all. It is the Mono desktop MSBuild based system that is totally unrelated to the .NET 5 code base.

    What you're saying is a categorical "no" to having a dot release that includes what might be needed in the build system for Xamarin to support Mac Catalyst.

    I am reading it differently. It could very much be shipped as part of classic (non-.NET 6) Xamarin packages as a preview feature.

  22. gdignard commented on Dec 3, 2020

    @gdignard

    I would point out obvious that there's a very real value of having a feature like this appear as early as possible, even with disclaimers of "preview" / "as-is" / " WARNING: Operating this software can expose you to unimplemented features which are known to the State of California to cause machine crashes."

    Having it in a non-publishable state is still of enormous value as the development process can begin even if things aren't stable. As was noted, as part of the .NET 6 release, it puts Xamarin developers at a 30 month disadvantage. Having access to Catalyst sooner than that would at least put us in a position of having software ready to go when there's a GM rather than having the race start then for us.

    I'm very happy to see the work underway and for the traction it's finally starting to receive.

  23. changed the title [-]Add Mac Catalyst TargetFrameworkIdentifier or Runtime Identifier[/-] [+]Add Mac Catalyst TargetFrameworkIdentifier[/+] on Jan 27, 2021
  24. marek-safar commented on Feb 25, 2021

    @marek-safar
    Contributor

    Closing as the design was finalized in dotnet/designs#174

  25. ghost locked as resolved and limited conversation to collaborators on Mar 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions