- Xamarin Mac App
- Xamarin Forms Mac App
- Xamarin Mac Desktop App
- Xamarin Mac Agent
- Xamarin Mac App Name Android Studio
- Xamarin Mac App Name Finder
With Visual Studio for Mac, HockeyApp, and Xamarin Test Cloud, the online food ordering platform ensured automated app testing, updates, distribution, and monitoring to offer better app experience to their Android and iOS users.
TL;DR I have written a tool that will convert your Xamarin.iOS app(including Xamarin.Forms and MAUI) to a Mac app using Mac Catalyst.This makes creating a macOS app and selling it on the App Store easierthan ever.If you sponsor me on GitHub,subscribe to me on Twitch,or support me through Patreon,I will send you a link to try a beta version of it.
A lot of what I’m about to discuss here was discussed onEpisode 225 of Merge Conflict.Have a listen!
Twitch
I also have been live streaming this work on Twitch. You can see me getting it to work with Xamarin.Forms.
Fragmented Brain
Oh how time changes everything. When I first started programming,I learned to write apps in Visual Basic on Windowsand thought it to be a wonderful canvas upon which build some cool stuff.I thought I would spend the rest of my life learning its ins and outs,mastering its UI, building my own UIs, and being happy.
But time changes everything. I abandoned my beloved VB, to learnMFC and fell in love with that. Then I learned Delphiand thought, finally, the one tool to rule them all.But I was wrong. The web came. All of a sudden I was breakingmy UIs into servers and clients like it was the 1970s.And then iOS came into my life and I abandoned all of that for UIKit.But then Google wanted a piece of the action and thrust Android into the worldand yet another UI framework into my brain.
I have been forced to learn too many frameworks in my pursuit to build cool apps.It’s been exhausting. :-)
Unification
So, when Apple announced a unification of their platform APIs with macOS Catalina,I was all ears.
Apple had decided to allow macOS apps to be written using UIKitas opposed to the mighty AppKit. The technology is called Mac Catalyst and is a port of Apple’s mobile libraries to work on Intel 64-bit Macs.
As I support multiple apps that release for both iOS and Mac, this decisionhas real economic repercussions for my business.
- It will allow me to add another store (another way to sell) my existing apps.
- It will guarantee that all my future apps will also be for sale on at least two stores.
- It will drastically decrease the amount of time I spend fixing UI bugs on mac.
- It will give me more time to focus on and improve the iOS versions of my apps.
All wins in my opinion. While I have grown to love AppKit, with Mac Catalyst,I’m not sure I’ll ever write another AppKit app again.
Lastly, Apple has introduced Apple Silicon macs that will also be able tonatively run UIKit. In the same way UWP is Microsoft’s universal framework,UIKit is shaping up to be Apple’s.
Just one snag, I write my apps using Xamarin.iOSand Microsoft has not yet added support for Catalyst apps.Schedules and all that.
This delay was frustrating me and the opportunity cost was killing me,so I decided to take matters into my own hands and port Xamarin.iOS to Mac Catalyst.Fortunately, Xamarin and mono and .NET are all open source - the code is right there.You just have to be crazy enough to start editing it. :-)
It wasn’t easy, but with enough effort I was able to get it all working!(I would put a GIF here, but seriously no meme could capture how I felt.)
And now it’s time to share that work with everyone.
BETA
If you would like to convert your own apps to run on Macs, I have prepared a downloadableSDK/tool to do that conversion. I am making it available to people who supportmy OSS work. Namely, if you:
Then I will give you a link to the SDK. The SDK is just a little .NET Core toolthat converts the iOS version of your Xamarin app to a Mac Catalyst version.“It just works”
This is an early version so you can also expect errors.That is to say, sometimes, it doesn’t just work. But so far it has been able to runmy largest apps.
I hope you’ll give it a shot. It’s really fun seeing your apps work on Macs!
I haven’t tried releasing to the Mac App Store yet, that’s the next hurdle to overcome.
Contributing Back
I am working with Microsoft and the mono team to integrate this work into theproduct so everyone can use it. Schedules are still tight, and the world is stillcrazy so it will probably take a little time, but I’ll keep working on it!
On that front, the first big step has already been taken. I submitted a PRto the mono project, and it has been accepted!
@akoeplinger Thank you, looks great!
I am so delighted! I have always wanted to be a mono hacker and now I am! :-)
Next steps are getting changes to Xamarin.iOS put in-place. These are smallbut require coordination with the build tooling so have to be donecarefully.
In Conclusion
The future app development is looking bright thanks to Apple’s unification efforts,and Microsoft’s commitment to open source. I can’t wait to get all my apps onto Mac.
If you want to help me out, you can do so by buying my apps and by supporting my open source work.I’ll put those links here one more time. ;-)
The big buzz ever since Microsoft Build has been about Xamarin.Forms 3.0 - and rightfully so - there's a lot of cool features in it.
But I don't want to overlook the next release of Xamarin.Forms - and that's 2.3.5. There are a couple of big time features in this release that are hiding under that last version number being bumped from 2.3.4.
A show stopping feature of Xamarin.Forms 2.3.5 is the ability to create a macOS app. And according to everything I've read, it 'should just work'.
That's what I want to take a look at in this article - how much work it really takes to create a Xamarin.Forms macOS app.
The Setup
I want to prove out, at least to myself, the viability of adding a macOS app to a Xamarin.Forms solution; and have it work well enough where I could potentially deliver it to a customer.
In other words, how much work would it be for me to create a macOS app from an existing Xamarin.Forms application and are there any shortfalls that I would hit immediately?
And most importantly of all, would I be able to stay away from having to write any macOS specific code?
The TL;DR is yes, it is viable... kind of.
Read on for the full story. And all the code can be found on GitHub, of course.
The App
In order to test that out, I decided to throw together a quick app that contains a lot of the UI elements, navigation metaphors, and Xamarin.Forms techniques (like Behaviors
) that I have found myself using a lot lately.
The idea is to get a generic app working on iOS and Android with 100% shared code (the intialization code notwithstanding). Then add in the macOS app, and see how it works without adding any platform specific code or making any compromises to functionality.
So... what kind of app should I make?
Well, it's summer right now in Wisconsin. I love to garden, in fact, I'm sitting in my backyard typing this looking at my garden ... So the app that I decided to create would be a 'Garden Tracker'. So I could theoretically keep track of what I have planted, what managed to die on me, and then restock plants.
The app holds a list of plants that are 'currently planted in the ground' in a ListView
.
Via a ContextAction
on a cell in the ListView
the app allows me to record that a plant died. Taking it off the list of 'planted' plants and moving it to another screen of 'dead plants'. (Unfortunately though I love to garden, I do sometimes I have the touch of death.)
Those two pages are both comprised of ListViews
with straight up TextCells
and are navigated to via a MasterDetailPage
.
There is a third page which is also reached via the MasterDetailPage
and that's the garden center page - where I can restock on plants - which adds them back into the 'currently planted' page. This third page groups plants by type, vegetables, herbs, and flowers - arranged on a TabView
.
There's also a page that's pushed onto the navigation stack via tapping on a plant on the 'currently planted' page - which shows the plant's name along with a Wikipedia page - so I could test out a WebView
.
So while not a totally rigorous app - I felt it exercised a lot of the common functionaity found in a Xamarin.Forms app, and would be a good test to see how well it ported over to macOS.
The macOS Porting
I was pleasantly surprised that getting the app to run on macOS was super simple. It was much more work to create the app in the first place than it was to add in the macOS portion of it.
There's a tutorial on Xamarin's site going over what to do, but I'll run over it here as well with some commentary.
I should mention that I started development with Xamarin.Forms 2.3.5 from the get-go, which is currently still in beta. So you'll need to update all of your NuGets to a 2.3.5 version - so make sure 'show pre-releases' is checked in the NuGet Package Manager.
First up, I went to File -> New Project and added a Mac Cocoa App, as you can see in the screenshot below.
After running through the naming of the app and where it should be saved it's added to your solution and looks deceptively like an iOS app. There are storyboards, view controllers, and an app delegate.
Basic Housekeeping
The first things that need to be done are to add references - to Xamarin.Forms 2.3.5 and to the core project where all of your custom code is stored.
While you're doing maintenance, go into the Info.plist file and delete the entry that says NSMainStoryboardFile
. (You'll probably have to go into the source view to see it.) This will make sure the storyboard doesn't get launched when the app opens.
So, if how do you make sure the app opens the proper Xamarin.Forms window?
AppDelegate
Just like in iOS, the AppDelegate in a Cocoa app is what gets called when lifecyle events such as DidFinishedLaunching
occured.
The next step, and this is an important step, is to make the AppDelegate
class inherit from FormsApplicationDelegate
.
The definition will look like this:
Since there's not a storyboard file to define the window the app should take up, we need to override the MainWindow
property within the AppDelegate
.
That MainWindow
returns an NSWindow
, which is best setup in the constructor of the AppDelegate
.
Stealing... I mean drawing inspiration from... how that NSWindow
is setup from the linked tutorial above from Xamarin, we get the following:
It's pretty self-explanatory on what's going on. Within the constructor the properties of the window are getting set, and it's being returned in the MainWindow
property.
There is one more boilerplate, ininitialization, step that needs to be taken care of.
Go into the MainClass
and add the following line into the static constructor:
So, that's it. There was some macOS specific code ... but it was all intialization, so I won't count it. Plus I'm sure once Xamarin gets the templates setup within Visual Studio, these steps won't even be necessary.
Only thing left to do is run the app...
The Results
And ....
It's ugly!!
Who would have ever guess that a macOS app, by default, would be so ugly!!
To be fair, the out of the box Android apps aren't exactly pretty either, but I expected more from Apple!
Xamarin Mac App
Alright - looks aside - how does it work?
The MasterDetailPage
automatically laid itself out so the Master
portion was always visible. Cool! Just like I would have expected.
Tapping on those ugly, ugly, buttons brings up the different pages - and they work as expected too. In fact, the App.Properties
data store works great - even better than it does on the iOS and Android simulators in that it actually does save to 'disk' when hard exiting (pressing the stop button) from the IDE.
The ListViews
appear to be working as expected as well.
The Behavior
I have to bind the ListView.ItemSelected
event to a Command
in the view model works flawlessly to bring up a child navigation page.
But there is a problem...
An Issue
I had the detail page defined with a StackLayout
with a Label
and a WebView
as its children. Worked great on iOS and Droid.
But on macOS the StackLayout
only shows the bottom portion of the WebView
. Weird.
It was easily solved by putting those 2 controls into a Grid
.
Xamarin Forms Mac App
Not a big deal on this small app, but it might be a pain on a larger app to correct in many places.
Another Issue
Now this may be due to the way macOS works ... but I could not get the ContextAction
on the TextCell
to fire on the 'Planted' page.
Xamarin Mac Desktop App
So there's no way for me to kill a plant!
Not a bad thing in real life ... but if an app relies on those ContextActions
there's some work you need to do in your app.
Overall
I would say ... not too bad.
According to this blog post, there are still some known issues - but some of those have been fixed as I write this.
Xamarin Mac Agent
The layout engine has some bumps yet and I was able to find another bug with the ContextActions
.
Xamarin Mac App Name Android Studio
But it is a preview yet.
I am pretty excited to be able to write macOS apps - without too much effort - with Xamarin.Forms ... now to work on how they look.
Xamarin Mac App Name Finder
Again, check out all the code on GitHub here!