Let’s take a look at some common stumbling blocks with .NET MAUI development on macOS and ways to get around for a smooth developer experience.
The Hawaiian archipelago, with the island of Maui in particular, is known to grow a fascinating number of exotic fruits. The variety of tropical fruits from Hawaii covers the gamut from commercial fruits like bananas and pineapples, to more unusual varieties like rambutan, cherimoya, dragon fruit and lychee.
But let’s face it—Maui isn’t particularly known for apples. That’s until you do a little research though or actually visit the island. The mountains of Maui produce some unique flavors of apples—pear shaped Ohi’a’ai mountain apples, orange Koru apples, purple apples and even a completely different type of fruit called star apples.
Before you get pensive as to why you can’t grow tropical fruits in your backyard, let’s change topic. We’re talking about .NET MAUI—the evolution of Xamarin.Forms into a modern cross-platform framework for targeting mobile and desktop apps from single codebase. With Release Candidate builds coming up in the horizon, .NET developers are understandably excited about .NET MAUI. But what if your dev machine is Apple-flavored—aka macOS?
There is much to celebrate on Windows-land with Visual Studio 2022 Previews, updated Docs and all the .NET MAUI tooling. But VS for Mac is going through a huge UI update and .NET MAUI tinkering on macOS is mostly powered through CLI tooling. .NET MAUI is also a big promise, and cross-platform tooling has lots of dependencies from various teams—VS engineering, XAML experience, MAUI folks and, of course, bits from Apple and Google.
Staying on the bleeding edge is not always smooth-going—but you’re hardly alone. If you are facing roadblocks developing with .NET MAUI on macOS, it is more than likely someone else has seen the same issues before.
Let’s recap the 10 most common stumbling blocks and how to get around them. macOS is a wonderfully modern desktop OS, particularly for iOS and Android development, and .NET MAUI will have first-class tooling. Apples are indeed welcome in Maui.
The .NET MAUI maui-check CLI tool is indispensable for most MAUI developers. It goes through a system health check for .NET MAUI development, stops by default at each step to point out any missing dependencies and even installs everything for you.
But many folks on macOS may have encountered an initial error running maui-check from their Terminal—this has to do with macOS using ZSH instead of Bash. The location for .NET global tools may just need to be added to your $PATH environment variable for execution, if not done so already. Here’s how:
export PATH=$HOME/.dotnet/tools:$PATH
In case your $HOME may not be set right, you may want to use your explicit macOS home directory name to point to the .NET tools. You can always check your $PATH variable like so:
echo "$PATH"
Here’s mine:
When we build native iOS and Mac Catalyst apps with .NET MAUI, Xcode actually has to do the build and create the app package with assemblies. And there are some dependencies as Apple moves things forward with iOS 15 and macOS Monterey.
Starting with .NET MAUI Preview 6, you have had the need for Xcode 13, which is in beta—you can get the bits from Apple Developer Account, once you sign up for free. Xcode Releases has a nice catalog of all the Xcode builds, release notes and download links.
As of now, .NET MAUI Preview 7 needs Xcode Beta 4/5, and .NET MAUI RC needs Beta 5. Regular Xcode can reside side by side with Beta Xcode—you’ll have to tell the maui-check tool and the .NET MAUI build system which Xcode to use. Here’s how:
When folks on Windows/VS 2022 do File > New Project for .NET MAUI apps, they’re essentially using templates to scaffold projects. You have access to the same templates on macOS—just as CLI. Fire up this command to get a list of all your installed templates:
dotnet new --list
What you see may be different, but you can see some new templates that are being cooked up—you should have the maui and the maui-blazor ones at least.
If for some reason you don’t see any, you can manually grab the templates from NuGet like so:
dotnet new --install Microsoft.Maui.Templates::6.0.100-preview.7.1345
However, please be aware that work is ongoing with the templates and what the project dependencies end up being under the covers. You’re better off trusting the maui-check tool to give you the templates—if needed, consider updating maui-check to get the latest bits:
dotnet tool update -g redth.net.maui.check
And running maui-check asking for latest bits:
maui-check --main/preview
If you’re set up with .NET MAUI tools but app builds complain about missing SDKs, something may not be right with your .NET runtimes. Here’s the way to check quickly:
dotnet --list-sdks
Here are mine going back to the first Previews of .NET 6 and .NET MAUI:
Again maui-check should have gotten you the correct SDKs, but you can always cleanse and do it yourself. Head to Dot.net and grab the latest .NET 6 Preview runtime.
You think you’ve gotten the latest runtimes/SDKs/dependencies and start building your .NET MAUI apps—only to see build errors about some workloads. Well, this may be rare and requires taking a deep breath first—turns out, we’ve had lots of Previews already, and workloads are the silos that .NET MAUI depends on to reach each platform. Here’s what the latest should look like:
If you have been tinkering for a while, it is possible that some older workloads did not get cleaned up and replaced by newer bits. The maui-check repo has a handy script that does some of this cleanup—it’s called Clean-Old-DotNet6-Previews.ps1. But doh—it’s a PowerShell script that is meant for Windows. What gives on a Mac? Relax—it’s easy actually:
All you got to do is save the script locally and point to it:
pwsh <YourLocation/YourFile.ps1>
You may also want to run maui-check with some “force” to ensure the workload repair/update/install commands run regardless of present workloads, like so:
maui-check --force-dotnet
So .NET MAUI is meant to give developers more confidence as we try to reach various platforms from a single codebase—namely iOS, Android, Windows and macOS. You have successfully scaffolded a .NET MAUI project, but then you get told—somewhat rudely—you can’t build for Windows on a Mac! Well, duh—all you wanted was to run the app on iOS, Android and Mac.
Turns out .NET MAUI does not know your intentions and the created solution is meant to support all platforms, including reaching Windows through WinUI 3. The Windows project is a separate folder—in line with MSIX app packaging needs. Here is what you get:
You, of course, cannot run the WinUI project on a Mac. So if you just want to focus on iOS/Android/MacCatalyst and skip Windows. Simply go one level down—into the folder which has the .csproj file and fire up the dotnet build
command to deploy to your chosen platform.
Congratulations first on being able to create/build your .NET MAUI apps—you are on your way to greatness. The next step is to see your app being deployed to iOS Simulators—here’s how:
dotnet build -t:Run -f net6.0-ios
This should launch the app on the default iOS simulator—most likely the iPad Pro as it does for me.
Want to see the app on an iPhone simulator? You can retrieve a list of installed Simulators and their Unique Device IDs (UDID), like so:
/Applications/Xcode.app/Contents/Developer/usr/bin/simctl list
Then you can specify which Simulator you want to run by using the _DeviceName
MSBuild property, like this:
dotnet build -t:Run -f net6.0-ios -p:_DeviceName=:v2:udid=<YourUDID>
Ok, this one wasn’t an easy fix for me. When we deploy an iOS app to a Simulator/Device, it uses an Apple Provisioning Profile—with identifiers tied to you/device and local certificates. Both Xcode and Visual Studio have Settings where you could enter your Apple Developer credentials—does not have to be a paid Apple Store Account. Xamarin.Forms and .NET MAUI then use a default Provisioning Profile with a Wildcard App Identifier—you can manually download the profile/certificates as well.
Between VS 2022 Preview, Xcode Betas and .NET MAUI bits, this somehow got messed up for me and the builds could not grab the default Provisioning Profile. I had to go to Apple Developer Account and manually grab the dummy Provisioning Profile—one that uses a local certificate and tied to one of my iOS devices.
This Provisioning Profile uses a wildcard app identifier—com.sam.*
. So all I have to do in my .NET MAUI project is change the default App Identifier in the .csproj file, like so:
All future deployments to Simulators/Devices are smooth thereafter.
Ah, so you don’t write code that is perfect the first time around and have a need to debug through your code? Welcome to developer reality. Now, under normal circumstances, you expect a stellar debugging experience from Visual Studio and Hot Reload will make the inner loop even faster in .NET MAUI.
However, we do not have VS for Mac or formal VS Code support on macOS yet—there is a silver lining though.
Before we get to that, have you heard of Comet? As a refresher, Comet is the experimental way of bringing MVU design pattern to building the visual UI tree with .NET MAUI—you don’t have to write XAML if you don’t want to. You can get started with Comet/MVU pattern with the corresponding project template—all .NET MAUI tooling works as usual.
dotnet new -i Clancey.Comet.Templates.Multiplatform
dotnet new comet
Now, Comet comes with a handy little VS Code Extension—Comet for .NET Mobile, which can be used for debugging through code. Even if you are not using the MVU way, the Comet extension does actually help in automating the build/change/debug cycle with VS Code running on a Mac. You can start with a default .NET MAUI CLI project template, choose an emulator/device and be able to build/launch the app—all from within VS Code.
.NET MAUI gives you a solid foundation to build cross-platform apps and the toolsets to get started—shipping production quality apps requires a lot of effort. And when it comes to modern mobile/desktop apps, UI is everything—it is the crux of how your users experience the app.
More than likely, your .NET MAUI apps could use some UI help—polished, performant UI components that are well-engineered and could light up your app’s functionality. This is where Progress Telerik UI suites could help—developers get to drop in quality UI components and ship apps faster.
Did you know there is already a Telerik UI for MAUI suite? It’s exactly what it sounds like—all the Telerik UI you like, for all your MAUI apps. You can get started today and give things a spin—the latest Preview works with .NET MAUI Preview 7. You get all the binaries and a simple Demo App that showcases all of the UI on top of .NET MAUI.
Fire up a dotnet build
and you can see the app deployed on iOS/Android/Windows with all the complex Telerik UI that you crave—the Grids, Charts, ListViews, Gauges, BarCodes, PopUps and more. Go make awesome apps with .NET MAUI—Telerik is here to help.
Breaking ground for something big requires a bit of sweat—it is how we get a solid foundation. The same can be said about bleeding-edge tech—you are brave frontline soldiers paving the way forward. .NET MAUI is a wonderful promise for modern cross-platform development, and it is only a matter of time before tooling becomes solid.
Until then, you’re not alone. We can keep tinkering to make the development experience better for all developers. And eat your apples—from Maui or not, they’re great for you!
Sam Basu is a technologist, author, speaker, Microsoft MVP, gadget-lover and Progress Developer Advocate for Telerik products. With a long developer background, he now spends much of his time advocating modern web/mobile/cloud development platforms on Microsoft/Telerik technology stacks. His spare times call for travel, fast cars, cricket and culinary adventures with the family. You can find him on the internet.