Home > database >  How to easily share code between iOS and Mac Catalyst in .net 6?
How to easily share code between iOS and Mac Catalyst in .net 6?

Time:05-04

I'm in the process of upgrading a Xamarin Native solution to run on .net 6 using SDK style multi-targetted projects.

As I understand it, there are two ways of writing platform-dependent code: a) Code inside the appropriate platform directory (e.g. "iOS" or "MacCatalyst") is always compiled conditionally for that platform. b) Code can be explicitly conditionally compiled via e.g., #if IOS.

Neither of these seems ideal when there is a large body of code that is shared between two platforms. In (a) the code is duplicated and in (b) the code is strewn with #ifs.

Is there a better way to share code between these two platforms?

CodePudding user response:

I'm considering creating a "Shared" folder under Platforms/iOS and symlinking that folder to Platforms/MacCatalyst/Shared.

Still holding out for other answers, as well as comments on this one.

EDIT: I tried this on Visual Studio For Mac 2022. The symlinked folder at Platforms/MacCatalyst/Shared appears as a single file with a reddish title in Solution Explorer, i.e., its subtree isn't visible. However, the project complies fine for both iOS and Mac Catalyst. Since the shared code is accessible from its original location at Platforms/iOS/Shared, this looks like valid albeit somewhat unsupported strategy.

CodePudding user response:

The situation is that MacCatalyst uses the same API as iOS?

If so, I would place such a file under the cross-platform folder, and wrap the entire contents in

#if iOS || MacCatalyst
...
#endif

That's still #if's, but it's cleaner than having code "strewn with #ifs".

Another way to keep the code "clean", is to use partial class.

If only some of the code in a class makes iOS calls, you could choose to split methods that make such calls into a separate file - but with the same class name.
File that has no iOS dependencies:

public partial class MyClass
...

File that has iOS dependencies (in the same MyClass):

#if iOS || MacCatalyst
public partial class MyClass
...
#endif

Of course the same technique can be used for code that is ONLY needed on one or the other platform.

This makes it possible to include platform-specific implementation details in the same class as the common code. Yet keep the #ifs manageable.


I recommend developing a standard naming convention for the files.

I name the cross-platform file MyClass.cs.
I name an iOS-only partial class file MyClass.iOS.cs. I haven't done mac stuff, but if I did, the iOS Mac class I would name something like MyClass.iOSMac.cs.

  • Related