Skip to content

First application


Prepared and tested with Xcode 9 and Swift 4

In this tutorial we cover the following topics


Concepts, info etc.


The Model-View-Controller

Cocoa - a UI framework for building software programs to run on MacOS - heavily uses model-view-controller (MVC) pattern. MVC divides a given software application into three interconnected parts, so as to separate internal representations of information from the ways that information is presented to or accepted from the user.

Components
  • The model directly manages the application's data.
  • The view can be any output representation of information, such as a chart or a diagram. Also other elements like windows, controls, and other that the user can see and interact with are considered to be a part of a view. Multiple views of the same information are possible, such as a bar chart for management and a tabular view for accountants.
  • The controller, accepts input and converts it to commands for the model or view. Controller binds together the model and view. It contains the application logic that decides how to handle the user’s inputs.

Interactions

In addition to dividing the application into three kinds of components, the model-view-controller design defines the interactions between them.

  • A model stores data that is retrieved according to commands from the controller and displayed in the view.
  • A view generates an output presentation to the user based on changes in the model.
  • A controller can send commands to the model to update the model's state (e.g. editing a document). It can also send commands to its associated view to change the view's presentation of the model (e.g. by scrolling through a document).



Actions

An interface objects in a storyboard or nib file can be set up to trigger special methods in our controller class: action methods. For example, we can decide that when the user press a button, a specific action method should be called. Actions are methods that are declared with a special return IBAction code. The declaration for an action method will take one of the following forms:



Outlets

A controller class can refer to objects in a storyboard or nib file by using a special kind of property called an outlet. We can think of an outlet as a pointer to an object within the user interface. For example we can create a button in Interface Builder. By declaring an outlet and connecting that outlet to the button object, we would then be able to use the outlet from within a code to change the text displayed on that button.

Outlets are declared using the keyword IBOutlet. Below there is an example of an outlet called textField, which can be set to point to any text field in the user interface.


Xcode file formats

Interface Builder - an Xcode part we use to design view of MacOS application - supports a few different file types.

  • .nib The oldes one is a binary fomat that uses the extension .nib
    Each nib file can contain any number of objects, but each one will usually contain a single view and controllers or other objects that it is connected to. Such a approach help us to divide an aplication into idependent parts which can be loaded ony when they are needed for display.
  • .xib This is a modern, XML-based, version of .nib files. Both of these formats contain exactly the same sort of document, but the .xib as text-based is more natual choice in term of human readability and source control management systems.
  • .storyboard This type of file can contain several view controllers, as well as information about how they are connected to each other when the application runs. A storyboard never loads all its contents at once which is opposite to the all at once load nib files.
  • It's good to note that although .nib files are today not in use - they are replaced by modern formats - Interface Builder files are still called nib files in many documentation, regardless of whether the extension actually used for the file is .xib or .nib.

Todo (id=001_first_application:explain_xib_vs_storyboard): text: add more description about xib and storyboard



First MacOS application

  1. Step 1: setting up a project in Xcode
    Launch Xcode and select File | New | Project... from main menu or from Welcome to Xcode screen select Create a new Xcode project.

    In project window select macOS | Application | Cocoa App template and then click the Next button.

    You will see the project options sheet, which should look like below (image below shows the completed options sheet after specifying the fields)

    Press Next button, and you will be prompted for a location for your project. When selected, press Create to save the project.
  2. Step 2: a closer look at the project files
    Let’s look at the files that were created for us by Xcode.

    • The first folder, which is always named after our project, is macOS First Application. This is a place where most of the code that we will create go. In the Project Navigator expand the macOS First Application folder. This folder should contain two source code files (the ones that end in .swift), a storyboard file, a .plist file, a .entitlements file, and an asset catalog for containing any assets like images that the application needs.

      The source code files implement two classes that our application needs: the application delegate (AppDelegate.swift) and the view controller (ViewController.swift) for our application’s (only) view. The controller class called ViewController is responsible for managing our application’s view.

      Main.storyboard contains the user interface elements specific to our project’s main view controller.

      Info.plist is a property list that contains information about the application, such as its name, whether it requires any specific features to be present on the devices on which it is run, and so on.

      macOS_First_Application.entitlements Entitlements confer specific capabilities or security permissions to our macOS or iOS app.

    • The Products folder contains the application that this project produces when it is built.

    It is worth to note that the folders in the navigator area do not have to correspond to real folders in a file system. These are logical groupings within Xcode to help us to mantain the source code. The hierarchy inside Xcode is completely independent of the file system hierarchy, so moving a file in Xcode will not change the file’s location on the file system.

    When we take a closer look at ViewController.swift file we can find there some boilerplate code in the form of viewDidLoad and representedObject methods. We can keep them all or delete (or simply comment) if we have no intention to use it.

  3. Step 3: designing the user interface
    Single click Main.storyboard file to open the application’s view in Xcode’s Interface Builder.

    Now we are going to add some simple components: one label, one text field and one button. Select View | Utilities | Object Library (or select a correct icon in Xcode) and find in Object Library a Label object (you can complete this faster with a help of serach field at the bottom).

    Drag the Label from the library and drop it on the white window (not this with View Controller inside) inside the editing area. This will add a label to your application’s view. Place the label at the top and centered by using the blue guidelines that appear to help us. Double-click this label - this will allow you to edit the label's properties. If not, next select from toolbar Attributes Inspector, or from main menu View | Utilities | Show Attributes Inspector, or press Command + Alt + 4.

    Give this label an empty title and as placeholder enter I'am waiting for a new text.

    Because our placeholder text is longer than space left in label component, we have to stretch it a little bit

    Now we can select Product | Run if we are curious whether does it work or not

    To stop it, select macOS First Application | Quit macOS First Application from main menu.

    Notice, that we can't stop it selecting red dot in application's main window top left corner.

    Find in Object Library a Text Field object, then drag and drop it on the white window inside the editing area, just below the label.

    Find in Object Library a Push Button object, then drag and drop it on the white window inside the editing area, just below the text field and change its Title attribute value to Change

  4. Step 4: add outlets
    Select View | Assistant Editor | Show Assistant Editor to open the Assistant Editor. Alternatively we can show and hide the Assistant Editor by clicking the middle editor button in the collection of buttons on the upper-right side of the project window.

    To add an outlet for label, select it in Interface Builder and Control-drag from the label to the empty space just below the @class ViewController: NSViewController { line in the AppDelegate.swift file until you see a horizontal line Insert Outlet ot Action.


    After releasing mous button we will see a pop-up window that offers to create an Outlet or an Outlet Collection.

    As a name for this outlet enter label.

    We can verify if outles has been created by pressing right mouse button on the label where in Referencing Outlets section you shoud be able to find Label - View Controller connection.

    The same way add an outlet for the text field named textField.

  5. Step 5: add an action
    To add an action related to the button we have to use the same Control-drag technique as for label and text field.

    After releasing mous button we will see a pop-up window. First we have to change Connection to Action.

    Next, enter Name as buttonChangePress and select Type as NSButton.

    Finally, press Connect button. You shoud see this code inserted into ViewController.swift


    We can verify that the trigger was creaded by pressing right mouse button on the button where in Sent Actions section we shoud be able to find action - View Controller buttonChangePress:

    Another verification method is to hover over grey dot in the line where the action function starts (line 28 in our case)

    The same works for the label

    and the text field
  6. Step 6: add an action method
    Add the following code to the buttonChangePress method:
  7. Step 7: run and test
    Select Product | Run