Make a Simple Mac App in Swift
I have seen some questions from people looking for information on developing Mac apps in Swift. To help people who want to write Mac apps in Swift, I’ve written this tutorial that walks you through creating a simple Mac app in Swift. The app generates and displays a random number when you click a button.
Create the Project
The first step is to open Xcode and create a project. Choose File > New > Project to create a new Xcode project. The New Project Assistant opens.
The project is a Mac app so click the macOS button at the top of the window. Select Cocoa App. Click the Next button to move on to the next step.
Enter the name of the project in the Product Name text field.
Select None from the Team menu. You need a team only if you’re going to submit an app to the Mac App Store. This project is not going on the Mac App Store.
Enter either your name or a company name in the Organization Name text field. Use the organization name to fill out the organization identifier, which takes the form com.OrganizationName
.
Choose Swift from the Language menu.
Select the Use Storyboards checkbox. Deselect the Create Document-Based Application and Use Core Data checkboxes. This project is not a document-based application and does not use Core Data.
Xcode 11 Update
Xcode 11 replaced the Use Storyboards checkbox with an Interface menu. Choose Storyboard from the menu.
This project does not use unit tests or UI tests so you can deselect the Include Unit Tests and Include UI Tests checkboxes if you want.
Click the Next button. Choose a location to save your project. Click the Create button to finish making the project.
After creating the project you should see a list of the project’s files on the left side of the project window. You’re going to work with two files in this tutorial: Main.storyboard
, which contains the user interface, and ViewController.swift
, which contains the source code for the view controller.
Build the User Interface
Let’s start by building the user interface. Select the Main.storyboard
file to open it. The user interface for this project has two items: a label to display the random number and a button to click to generate the random number.
Drag a label and a button from the object library to the view controller scene. If you’re using Xcode 10 or later, the button to access the object library is on the right side of the project window toolbar.
If you’re using an earlier version of Xcode, the object library is in the lower right portion of the project window.
Configure the Label
The label you added can use some configuration so it looks better. You’re going to perform the following configurations:
- Change the label’s text
- Center the text
- Increase the size of the label’s text
- Resize the label
To configure the label select it in the canvas and open the attributes inspector.
Enter the text 0
in the Title text field. Center the text from the Alignment segmented control by clicking the second button.
Use the steppers (up and down arrows) next to the Font text field to increase the size of the text to 36 points.
Resize the label if you need to so it’s big enough to show two digits with the larger text. Select the label in the canvas to resize the label.
Configure the Button
The button has the text Button
. Change the text to Show Number
from the attributes inspector or by double-clicking the button in the canvas. The user interface should look similar to the following when you’re finished:
Create Outlets
Now that you created the user interface, you want to access the label and button in your code. Create outlets so you can do this. Outlets are variables in your code that hold items in your project’s storyboards and xib files.
The first step to creating an outlet is to open the assistant editor so the storyboard and source code file are both open. Choose View > Assistant Editor > Show Assistant Editor to open the assistant editor. Open the file Main.storyboard
in one editor and the file ViewController.swift
in the other editor.
Select the button in the storyboard. Hold down the Control key and drag to the ViewController.swift
file. When the mouse cursor is inside the definition of the ViewController
class, you should see the text Insert Outlet or Action
. When you see that text you can let go of the mouse button. A popover like the following will open:
Enter a name for the outlet in the Name text field. Notice how Xcode knows the type is NSButton
. Click the Connect button to finish creating the outlet.
Repeat the process for the label. Select it and control-drag to the ViewController.swift
file. This time you’ll notice the type is NSTextField
instead of NSButton
. Labels in Mac apps are text fields and not their own special class like they are in iOS. After creating the outlets, the code should look similar to the following:
Make sure the outlets are connected with filled-in circles like they are on the left side of the screenshot. If the outlets aren’t connected, the app will crash when you try to access the outlets.
Create an Action
When someone clicks the button, the app should generate a random number and display it. Create an action so you can add the code to generate the random number and display it. An action is a function that is connected to an item in your user interface. Clicking on the item calls the action.
Creating an action is similar to creating an outlet. Select the button and control-drag to the ViewController.swift
file. When you see the Insert Outlet or Action
, let go of the mouse button to open a popover.
The connection is now an action. Enter the name in the Name text field. The Type combo box determines the data type of the action’s sender. For this project all you care about is the button was clicked so you can stick with Any
, which can be any type. If you needed to access the button’s title, you would choose NSButton
from the Type combo box. Click the Connect button to create the action, which should look similar to the following:
Make sure the action is connected on the left side of the editor or nothing will happen when you click the button.
Write the Code
Now it’s time to write some code. There are two functions you need to write. The first function generates a random number. The second function updates the label with the random number.
The following function generates a random number:
func generateRandomNumber() -> Int {
let minValue = 0
let maxValue = 99
return Int.random(in: minValue...maxValue)
}
The first two lines of code define the range for the random number, 0–99. The last line of code generates a random integer in the range I defined. I could have reduced this function to one line,
return Int.random(in: 0...99)
But I didn’t want to hardcode the values so I created the two constants for the minimum and maximum values.
The following function updates the label with the generated random number:
func updateLabel(value: Int) {
valueLabel.stringValue = value.description
}
The code sets the label’s text to the value of the number I passed to the function. The description
property holds the string representation of the number so it can be displayed in the label.
The last thing to do is to call the two functions in the showRandomNumber
action. If you don’t add the code to the action, nothing will happen when you click the button.
@IBAction func showRandomNumber(_ sender: Any) {
let randomValue = generateRandomNumber()
updateLabel(value: randomValue)
}
Conclusion
Click the Play button in the project window toolbar to build and run the project. When you click the Show Number button, a new number appears above the button.
I have the project on GitHub if you run into any problems.
If you’re looking to build on this project, I have a few suggestions.
- Try creating the project with a xib file instead of a storyboard. Deselect the Use Storyboards checkbox when creating the project. You’ll be using the
AppDelegate.swift
file instead ofViewController.swift
. - Add arguments to the
generateRandomNumber
function for the minimum and maximum values so you can specify the minimum and maximum values for the random number generator. - Add text fields to the user interface so people can specify the minimum and maximum values for the random number generator.