Mobile App Dev 2021W: Tutorial 2

From Soma-notes
Revision as of 04:58, 24 January 2021 by Soma (talk | contribs)

This tutorial is still being developed.

Introduction

Concepts

  • Functions, closures
  • command line synchronous interface
  • iOS async interface
  • dictionaries
  • nested Views

Tasks

Code

Converter.swift

//  Conversions.swift

struct Converter {
    var convFrom = "From Type"
    var convTo = "To Type"
    var convert: (_ from: Double) -> Double?
    
    func formatConversion(_ from: Double) -> String {
        if let to = self.convert(from) {
            return "\(from) \(self.convFrom) is \(to) \(self.convTo)."
        } else {
            return "Converting \(from) \(convFrom) to \(self.convTo) failed."
        }
    }
    
    init(_ from: String, _ to: String, _ f: @escaping (_ from: Double) -> Double?) {
        self.convFrom = from
        self.convTo = to
        self.convert = f
    }
}

func InToCM(_ inch: Double) -> Double {
    let cm = 2.54 * inch
    return cm
}

let conversions: [String: Converter] =
    ["F to C": Converter("Farenheit", "Celsius",
                         {F in return ((F - 32.0)*(5/9))}),
     "C to F": Converter("Celsius", "Farenheit",
                         {C in return ((9/5)*C + 32.0)}),
     "km to mi": Converter("kilometers", "miles",
                           {k in
                            let m = k * 0.6213712
                            return m
                           }),
     "inch to cm": Converter("inches", "centimeters",
                             InToCM)
    ]

ContentView.swift (Converter2)

// ContentView.swift (Converter2)

import SwiftUI

struct ContentView: View {
    @State var convMode: String? = nil
    @State var fromS = ""
    var body: some View {
        VStack{
            ConvMenu(convMode: $convMode,
                     fromString: $fromS)
            Spacer()
            ConvOutput(convMode: $convMode,
                       fromString: $fromS)
            Spacer()
            Spacer()
        }
    }
}

struct ConvMenu: View {
    @Binding var convMode: String?
    @Binding var fromString: String
    var body: some View {
        let availConversions = [String](conversions.keys)
        Menu("Conversions menu") {
            ForEach(availConversions, id: \.self) {
                conversion in
                Button(conversion, action: {
                    convMode = conversion
                    fromString = ""
                })
            }
        }
    }
}

struct ConvOutput: View {
    @Binding var convMode: String?
    @Binding var fromString: String
    var body: some View {
        if let mode = convMode {
            let conv = conversions[mode]!
            TextField("Enter \(conv.convFrom)", text: $fromString)
            Spacer()
            if let from = Double(fromString) {
                Text(conv.formatConversion(from))
            }
        } else {
            Text("Please select a conversion")
            Text("type from the menu above.")
        }
    }
}

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

main.swift (Convert2Cmd)

//  main.swift (Convert2Cmd)

var convAvail = conversions.keys.sorted()

func getChoice() -> String? {
    print("Available Conversions:")
    for i in 0..<convAvail.count {
        print(" \(i+1). \(convAvail[i])")
    }
    
    print("Enter choice: ", terminator: "")
    if let choice = readLine() {
        if let c = Int(choice) {
            if ((c > 0) && (c <= convAvail.count)) {
                return convAvail[c-1]
            }
        }
    }
    return nil
}

let getConversion = {(_ choice: String) in
    let conv = conversions[choice]!
    print("\nEnter \(conv.convFrom): ", terminator: "")
    if let vs = readLine() {
        if let v = Double(vs) {
            let res = conv.formatConversion(v)
            print(res)
            return
        } else {
            print("You didn't enter a number!")
        }
    }
}

if let choice = getChoice() {
    getConversion(choice)
} else {
    print("You didn't make a valid choice!")
}