100 Days of SwiftUI(DAY 26 (Project 4))

DAY 26 (Project 4)BetterRest

iOS開発の真のパワー機能の1つである機械学習(ML)。

すべてのiPhoneには、Core MLと呼ばれるテクノロジーが組み込まれています。
これにより、以前のデータに基づいて新しいデータを予測するコードを作成できます。いくつかの生データから始めて、それをトレーニングデータとしてMacに渡し、その結果を使用して、新しいデータについて正確な推定を行うことができるアプリを構築します。すべてデバイス上で、ユーザーに完全なプライバシーを提供します。
私たちが構築している実際のアプリはBetterRestと呼ばれ、コーヒーを飲む人が3つの質問をすることで安眠を助けるように設計されています。

これが機械学習の出番です。回帰分析と呼ばれる手法を使用して、すべてのデータを表すことができるアルゴリズムをコンピュータに作成するよう依頼できます。これにより、これまでに見たことのない新しいデータにアルゴリズムを適用して、正確な結果を得ることができます。

このプロジェクトのいくつかのファイルをダウンロードする必要があります。これはGitHubから行うことができます:https : //github.com/twostraws/HackingWithSwift

Stepper

struct ContentView: View {
    @State private var sleepAmount = 8.0

    var body: some View {
            Stepper(value: $sleepAmount, in: 3...12,step: 0.25) {
                Text("\(sleepAmount, specifier: "%.2f") hours")
            
            }
    }
}

DatePickerで日付と時刻を選択する

import SwiftUI

import SwiftUI

struct ContentView: View {
    @State private var wakeUp = Date()
    
    // when you create a new Date instance it will be set to the current date and time
    let now = Date()

    // create a second Date instance set to one day in seconds from now
    let tomorrow = Date().addingTimeInterval(86400*2)
    // error
    // create a range from those two
    //let range = now...tomorrow

    var body: some View {
        // DatePicker("Please enter a date", selection: $wakeUp)
        // DatePicker("", selection: $wakeUp)
        // DatePickerにForm:
        /*
        Form {
            DatePicker("Please enter a date", selection: $wakeUp)
        }
      */
        
        // 過去は不可
        //atePicker("Please enter a date", selection: $wakeUp, in: Date()...)
        /*
        DatePicker("Please enter a time", selection: $wakeUp, displayedComponents: .hourAndMinute)
            .labelsHidden()
      */
        
        DatePicker("日時を選択", selection: $wakeUp, in: now...tomorrow)
    
        
    }
}

Computed Properties関連でerror有り 改善案

struct ContentView: View {
    @State private var wakeUp = Date()
    let now:Date = Date()
    let tomorrow = Date().addingTimeInterval(86400)

    var body: some View {
        DatePicker("日時を選択", selection: $wakeUp, in: now...tomorrow)
    }
}


Create MLを使用したモデルのトレーニング

struct ContentView: View {
    @State private var wakeUp = Date()
    @State private var sleepAmount = 8.0
    @State private var coffeeAmount = 1
    
    func calculateBedtime() {
    }

    var body: some View {
        NavigationView {
            VStack {
                Text("When do you want to wake up?")
                    .font(.headline)

                DatePicker("Please enter a time", selection: $wakeUp, displayedComponents: .hourAndMinute)
                    .labelsHidden()

                // more to come
                Text("Desired amount of sleep")
                    .font(.headline)

                Stepper(value: $sleepAmount, in: 4...12, step: 0.25) {
                    Text("\(sleepAmount, specifier: "%g") hours")
                }
                
                Text("Daily coffee intake")
                    .font(.headline)

                Stepper(value: $coffeeAmount, in: 1...20) {
                    if coffeeAmount == 1 {
                        Text("1 cup")
                    } else {
                        Text("\(coffeeAmount) cups")
                    }
                }
                

            }
            .navigationBarTitle("BetterRest")
            .navigationBarItems(trailing:
                // our button here
                Button(action: calculateBedtime) {
                    Text("Calculate")
                }
            )
            
        }
        
    }
}


SwiftUIをコアMLに接続する
Pipeline Regressor
検索KEYWORD(The 100 Days of SwiftUI conputed property)
SOLVED: Day 28 – Challenge Three
解決済み:28日目-チャレンジ3

途中経過、NavigationView、alert、navigationBarItemsなど

import SwiftUI

struct ContentView: View {
    @State private var alertTitle = ""
    @State private var alertMessage = ""
    @State private var showingAlert = false
    
    func calculateBedtime() {
        showingAlert = true
    }
    
    var body: some View {
       NavigationView {
            VStack {
                Text("When do you want to wake up?")
                    .font(.headline)

                
                    //alert
                    .alert(isPresented: $showingAlert) {
                    Alert(title: Text(alertTitle), message: Text(alertMessage), dismissButton: .default(Text("OK")))
                }
            }
            .navigationBarTitle("BetterRest")
            .navigationBarItems(trailing:
            Button(action: calculateBedtime) {
                Text("Calculate")})
        }
    }
}


import SwiftUI

