Setting up your Mac for .NET MAUI in 2023

Sahu
7 min readJun 11, 2023
Photo by Turag Photography on Unsplash

Introduction

MAUI, short for Multi platform Application User Interface, is the evolution and simplificiation of a multitude of solutions which were previously used to create cross platform mobile and desktop applications with .NET (few of those being the various targets of Xamarin like Xamarin.Forms, Xamarin.Android, Xamarin.iOS; Windows UWP, Windows Presentation Foundation, Tizen.NET, etc.)

You’ll find all the details here — https://learn.microsoft.com/en-us/dotnet/maui/what-is-maui. I don’t see a reason to explain everything in this post, but the gist being it’s a more modern and simplified experience but still familiar to the seasoned C#/Xamarin developers.

The Setup

There are two clear paths that atleast I see, in terms of the setup and I have a clear preference. But I’ll talk about both of them.

Note: I have an Intel based Mac so things might be different compared to an M1 based machine. I’m still trying to upgrade, and when I do, I’ll write another article covering the differences.

The Visual Studio way

If you’re coming with a Xamarin/UWP/WPF background, most likely you’d want to use Visual Studio for Mac to get things going. The setup is quite straight forward, you just install VS for Mac and tick the check boxes saying you want .NET and .NET MAUI to be setup.

More details here — https://learn.microsoft.com/en-us/dotnet/maui/get-started/installation?tabs=vsmac

The non — Visual Studio way

If you’re starting out new or just prefer using Visual Studio Code for your general coding workflow, chances are you’d want to continue using that for developing those cross platform apps. And, yes, you can. I have done both; I enjoy Visual Studio, Visual Studio for Mac, but I also enjoy using Visual Studio Code for coding in JavaScript, TypeScript and any other coding related task, really.

I honestly prefer it this way as I learnt a lot, just trying to set it up, but you may be looking for a straight forward setup, I understand.

Okay, let’s get to it.

1. Install pre-requisites

If you are someone who wants this level of control, I assume you use a software package manager to install things. I use brew for setting everything up. So install brew. Checkout brew.sh for this.

2. Install Visual Studio Code (Duh)

You might have it installed already, if not, this can be done with a cask as well.

$ brew install --cask visual-studio-code

3. Install .NET SDK

Even though .NET 6 is in LTS right now, I suggest you install both .NET 7 and .NET 6. This will be helpful for something I’ll discuss later in this article.

I use my https://github.com/cli-config/cli-config project to set it up, but feel free to set it up however you wish. dotnet is available as a cask in homebrew but I’ve never set it up that way.

4. Install the MAUI workload

I learnt about .NET cli workloads from an article I found when I originally started setting up MAUI on my Mac. That article seems to have fallen off of the face of the Earth, can’t find it anymore (will link it if I find it again)

$ dotnet workload install maui

You’ll also need the Project Templates for .NET MAUI, so you can do dotnet new maui.

$ dotnet new install Microsoft.Maui.Templates::6.0.312

At this point, you have most of the things to at least write a .NET MAUI app, albeit you won’t be able to run it. 😂 Create a new .NET MAUI app with the following command -

$ dotnet new maui -n maui-hello-world

Depending on what platform you want to run your app on, you’ll need parts of the following -

5.1. Targeting iOS/mac?

You’ll need to install XCode. I already had XCode installed, but maybe mac should work without it. Go to the App Store and download the latest version of XCode. You DON’T need an Apple Developer Account.

To run your app on mac, use the following command

$ dotnet build -t:Run -f net7.0-maccatalyst
Running the .NET MAUI App on macOS

For iOS — iPhones and iPads, you can run the following command to start your app in the iOS simulator.

$ dotnet build -t:Run -f net7.0-ios

To choose which simulator to use, run the following command first, to get a list of all emulators. (I got to know this from this Github comment)

$ /Applications/Xcode.app/Contents/Developer/usr/bin/simctl list 

...
== Devices ==
-- iOS 16.4 --
iPhone SE (3rd generation) (44D1D920-D740-456A-B3EC-E1AA49ED726A) (Shutdown)
iPhone 14 (03C3959D-1674-4EB3-B28E-1CD5448CC818) (Shutdown)
...

Once you have the Guid, use it to launch the app in the right simulator.

$ dotnet build -t:Run -f net7.0-ios -p:_DeviceName=:v2:udid=03C3959D-1674-4EB3-B28E-1CD5448CC818
Running the .NET MAUI App on the iOS Simulator

