본문 바로가기
IT/swift

100 days of SwiftUI - Day27

by 가능성1g 2024. 11. 23.
반응형

저번 시간에 결과로 뽑아낸 ML모델을 이용해서 간단한 앱을 만든다.

제목하야 더 나은 숙면을 위하여!

알다시피 저번 ML이 하루에 먹은 커피양, 일어나고 싶은 시간, 자고싶은 시간을 입력하면 몇시에 자야 되는지에 대해서 추측할수 있는 거다. 

그래서 UI는 그것들을 입력받아서 ML을 호출해서 팝업으로 띄워주는 내용이다. 

 

//
//  ContentView.swift
//  BetterRest
//
//  Created by HanTJ on 11/23/24.
//

import SwiftUI
import CoreML

struct ContentView: View {
    @State private var wakeUp = defaultWakeTime
    @State private var sleepAmount = 8.0
    @State private var coffeeAmount = 1
    
    @State private var alertTitle = ""
    @State private var alertMessage = ""
    @State private var showingAlert = false
    
    static var defaultWakeTime: Date {
        var components = DateComponents()
        components.hour = 7
        components.minute = 0
        return Calendar.current.date(from: components) ?? .now
    }
    
    var body: some View {
        NavigationStack{
            Form {
                VStack(alignment: .leading, spacing: 0){
                    Text("언제 일어나고 싶나요?")
                        .font(.headline)
                    
                    DatePicker("시간을 입력하세요", selection: $wakeUp, displayedComponents: .hourAndMinute)
                        .labelsHidden()
                }
                
                VStack(alignment: .leading, spacing: 0){
                    Text("자고싶은 수면의 시간")
                        .font(.headline)
                    
                    Stepper("\(sleepAmount.formatted()) 시간", value: $sleepAmount, in: 4...12, step: 0.25)
                }
                
                VStack(alignment: .leading, spacing: 0){
                    Text("하루에 먹는 커피양")
                        .font(.headline)
                    
                    Stepper("\(coffeeAmount) 잔", value: $coffeeAmount, in: 1...20)
                }
            }
            .navigationTitle("더 나은 숙면을 위하여")
            .alert(alertTitle, isPresented: $showingAlert) {
                Button("OK") { }
            } message: {
                Text(alertMessage)
            }
            .toolbar {
                Button("계산", action: calculateBedTime)
            }
        }
    }
    
    func calculateBedTime() {
        do {
            let config = MLModelConfiguration()
            let model = try SleepCalculator(configuration: config)
            
            let components = Calendar.current.dateComponents([.hour, .minute], from: wakeUp)
            let hour = (components.hour ?? 0) * 60 * 60
            let minute = (components.minute ?? 0) * 60
            
            let prediction = try model.prediction(wake: Double(hour+minute), estimatedSleep: sleepAmount, coffee: Double(coffeeAmount))
            
            let sleepTime = wakeUp - prediction.actualSleep
            
            alertTitle = "잠자리에 들어야 하는시간은…"
            alertMessage = sleepTime.formatted(date: .omitted, time: .shortened)
        }catch {
            alertTitle = "오류"
            alertMessage = "숙면시간 계산중 오류 발생"
        }
        showingAlert = true
    }
}

#Preview {
    ContentView()
}

ML을 쓰기 위해 import CoreML을 썼다.

모델파일을 프로젝트에 드래그 드랍 하는걸로 바로 쓸수 있다. (확장자 mlmodel )

모델파일과 동일한 클래스가 자동생성되니, 그걸 쓰는 느낌이다. 

모델을 만들때 썼던 input, output을 그대로 쓴다. 

이번 UI에서 가장 중점적인것은 Date관련이다. 공부가 많이 필요하다. DateComponent, Calendar 를 이용한다. 

값을 입력받는걸 만들때는 Form으로 그룹화 하는게 이쁘게 나온다. 

(복습) 팝업창 띄우기 !!

 

10:10분에 자야지 잘 잘수 있군!!

반응형