Mobile App Dev 2022W: Assignment 1

From Soma-notes
Revision as of 23:12, 26 January 2022 by Soma (talk | contribs) (→‎Questions)

This assignment is still being developed.

Please answer all of the following questions in the supplied template. The questions are based on textanalyzer-2, which is an enhanced version of textanalyzer-1 from Tutorial 2. There are ?? questions worth ?? points.

Do not turn in modified applications. Instead, when answering code writing questions, include code snippets and explain how they should be used to modify the application. Use complete sentences when answering. Be sure to list collaborators and outside sources that you used.

Submit your answers via Brightspace by February 3, 2021 by 11:59 PM.

Questions

  1. [4] Questions about AnalysisResult View (lines 34-47):
    1. [1] What is the purpose of the Spacer() calls at the beginning and end of the AnalysisResult body?
    2. [1] What does the result area say when the app starts?
    3. [2] Can you ever make it display the the initial message after you've selected something from the analysis menu? Why or why not?
  2. [1] Why doesn't the AppTitle view use a @Binding decorator for title?
  3. [2] How often are the analysis mode functions called (at minimum)? How do you know?
  4. [2] What happens if we add a line analysisMode = "Count" between lines 13 and 14? Why?

Code: textanalyzer-2 ContentView.swift

//
//  ContentView.swift for textanalyzer-2
//
//  Created by Anil Somayaji on 2022-01-26.
//

import SwiftUI

struct ContentView: View {
    @State private var t = ""
    @State private var analysisMode = "None"
    var body: some View {
        VStack{
            ModeMenu(analysisMode: $analysisMode)
            AppTitle(title: "Text Analyzer")
            TextField("Enter Text", text: $t).padding()
            AnalysisResult(mode: $analysisMode,
                           userInput: $t)
            Spacer()
        }
    }
}

struct AppTitle: View {
    var title: String
    
    var body: some View {
        Spacer()
        Text(title).font(.title).bold().padding()
        Spacer()
    }
}

struct AnalysisResult: View {
    @Binding var mode: String
    @Binding var userInput: String
    
    var body: some View {
        Spacer()
        if let analysisFunc = analysis[mode] {
            Text(mode + ": " + analysisFunc(userInput))
        } else {
            Text("Please Select a Mode")
        }
        Spacer()
    }
}

struct ModeMenu: View {
    @Binding var analysisMode: String

    var body: some View {
        let availModes = [String](analysis.keys)

        Menu("Analysis menu") {
            ForEach(availModes, id: \.self) {
                mode in
                Button(mode, action: {
                    analysisMode = mode
                })
            }
        }

    }
}

func countUpper(s: String) -> String {
    var count = 0
    let upperCase: Set<Character> =
    ["A","B","C","D","E","F","G","H","I","J","K","L","M",
     "N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
    
    for c in s {
        if (upperCase.contains(c)) {
            count += 1
        }
    }
    
    return String(count)
}

func countPetsMentioned(s: String) -> String {
    var count = 0
    let pets = ["Roshi", "Tab", "Shift"]
    
    for p in pets {
        if (s.contains(p)) {
            count += 1
        }
    }
    return String(count)
}

let analysis: [String: (String) -> String] = [
    "Count": {s in return String(s.count)},
    "Empty": {s in return (s == "") ? "Yes" : "No"},
    "Upper Case": countUpper,
    "Pets Mentioned": countPetsMentioned
]

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}