You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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.
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?
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?
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.
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.
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?
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).
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?
@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.
@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?
@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".
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.
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.
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.
changed the title [-]Add Mac Catalyst TargetFrameworkIdentifier or Runtime Identifier[/-][+]Add Mac Catalyst TargetFrameworkIdentifier[/+]on Jan 27, 2021
Activity
Dotnet-GitSync-Bot commentedon Nov 18, 2020
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.
marek-safar commentedon Nov 18, 2020
@terrajobst @ericstj @mhutch would you be in favour of adding a new TFM for this configuration
Redth commentedon Nov 18, 2020
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 CATALYSTbased 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.
rolfbjarne commentedon Nov 19, 2020
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?
Redth commentedon Nov 19, 2020
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?
rolfbjarne commentedon Nov 19, 2020
It's the second part: I wonder if the IDE will handle the reference swap correctly.
marek-safar commentedon Nov 19, 2020
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.rolfbjarne commentedon Nov 19, 2020
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")].I assume there's a way to tell the platform compatibility analyzer which platform we're building for outside of the TFM?
am11 commentedon Nov 19, 2020
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) anddotnet-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).filipnavara commentedon Nov 19, 2020
If you keep a single TFM how would I actually multi-target an app for both iOS and macOS in a single build?
mhutch commentedon Nov 19, 2020
@terrajobst @richlander
My initial feeling is that we need a new TFM. But
catalystdoesn't seem particularly descriptive and may end up seeming out of date in a few years. Maybe we should usenet6.0-mac-catalyst? Or given we haven't shippednet6.0-macyet, maybe we should use that for Catalyst and usenet6.0-mac-cocoafor Xamarin.Mac?52 remaining items
Redth commentedon Dec 3, 2020
@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.
coolbluewater commentedon Dec 3, 2020
@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?
filipnavara commentedon Dec 3, 2020
No, it does not. At least not Xamarin.iOS/Mac/Android.
coolbluewater commentedon Dec 3, 2020
@filipnavara, see my edit above.
Redth commentedon Dec 3, 2020
@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".
coolbluewater commentedon Dec 3, 2020
@Redth, I understand your role now.
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:
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.
filipnavara commentedon Dec 3, 2020
Nope. Not at all. It is the Mono desktop MSBuild based system that is totally unrelated to the .NET 5 code base.
I am reading it differently. It could very much be shipped as part of classic (non-.NET 6) Xamarin packages as a preview feature.
gdignard commentedon Dec 3, 2020
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.
Add very early support for Mac Catalyst. (#10199)
[-]Add Mac Catalyst TargetFrameworkIdentifier or Runtime Identifier[/-][+]Add Mac Catalyst TargetFrameworkIdentifier[/+]marek-safar commentedon Feb 25, 2021
Closing as the design was finalized in dotnet/designs#174