5.2. Targeting Windows?

Well… You’ll need to run your app on a Windows Machine, for now.

5.3. Targeting Android?

You’ll need Android tooling. I’m being precise here, you don’t need to install Android Studio. That might be a faster setup, and I encourage you to try it out, but I want to install only the things I need, so here goes.

The following steps took me hours to figure out 😿 🙆🏻‍♂️, so hope it saves you some time.

  • First, I’ll install android-sdk
$ brew install --cask android-sdk
  • Install the SDK tools for the right the android version. For example, in the project I created with dotnet new maui, I see <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">31.0.2</SupportedOSPlatformVersion> in the .csproj file. So i’m installing android-31
$ sdkmanager "system-images;android-31;google_apis;x86_64"

# Make sure you are using the right sdkmanager

$ ls -l `which sdkmanager`
lrwxr-xr-x@ 1 mrsauravsahu mrsauravsahu 60 Jun 1 17:14 /usr/local/bin/sdkmanager -> /usr/local/Caskroom/android-sdk/4333796/tools/bin/sdkmanager
  • Create an emulator with this Android version
$ avdmanager create avd -n my_android_31 -k "system-images;android-31;google_apis;x86_64"
  • Launch the emulator, this has its own quirks.

You need to pass the full path to the emulator binary.

$ /usr/local/share/android-sdk/emulator/emulator -avd my_android_31 -skin 540x1200
# the -skin parameter can be used to change screen resolution

Note: Don’t kill this command, it’ll kill the emulator.

Running the Android Emulator with emulator command

Finally!

Time to run the Android app on this Emulator.

$ dotnet build -t:Run -f net7.0-android
MSBuild version 17.6.1+8ffc3fe3d for .NET
Determining projects to restore...
All projects are up-to-date for restore.
/Users/mrsauravsahu/.cli-config/current/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.46/tools/Xamarin.Android.Tooling.targets(70,5): error XA5300: The Android SDK directory could not be found. Check that the Android SDK Manager in Visual Studio shows a valid installation. To use a custom SDK path for a command line build, set the 'AndroidSdkDirectory' MSBuild property to the custom path. [/Users/mrsauravsahu/Downloads/mrsauravsahu/code/maui-hello-world/maui-hello-world.csproj::TargetFramework=net7.0-android]

Build FAILED.
...

And that failed. So, MSBuild needs to know where the android-sdk is, so we can pass that parameter.

$ dotnet build -t:Run -f net7.0-android -p:AndroidSdkDirectory=/usr/local/share/android-sdk

MSBuild version 17.6.1+8ffc3fe3d for .NET
Determining projects to restore...
All projects are up-to-date for restore.
/Users/mrsauravsahu/.cli-config/current/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.46/targets/Microsoft.Android.Sdk.Tooling.targets(20,5): error XA0031: Java SDK 11.0 or above is required when using .NET 6 or higher. Download the latest JDK at: <https://aka.ms/msopenjdk> [/Users/mrsauravsahu/Downloads/mrsauravsahu/code/maui-hello-world/maui-hello-world.csproj::TargetFramework=net7.0-android]
Build FAILED.
...
Time Elapsed 00:00:01.55

And we need the Java JDK installed as well — Java 11

$ brew install java11

We also need to resolve to this newer version of java if we have any other version installed. I had java 8 installed. We can do that like this.

$ export PATH="/usr/local/opt/openjdk@11/bin:$PATH"

Rerun the build command and your app should now run on the Android Emulator

$ dotnet build -t:Run -f net7.0-android -p:AndroidSdkDirectory=/usr/local/share/android-sd
Running the .NET MAUI App on the Android Emulator

Enhancing the Dev Workflow

And that’s the setup if you want to do things manually. At this moment, you’ll be wondering, running the app is fine, but in my dev workflow, I can’t be wasting time rebuilding the app every time I change something.

Now the reason I suggested installing .NET 7 is because of the coolest MAUI extension I found — https://marketplace.visualstudio.com/items?itemName=nromanov.dotnet-meteor — install this, follow the instructions and you’ll be able to use XAML Hot Reload — so no need to rebuild your app, you’ll be able to see live updates in the emulator.

Conclusion

This was the first blog on .NET MAUI. I’m exploring cross platform app development so I’ll writing more soon. Comment your suggestions and let me know if anything didn’t work and how you fixed it!

— S

--

--

Sahu

Personal Opinions • Beyond Full Stack Engineer @ McKinsey & Company