Enumerations With Functions

Free iOS Development Tutorial

Immerse yourself in this comprehensive iOS development tutorial, where we delve into more complex topics such as enums, classes, methods, properties, and even concepts like memory allocation. Complete step-by-step exercises and get hands-on experience with creating and using enumerations, adding functions, and instantiating a class.

This exercise is excerpted from Noble Desktop’s past app development training materials and is compatible with iOS updates through 2021. To learn current skills in web development, check out our coding bootcamps in NYC and live online.

Topics Covered in This IOS Development Tutorial:

Creating & Using Enumerations, Adding Functions, Instantiating a Class

Exercise Overview

In this exercise, we’ll dive deeper into enums by seeing how they work with classes and methods to assign an appropriate type. We’ll also explore more complex properties including computed properties, and learn about references.

Getting Started

  1. Launch Xcode if it isn’t already open.

  2. Go to File > New > Playground.

  3. Under iOS, double–click on Blank.

  4. Navigate into Desktop > Class Files > yourname-iOS App Dev 1 Class.

  5. Save the file as: Enums.playground

  6. Click Create.

Full-Stack Web Development Certificate: Live & Hands-on, In NYC or Online, 0% Financing, 1-on-1 Mentoring, Free Retake, Job Prep. Named a Top Bootcamp by Forbes, Fortune, & Time Out. Noble Desktop. Learn More.

Creating & Using Enumerations

  1. In your new Playground file, delete all the code that’s there.

  2. Create a new class that has an enum called MaritalStatus inside it, as shown below in bold:

    class Person {
    
       enum MaritalStatus {
    
       }
    
    }
  3. Add the following cases to the MaritalStatus enum:

    enum MaritalStatus {
       case single
       case married
       case divorced
       case complicated
    }

    Adding this MaritalStatus enum inside the Person class means it will only be accessible within the class.

  4. We’re going to add some properties to the Person class. Below the enumeration, add the first two familiar variables shown below:

    enum MaritalStatus {
       case single
       case married
       case divorced
       case complicated
    }
    
    var name: String
    var age: Int

    Don’t worry about the red error for now. We’ll initialize the properties shortly to fix it.

  5. Add the maritalStatus property shown in bold below:

    var name: String
    var age: Int
    var maritalStatus: MaritalStatus

    We’re defining this property of type MaritalStatus (our enum), so it can only ever be one of the four cases we added above.

  6. We’ll assign the next partner variable an optional string data type as a person may or may not have a partner. We’ll also add some extra code that will execute depending on whether the person does have a partner.

    var name: String
    var age: Int
    var maritalStatus: MaritalStatus
    var partner: String? { return }

    We’re defining partner as a computed property (indicated by the return within curly braces). Remember that computed properties draw information from another property, and do not store information themselves.

  7. This partner computed property will draw information from a spouse property we’ll add shortly. Add the bold code as shown below:

    var name: String
    var age: Int
    var maritalStatus: MaritalStatus
    var partner: String? { return spouse?.name ? "No one" }

    Let’s break down what we’ve added to this computed property. We’re using a nil-coalescing operator (a ? b) which unwraps an optional (a) if it contains a value, or returns a default value (b) if a is nil. The first expression (a) must be of an optional type. The second expression (b) must match the type that is stored inside the first.

    For this partner property, spouse? will be unwrapped if it contains a value, and assigned its name. If spouse does not contain a name value (is nil), then it will return the string "No one". We’ll assign the spouse property next (and get rid of the new error).

    NOTE: The question mark in spouse?.name signifies that we are using optional chaining. This means we can ask a question without unwrapping the optional (unlike if we used an exclamation mark).

  8. Next, we’ll add the stored spouse variable, which we’ll assign the type Person (our original class type), and make it an optional, since we don’t necessarily need a value for this person. Add the bold code:

    var partner: String? { return spouse?.name ? "No one"}
    
    var spouse: Person? {
    
    }

    Take note that this Person? optional is referencing another person instance as their spouse. We’ll see why this is important shortly. Within the curly braces we’ll add the code which will execute depending on whether a person has a spouse already. This will get rid of the new red error.

  9. Add the following bold code:

    var partner: String? { return spouse?.name ? "No one"}
    
    private var spouse: Person? {
    
    }

    We set this spouse property to be private. As we’ve seen in an earlier exercise, we set variables to private so that they will only be used by the instance itself internally, and cannot be accessed outside the (Person) class.

  10. Add the following weak keyword shown in bold:

    var partner: String? { return spouse?.name ? "No one"}
    
    private weak var spouse: Person? {
    
    }

    We’ve added this weak keyword because Swift takes care of memory allocation for us automatically (which we’ll see more of in a later exercise). By default, variables have a strong reference. In our example however, one person references another person, and we want to be able to eliminate a person from memory. If two instance references are both strong and pointing to each other, it creates a kind of deadlock—both references can no longer be removed and memory cannot be deallocated. Luckily, weak references allow whatever they are pointing to be deleted as an instance can be deallocated while the weak reference is still referring to it.

    Another error will appear. We’ll get rid of this next.

  11. Add the didSet property observer inside the spouse property shown below.

    private weak var spouse: Person? {
       didSet {
    
       }
    }

    Remember that the didSet property observer keeps tabs on the variable’s value. When didSet detects that the variable has been updated, it will execute the code inside its set of curly brackets.

  12. The code we’ll add within the curly braces will be triggered when the property value is changed. Add the if statement below that will run when we assign or remove the partner of a person.

    private weak var spouse: Person? {
       didSet {
          if spouse!= nil { print("\(name) is now with \(spouse!.name)") }
       }
    }

    If the value of spouse is not nil then the print statement will execute, including both the person and the partner’s name.

  13. If the spouse property does not have a value, an else statement will run. Add the bold code shown below:

    private weak var spouse: Person? {
       didSet {
          if spouse!= nil { print("\(name) is now with \(spouse!.name)") }
          else { print("\(name) is now sadly alone") }
       }
    }
  14. We need to initialize our properties (and get rid of the red error). Add the initializer below the spouse property code block as shown in bold:

    private weak var spouse: Person? {

    Code Omitted To Save Space

    }
    
    init(name: String, age: Int, maritalStatus: MaritalStatus =.single) {
       self.name = name
       self.age = age
       self.maritalStatus = maritalStatus
    }

    We are initializing each person as .single to begin with.

    NOTE: We do not need to initialize the partner property as it is a computed property (not a stored property) which takes its information from another property.

