{"id":29944,"date":"2017-02-22T11:39:26","date_gmt":"2017-02-22T19:39:26","guid":{"rendered":"https:\/\/blog.xamarin.com\/?p=29944"},"modified":"2019-04-04T08:34:06","modified_gmt":"2019-04-04T15:34:06","slug":"building-your-first-macos-app","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/building-your-first-macos-app\/","title":{"rendered":"Building Your First macOS App"},"content":{"rendered":"<p>\t\t\t\tWhen developers think of building Xamarin apps for Apple devices, they often think of iPhone and iPad, but you can also build apps for macOS. While not exactly the same as its iOS counterpart, there are many transferable skills for iOS developers looking to build apps for macOS. With Xamarin.Mac, developers can create great macOS apps with the simplicity of C#.<\/p>\n<p>In this blog post, you&#8217;ll learn how to create your first macOS app in C#: a Pomodoro timer to keep us productive.<\/p>\n<h2>Getting Started with macOS<\/h2>\n<p>Building apps for macOS start just like any other application, with <code>File &gt; New<\/code>. Note that you&#8217;ll need to have Xamarin.Mac installed on your macOS device; building macOS apps from Visual Studio is unsupported.<\/p>\n<p><code>File &gt; New Solution &gt; Mac &gt; App &gt; Cocoa App<\/code><\/p>\n<p>Next, we need to enter the app name; we&#8217;ll call this\u00a0&#8220;Pomodoro.&#8221;<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-30028 size-full\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Screenshot-2017-02-21-09.22.55.png\" alt=\"\" width=\"903\" height=\"656\" \/><\/p>\n<p>The <code>Dock Item<\/code> and <code>Extension<\/code> options are customizable, but for now we&#8217;ll leave them unchecked and with the blank \/ default values. We&#8217;ll visit these in a later blog post.<\/p>\n<p>We now have our basic macOS app! You can test it by running the app from the top-left of Xamarin Studio. Unlike Xamarin.iOS, there is no need to choose a target to run the app on, since the app will run right on your Mac. You should see something like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Screenshot-2017-02-21-12.24.20.png\" alt=\"\" width=\"1119\" height=\"700\" \/><\/p>\n<h2>Building a User Interface<\/h2>\n<p>Now that we have a basic macOS app, it&#8217;s time to build out our user interface; a blank app isn&#8217;t very useful!<\/p>\n<p>Xamarin.Mac uses Xcode&#8217;s Interface Builder to develop UIs. Just like iOS, macOS interfaces are built using storyboards. Storyboard support on macOS was introduced in 10.10 (Yosemite). For the sake of simplicity, we&#8217;ll concentrate on macOS 10.10 and higher. If your application needs to support 10.9 or lower, you\u2019ll need to use .xib files, which you can read more about in our <a href=\"https:\/\/developer.xamarin.com\/guides\/mac\/application_fundamentals\/working-with-xibs\/\" target=\"_blank\">working with .xib files<\/a> guide.<\/p>\n<p>In the solution explorer, double-click <code>Main.storyboard<\/code>. Xcode will open automatically with a \u201cstub\u201d project and your storyboard will open in Interface Builder.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Screenshot-2017-02-21-09.24.27.png\" alt=\"\" width=\"1794\" height=\"1092\" \/><\/p>\n<p>The first thing we see is our blank UI. Notice that there&#8217;s a menu bar within the storyboard; you can use this to customize the menu bar for your app. For now, let\u2019s leave the menu as it is.<\/p>\n<p>Adding objects to our interface is somewhat similar to using the iOS designer in Xamarin Studio. On the bottom-right of the Interface Builder window, you&#8217;ll see the toolbox. You can view the available objects by selecting the icon &#8220;Show the Object library,&#8221; as shown here:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Screen-Shot-2017-02-21-at-19.14.15.png\" alt=\"Screen Shot 2017-02-21 at 19.14.15\" width=\"270\" height=\"302\" class=\"aligncenter size-full wp-image-30037\" \/><\/p>\n<p>We can simply drag and drop the views on the view controller. To start with, let\u2019s make an interface like the one below, which consists of a label and a button.<\/p>\n<p>First, find the <strong>Label<\/strong> object and then drag and drop the object into our View Controller.<\/p>\n<p>We can do the same for the <strong>Push Button<\/strong>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Screenshot-2017-02-21-09.27.33.png\" alt=\"\" width=\"600\" \/><\/p>\n<p>To edit the label and title for the button, you can either double-click to edit the text, or, in the <strong>Attributes Inspector<\/strong> in the top right, find the \u201cTitle\u201d and edit it there.<\/p>\n<p>Now that we have our user interface created, it&#8217;s time to configure actions and outlets to work with the user interface in code. To do this, we need switch to the Assistant Editor, so at the top right of the main Xcode window, click the icon that looks like two overlapping circles. This should automatically bring up a file called \u201cViewController.h\u201d. If it doesn\u2019t, then, at the top of the new editor pane, click on \u201cAutomatic\u201d and choose <code>Manual &gt; Pomodoro &gt; Pomodoro &gt; ViewController.h<\/code>. Xcode should now look like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Screenshot-2017-02-21-12.29.55.png\" alt=\"\" width=\"1194\" height=\"784\" \/><\/p>\n<p>Setting up actions and outlets in the header file (the .h file) will allow us to reference them from our Xamarin project. To run code when the button is clicked, we need to set up an action and to reference the label from our Xamarin project, we need to set up an outlet.<\/p>\n<p>Hold down the Control key, then click and drag from the button to the line beneath the final closing brace in the right editor. In the pop-up window, change the <b>Connection<\/b> to <code>Outlet<\/code> and the name to <code>TimerLabel<\/code> and hit connect:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Screenshot-2017-02-21-09.28.14.png\" alt=\"\" width=\"1194\" height=\"728\" \/><\/p>\n<p>This will automatically populate the header file with the correct definition for the outlet:<\/p>\n<pre class=\"theme:vs2012 lang:cs decode:true\">\n@property (nonatomic, retain) IBOutlet NSTextField *TimerLabel;\n<\/pre>\n<p>Repeat the same steps for the button, this time naming it <code>StartStopButton<\/code>.<\/p>\n<p>Now we need to add the action for the button. Hold down the Control key, then click and drag as before. This time, in the pop-up window, change the <b>Connection<\/b> to <code>Action<\/code> and the name to <code>StartStopButtonClicked<\/code> and hit connect:<\/p>\n<p>Once complete, you should have the following definitions:<\/p>\n<pre class=\"theme:vs2012 lang:cs decode:true\">\n@property (nonatomic, retain) IBOutlet NSButton *StartStopButton;\n@property (nonatomic, retain) IBOutlet NSTextField *TimerLabel;\n- (IBAction)StartStopButtonClicked:(id)sender;\n<\/pre>\n<p>For now, that&#8217;s all we need to do with Xcode so you can switch back to Xamarin Studio and the changes will be synced automatically.<\/p>\n<h3>Adding Behavior to the UI<\/h3>\n<p>Back in Xamarin Studio, open the <code>ViewController.cs<\/code> file. We can now add the code for the button we set up in Xcode.<\/p>\n<p>Add the following properties:<\/p>\n<pre class=\"theme:vs2012 lang:cs decode:true\">\nTimer MainTimer;\nint TimeLeft = 1500; \/\/ 1500 seconds in 25 minutes\n<\/pre>\n<p>Then, in <code>ViewDidLoad<\/code> add the following code:<\/p>\n<pre class=\"theme:vs2012 lang:cs decode:true\">\n\/\/ Fire the timer once a second\nMainTimer = new Timer(1000);\nMainTimer.Elapsed += (sender, e) =&gt; {\n    TimeLeft--;\n    \/\/ Format the remaining time nicely for the label\n    TimeSpan time = TimeSpan.FromSeconds(TimeLeft);\n    string timeString = time.ToString(@\"mm\\:ss\");\n    InvokeOnMainThread(() =&gt; {\n        \/\/We want to interact with the UI from a different thread,\n        \/\/ so we must invoke this change on the main thread\n        TimerLabel.StringValue = timeString;\n    });\n\n    \/\/ If 25 minutes have passed\n    if (TimeLeft == 0)\n    {\n        \/\/ Stop the timer and reset\n        MainTimer.Stop();\n        TimeLeft = 1500;\n        InvokeOnMainThread(() =&gt; {\n            \/\/ Reset the UI\n            TimerLabel.StringValue = \"25:00\";\n            StartStopButton.Title = \"Start\";\n            NSAlert alert = new NSAlert();\n            \/\/ Set the style and message text\n            alert.AlertStyle = NSAlertStyle.Informational;\n            alert.MessageText = \"25 Minutes elapsed! Take a 5 minute break.\";\n            \/\/ Display the NSAlert from the current view\n            alert.BeginSheet(View.Window);\n        });\n    }\n};\n<\/pre>\n<p>Finally, we need the code that will trigger when the button is clicked (we set up the action for this earlier):<\/p>\n<pre class=\"theme:vs2012 lang:cs decode:true\">\npartial void StartStopButtonClicked(NSObject sender)\n{\n    \/\/ If the timer is running, we want to stop it,\n    \/\/ otherwise we want to start it\n    if (MainTimer.Enabled)\n    {\n        MainTimer.Stop();\n        StartStopButton.Title = \"Start\";\n    }\n    else\n    {\n        MainTimer.Start();\n        StartStopButton.Title = \"Stop\";\n    }\n}\n<\/pre>\n<p>Now we have a basic Pomodoro timer! When the app is run, you can click the button to start the countdown timer:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-30034 size-full\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Screenshot-2017-02-21-13.17.15.png\" alt=\"\" width=\"592\" height=\"404\" \/><\/p>\n<p>Once 25 minutes has elapsed, an alert will be shown:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-30035 size-full\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Screenshot-2017-02-21-13.18.06.png\" alt=\"\" width=\"564\" height=\"376\" \/><\/p>\n<h2>Summary<\/h2>\n<p>Building apps with Xamarin.Mac is a great way to build powerful apps for macOS that harness the power of C#. In this blog post, we created a basic Pomodoro timer application for macOS. If you want to learn more about Xamarin.Mac, check out the <a href=\"https:\/\/docs.microsoft.com\/en-us\/xamarin\/mac\/get-started\/hello-mac\" target=\"_blank\">Xamarin.Mac documentation<\/a> and get involved in discussions on the <a href=\"https:\/\/forums.xamarin.com\/\" target=\"_blank\">forum<\/a>! The completed code for this blog post can be found on my <a href=\"https:\/\/github.com\/BytesGuy\/XMPomodoro\" target=\"_blank\">GitHub<\/a>.\t\t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When developers think of building Xamarin apps for Apple devices, they often think of iPhone and iPad, but you can also build apps for macOS. While not exactly the same as its iOS counterpart, there are many transferable skills for iOS developers looking to build apps for macOS. With Xamarin.Mac, developers can create great macOS [&hellip;]<\/p>\n","protected":false},"author":552,"featured_media":30034,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[6,4],"class_list":["post-29944","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-ios","tag-xamarin-platform"],"acf":[],"blog_post_summary":"<p>When developers think of building Xamarin apps for Apple devices, they often think of iPhone and iPad, but you can also build apps for macOS. While not exactly the same as its iOS counterpart, there are many transferable skills for iOS developers looking to build apps for macOS. With Xamarin.Mac, developers can create great macOS [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/29944","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/552"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=29944"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/29944\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=29944"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=29944"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=29944"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}