In this exercise you will examine a small SwiftUI app built using the MVVM design pattern:

Working with a partner:

  1. Read through the source code carefully.
  2. Download a copy of the project and try it out together.
  3. Then work together to respond to each question below on the paper provided.
  4. Finally, check your responses by expanding the example solutions provided.

Source Code

import Foundation
import Observation
import SwiftUI
 
// MODEL
struct ChemistryTerm: Identifiable {
    
    // MARK: Stored properties
    let id = UUID()
    let term: String
    let definition: String
    var isRevealed: Bool = false
}
 
 
// VIEW MODEL
@Observable
class ChemistryTermViewModel {
 
    // MARK: Stored properties
    var terms: [ChemistryTerm] = [
        ChemistryTerm(
            term: "Atom",
            definition: "The smallest unit of an element that retains its chemical properties."
        ),
        ChemistryTerm(
            term: "Isotope",
            definition: "Atoms of the same element that have different numbers of neutrons."
        ),
        ChemistryTerm(
            term: "Mole",
            definition: "An SI unit representing 6.022 × 10²³ particles of a substance."
        ),
        ChemistryTerm(
            term: "Electronegativity",
            definition: "The tendency of an atom to attract shared electrons toward itself in a bond."
        ),
        ChemistryTerm(
            term: "Oxidation",
            definition: "A process in which an atom or ion loses one or more electrons."
        ),
        ChemistryTerm(
            term: "Catalyst",
            definition: "A substance that increases the rate of a reaction without being consumed."
        ),
        ChemistryTerm(
            term: "Enthalpy",
            definition: "The total heat content of a system measured at constant pressure."
        ),
        ChemistryTerm(
            term: "Molarity",
            definition: "A measure of concentration equal to moles of solute per litre of solution."
        ),
        ChemistryTerm(
            term: "Valence Electrons",
            definition: "Electrons occupying the outermost energy level of an atom."
        ),
        ChemistryTerm(
            term: "Le Chatelier's Principle",
            definition: "A system at equilibrium will shift to partially offset any stress applied to it."
        ),
    ]
 
    // MARK: Functions
    func reveal(termToReveal: ChemistryTerm) {
        for index in terms.indices {
            if terms[index].id == termToReveal.id {
                if terms[index].isRevealed == false {
                    terms[index].isRevealed = true
                } else {
                    terms[index].isRevealed = false
                }
            }
        }
    }
 
}
 
// VIEW
struct ContentView: View {
 
    // MARK: Stored properties
    @State var viewModel = ChemistryTermViewModel()
 
    // MARK: Computed properties
    var body: some View {
        NavigationStack {
            ScrollView {
                VStack(spacing: 12) {
                    Text("Tap to toggle between each definition or term.")
                        .foregroundStyle(.secondary)
                    ForEach(viewModel.terms) { term in
                        Button {
                            viewModel.reveal(termToReveal: term)
                        } label: {
                            VStack(alignment: .leading, spacing: 6) {
                                if term.isRevealed {
                                    Text(term.term)
                                        .font(.headline)
                                        .foregroundStyle(.white)
                                } else {
                                    Text(term.definition)
                                        .font(.subheadline)
                                        .foregroundStyle(.white)
                                        .multilineTextAlignment(.leading)
                                }
                            }
                            .frame(maxWidth: .infinity, alignment: .leading)
                            .padding()
                            .background(term.isRevealed ? Color.green.mix(with: .black, by: 0.2) : Color.blue.mix(with: .black, by: 0.2))
                            .clipShape(RoundedRectangle(cornerRadius: 12))
                        }
                    }
                }
                .padding()
            }
            .navigationTitle("Chemistry Review")
        }
    }
 
}
 
#Preview {
    ContentView()
}

Review Questions

Question 1

Describe the overall purpose of this program.

Question 2

Describe where input and output occur in the running of the program. Identify the specific line(s) of code responsible for each.

Question 3

Identify where data is first stored in an array. Reference the specific line(s) of code that accomplish this.

Question 4

What is the name of the chosen array?

Question 5

Describe where the chosen array is used in the program — for example, where it is iterated over, where individual elements are accessed, or where existing data in the array is used to produce new data or drive behaviour.

Question 6

What does the data stored in the array represent within the program? Describe the type of data stored and what role it plays.

Question 7

Explain how the terms array manages complexity in this program. In your response, explain why the program could not be written — or how it would have to be written differently — if the array were not used.

Question 8

Identify where a function is defined in the program. What is the function’s name? What is its return type, if any? What parameter(s) does it define, and how do they affect what happens inside the function?

Question 9

Where is this function called in the program?

Question 10

What is the purpose of the reveal function, and how does it contribute to the overall functionality of the program?

Question 11

Explain in detailed steps how the reveal function uses sequence, selection, and/or iteration to accomplish its purpose. Your explanation should be detailed enough for someone else to reproduce the function.

Question 12

Describe a scenario where two separate calls to the reveal function, at different points while the program is running, would result in different outcomes.

Question 13

Describe the condition tested by each of the two calls identified above.

Question 14

What will the result of the first call be? What will the result of the second call be?