Adding Functions

  1. Add the following marry function below the initializer as shown in bold:

    self.maritalStatus = maritalStatus
    }
    
    func marry(personToMarry: Person) {
    
    }
  2. To check if a person is already partnered, we’ll add an if statement. The statement will check both whether the person has a partner (spouse has a value), or whether the person they want to partner with already has a value. If either are true, a print statement will execute. Add the bold code below:

    func marry(personToMarry: Person) {
       if spouse!= nil || spouse?.spouse!= nil {
          print("Oh, I wish… but no, \(name) is already married to \(spouse!.name). Please divorce first ;)")
          return
       }
    }

    We are setting this if statement to return. Returning this statement means the next statement we add will not be processed and we don’t need an else statement.

  3. If the person, and the potential spouse both do not already have a spouse, a different statement will execute. Add the following in bold below:

    return
       }
    
       spouse = personToMarry ; maritalStatus =.married
       personToMarry.spouse = self ; spouse!.maritalStatus =.married
    }

    If none of the if statement conditions are true (no one has a spouse already) then we’ll assign spouse a personToMarry, and assign the person’s maritalStatus to.married. Remember that self always refers to the instance of the type that is running the code. Here we’re assigning self to the spouse’s personToMarry. We also no longer need the question mark, as we know that the spouse exists. We can unwrap the spouse and set their maritalStatus to.married as well.

    Remember that when using the value of an enum, you must use dot syntax.

    NOTE: We’ve used a semi-colon to keep these statements on the same line so that we know they are associated. Feel free to write each statement on a different line if you prefer.

  4. Just in case things don’t work out, we’ll add one more function called divorce. Below the marry function add the following in bold:

    func marry(personToMarry: Person) {

    Code Omitted To Save Space

    }
    func divorce() {
    
    }
  5. Add the statements to the function shown in bold below:

    func divorce() {
      spouse?.spouse = nil ; spouse?.maritalStatus =.divorced
      spouse = nil ; maritalStatus =.divorced
    }

    In this function we’re using optional chaining again to evaluate whether a spouse exists. If the person has a spouse, the spouse value will be set to nil and maritalStatus will be set to.divorced. This statement separates the two people, so now the spouse will also be assigned a nil value, and a.divorced maritalStatus.

