bootstrap bulkhealth moodwell state-of-mind importer mvp
This commit is contained in:
95
BulkHealthApp/Import/ImportFlowViewModel.swift
Normal file
95
BulkHealthApp/Import/ImportFlowViewModel.swift
Normal file
@@ -0,0 +1,95 @@
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
import UniformTypeIdentifiers
|
||||
|
||||
@MainActor
|
||||
final class ImportFlowViewModel: ObservableObject {
|
||||
@Published var template = MoodwellStateOfMindTemplate.template
|
||||
@Published var entries: [MoodwellEntry] = []
|
||||
@Published var sourceKeys: [String] = []
|
||||
@Published var mapping = MoodwellStateOfMindTemplate.defaultMapping
|
||||
@Published var moodValenceScale: [Int: Double] = [1: -0.8, 2: -0.25, 3: 0.3, 4: 0.8]
|
||||
@Published var dryRunResult: DryRunResult?
|
||||
@Published var isImporting = false
|
||||
@Published var statusMessage = ""
|
||||
@Published var errorMessage: String?
|
||||
|
||||
let supportedContentTypes: [UTType] = [.json]
|
||||
|
||||
private let healthKitService = HealthKitService()
|
||||
|
||||
init() {
|
||||
loadBundledSample()
|
||||
}
|
||||
|
||||
func loadBundledSample() {
|
||||
guard let url = Bundle.main.url(forResource: "MoodwellData", withExtension: "json") else {
|
||||
errorMessage = String(localized: "error.sample.missing")
|
||||
return
|
||||
}
|
||||
loadFile(from: url)
|
||||
}
|
||||
|
||||
func loadFile(from url: URL) {
|
||||
do {
|
||||
let data = try Data(contentsOf: url)
|
||||
let payload = try JSONDecoder().decode(MoodwellPayload.self, from: data)
|
||||
entries = payload.mymoods
|
||||
if let firstEntry = payload.mymoods.first {
|
||||
sourceKeys = Array(firstEntry.sourceDictionary.keys).sorted()
|
||||
} else {
|
||||
sourceKeys = []
|
||||
}
|
||||
dryRunResult = nil
|
||||
statusMessage = String.localizedStringWithFormat(
|
||||
NSLocalizedString("status.loaded", comment: ""),
|
||||
entries.count
|
||||
)
|
||||
errorMessage = nil
|
||||
} catch {
|
||||
errorMessage = String(localized: "error.load.file") + " \(error.localizedDescription)"
|
||||
}
|
||||
}
|
||||
|
||||
func runDryRun() {
|
||||
let result = MoodwellStateOfMindTemplate.makeDrafts(entries: entries, mapping: mapping, moodValenceScale: moodValenceScale)
|
||||
dryRunResult = result
|
||||
if result.errors.isEmpty {
|
||||
statusMessage = String.localizedStringWithFormat(
|
||||
NSLocalizedString("status.dryrun.success", comment: ""),
|
||||
result.drafts.count
|
||||
)
|
||||
} else {
|
||||
statusMessage = String.localizedStringWithFormat(
|
||||
NSLocalizedString("status.dryrun.withErrors", comment: ""),
|
||||
result.errors.count
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func commitImport() async {
|
||||
guard let dryRunResult else {
|
||||
errorMessage = String(localized: "error.dryrun.required")
|
||||
return
|
||||
}
|
||||
guard dryRunResult.errors.isEmpty else {
|
||||
errorMessage = String(localized: "error.dryrun.fix")
|
||||
return
|
||||
}
|
||||
|
||||
isImporting = true
|
||||
defer { isImporting = false }
|
||||
|
||||
do {
|
||||
try await healthKitService.requestWriteAccessForStateOfMind()
|
||||
try await healthKitService.save(dryRunResult.drafts)
|
||||
statusMessage = String.localizedStringWithFormat(
|
||||
NSLocalizedString("status.import.success", comment: ""),
|
||||
dryRunResult.drafts.count
|
||||
)
|
||||
errorMessage = nil
|
||||
} catch {
|
||||
errorMessage = String(localized: "error.import.failed") + " \(error.localizedDescription)"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user