struct ContentView: View {
    @State private var wakeUp = Date()
    @State private var sleepAmount = 8.0
    @State private var coffeeAmount = 1
    
    @State private var alertTitle = ""
    @State private var alertMessage = ""
    @State private var showingAlert = false
    
    func calculateBedtime() {
        let model = SleepCalculator()
        
        let components = Calendar.current.dateComponents([.hour, .minute], from: wakeUp)
        let hour = (components.hour ?? 0) * 60 * 60
        let minute = (components.minute ?? 0) * 60
        //var bedTime = "Please set all input values"
        
        do {
            let prediction = try model.prediction(wake: Double(hour + minute), estimatedSleep: sleepAmount, coffee: Double(coffeeAmount))

            // more code here
            let sleepTime = wakeUp - prediction.actualSleep
            
            let formatter = DateFormatter()
            formatter.timeStyle = .short

            alertMessage = formatter.string(from: sleepTime)
            alertTitle = "Your ideal bedtime is…"
            
        } catch {
            // something went wrong!
            alertTitle = "Error"
            alertMessage = "Sorry, there was a problem calculating your bedtime."
            showingAlert = true
        }
        
        showingAlert = true
    }
    
    var body: some View {
       NavigationView {
            VStack {
                Text("When do you want to wake up?")
                    .font(.headline)

                DatePicker("Please enter a time", selection: $wakeUp, displayedComponents: .hourAndMinute)
                    .labelsHidden()
                
                Text("Desired amount of sleep")
                    .font(.headline)

                Stepper(value: $sleepAmount, in: 4...12, step: 0.25) {
                    Text("\(sleepAmount, specifier: "%g") hours")
                }
                
                Text("Daily coffee intake")
                    .font(.headline)

                Stepper(value: $coffeeAmount, in: 1...20) {
                    if coffeeAmount == 1 {
                        Text("1 cup")
                    } else {
                        Text("\(coffeeAmount) cups")
                    }
                }
                
                //alert
                .alert(isPresented: $showingAlert) {
                Alert(title: Text(alertTitle), message: Text(alertMessage), dismissButton: .default(Text("OK")))}
                
            }
            .navigationBarTitle("BetterRest")
            .navigationBarItems(trailing:
            Button(action: calculateBedtime) {
                Text("Calculate")})
        }
    }
}

最終版



import SwiftUI

struct ContentView: View {
    
    static var defaultWakeTime: Date {
        var components = DateComponents()
        components.hour = 7
        components.minute = 0
        return Calendar.current.date(from: components) ?? Date()
    }
    
    @State private var wakeUp = defaultWakeTime
    //@State private var wakeUp = Date()
    @State private var sleepAmount = 8.0
    @State private var coffeeAmount = 1
    
    @State private var alertTitle = ""
    @State private var alertMessage = ""
    @State private var showingAlert = false
    
    func calculateBedtime() {
        let model = SleepCalculator()
        
        let components = Calendar.current.dateComponents([.hour, .minute], from: wakeUp)
        let hour = (components.hour ?? 0) * 60 * 60
        let minute = (components.minute ?? 0) * 60
        //var bedTime = "Please set all input values"
        
        do {
            let prediction = try model.prediction(wake: Double(hour + minute), estimatedSleep: sleepAmount, coffee: Double(coffeeAmount))

            // more code here
            let sleepTime = wakeUp - prediction.actualSleep
            
            let formatter = DateFormatter()
            formatter.timeStyle = .short

            alertMessage = formatter.string(from: sleepTime)
            alertTitle = "Your ideal bedtime is…"
            
        } catch {
            // something went wrong!
            alertTitle = "Error"
            alertMessage = "Sorry, there was a problem calculating your bedtime."
            showingAlert = true
        }
        
        showingAlert = true
    }
    
    var body: some View {
       NavigationView {
            //VStack {
            Form {
                Text("When do you want to wake up?")
                    .font(.headline)
                /*
                DatePicker("Please enter a time", selection: $wakeUp, displayedComponents: .hourAndMinute)
                    .labelsHidden()
            */
                DatePicker("Please enter a time", selection: $wakeUp, displayedComponents: .hourAndMinute)
                .labelsHidden()
                .datePickerStyle(WheelDatePickerStyle())
                
                VStack(alignment: .leading, spacing: 0) {
                    Text("Desired amount of sleep")
                        .font(.headline)

                    Stepper(value: $sleepAmount, in: 4...12, step: 0.25) {
                        Text("\(sleepAmount, specifier: "%g") hours")
                    }
                }
                
                Text("Daily coffee intake")
                    .font(.headline)

                Stepper(value: $coffeeAmount, in: 1...20) {
                    if coffeeAmount == 1 {
                        Text("1 cup")
                    } else {
                        Text("\(coffeeAmount) cups")
                    }
                }
                
                //alert
                .alert(isPresented: $showingAlert) {
                Alert(title: Text(alertTitle), message: Text(alertMessage), dismissButton: .default(Text("OK")))}
                
            }
            .navigationBarTitle("BetterRest")
            .navigationBarItems(trailing:
            Button(action: calculateBedtime) {
                Text("Calculate")})
        }
    }
}