Using the Functions

  1. Below the last curly brace of the Person class, add the following four people constants.

    class Person {

    Code Omitted To Save Space

    }
    
    let june = Person(name: "June", age: 23)
    let march = Person(name: "March", age: 18)
    let jane = Person(name: "Jane", age: 22, maritalStatus:.divorced)
    let jim = Person(name: "Jim", age: 17)

    Remember that we set the default value of maritalStatus to .single in the initializer. This means we don’t need to set maritalStatus for all the people.

  2. Let’s see how the marry function can be used with our people. Add the following:

    let jim = Person(name: "Jim", age: 17)
    
    jane.marry(personToMarry: jim)
  3. If it is not showing already, click the top right middle button show hide debug area to show the Debug area.

  4. In the bottom Debug area, you should see Jane is now with Jim and Jim is now with Jane printed.

  5. We know this works, but let’s see if we can avoid adding some code. Locate where we defined the marry function shown below:

    func marry(personToMarry: Person) {

  6. Insert the underscore (_) as shown below:

    func marry(_ personToMarry: Person) {

    NOTE: The underscore (_) is used if we don’t want to define an explicit argument label for that parameter.

  7. Now return to the bottom of the playground where we married jane and jim. To get rid of the red error, delete personToMarry: so that you’re left with the code shown below:

    let jim = Person(name: "Jim", age: 17)
    
    jane.marry(jim)

    Much simpler!

  8. We can find out who is Jane’s partner by adding the code below:

    jane.marry(jim)
    jane.partner

    In the right sidebar, you should see “Jim” print.

    Remember that this is summoning the computed property partner which looks into the stored property spouse and returns their name.

  9. Let’s confirm Jane’s new marital status. Add the bold code:

    jane.marry(jim)
    jane.partner
    jane.maritalStatus

    In the right sidebar Jane should be married!

  10. Let’s make sure this function is working the way we think. Above the jane.marry(jim) line add the bold code.

    let jim = Person(name: "Jim", age: 17)
    
    jane.maritalStatus
    jim.maritalStatus
    
    jane.marry(jim)
    jane.partner
    jane.maritalStatus

    In the right sidebar you should see divorced next to Jane, and single next to Jim.

  11. Let’s check on Jim’s new marital status. Add the bold code:

    jane.marry(jim)
    jane.partner
    jane.maritalStatus
    jim.maritalStatus

    Great. Jim is definitely married.

  12. We can check Jim’s partner as well. Add the bold code shown below:

    jane.marry(jim)
    jane.partner
    jane.maritalStatus
    jim.partner
    jim.maritalStatus

    The right sidebar should show "Jane".

  13. Sadly, things didn’t go as planned. We’re going to have to use the divorce function. Add the following in bold:

    jim.maritalStatus
    
    jane.divorce()
  14. In the bottom Debug area, you should see Jim is now sadly alone and Jane is now sadly alone printed.

  15. To see Jane’s new partner and marital status, add the following bold code:

    jane.divorce()
    jane.partner
    jane.maritalStatus

    The right sidebar should show "No one" and divorced.

    We’ve just seen how easy it is to create an enumerated type, assign it to a variable, and then use it in functions that manipulate this type. Enumerations are used very often in app development, so we’ll continue to explore them in the next few exercises.

  16. Save and close the file. Keep Xcode open, as we’ll use it in the next exercise.

Noble Desktop Publishing Team

The Noble Desktop Publishing Team includes writers, editors, instructors, and industry experts who collaborate to publish up-to-date content on today's top skills and software. From career guides to software tutorials to introductory video courses, Noble aims to produce relevant learning resources for people interested in coding, design, data, marketing, and other in-demand professions.

More articles by Noble Desktop Publishing Team

How to Learn IOS & Web Development

Master IOS Development, Web Development, Coding, and More with Hands-on Training. IOS Development Involves Designing Apps for Apple Mobile Devices with Tools Like Xcode and SwiftUI.

Yelp Facebook LinkedIn YouTube Twitter Instagram