98 lines
2.8 KiB
Swift
98 lines
2.8 KiB
Swift
//
|
|
// iKeyMonApp.swift
|
|
// iKeyMon
|
|
//
|
|
// Created by tracer on 30.03.25.
|
|
//
|
|
|
|
import SwiftUI
|
|
import SwiftData
|
|
#if os(macOS)
|
|
import AppKit
|
|
#endif
|
|
|
|
@main
|
|
struct iKeyMonApp: App {
|
|
@StateObject private var sparkleUpdater = SparkleUpdater()
|
|
private let modelContainer: ModelContainer
|
|
|
|
init() {
|
|
#if os(macOS)
|
|
if let customIcon = NSImage(named: "AppIcon") {
|
|
NSApplication.shared.applicationIconImage = customIcon
|
|
}
|
|
#endif
|
|
|
|
self.modelContainer = Self.makeModelContainer()
|
|
}
|
|
|
|
var body: some Scene {
|
|
WindowGroup {
|
|
MainView()
|
|
.environmentObject(sparkleUpdater)
|
|
.onDisappear {
|
|
NSApp.terminate(nil)
|
|
}
|
|
}
|
|
.modelContainer(modelContainer)
|
|
.windowResizability(.contentMinSize)
|
|
|
|
Settings {
|
|
PreferencesView()
|
|
.padding()
|
|
.environmentObject(sparkleUpdater)
|
|
}
|
|
}
|
|
|
|
private static func makeModelContainer() -> ModelContainer {
|
|
let schema = Schema([MetricSample.self])
|
|
let storeURL = metricStoreURL()
|
|
let configuration = ModelConfiguration(url: storeURL)
|
|
|
|
do {
|
|
return try ModelContainer(for: schema, configurations: [configuration])
|
|
} catch {
|
|
print("⚠️ [SwiftData] Failed to open metric store at \(storeURL.path): \(error)")
|
|
resetMetricStore(at: storeURL)
|
|
|
|
do {
|
|
return try ModelContainer(for: schema, configurations: [configuration])
|
|
} catch {
|
|
fatalError("Unable to create metric history store: \(error)")
|
|
}
|
|
}
|
|
}
|
|
|
|
private static func metricStoreURL() -> URL {
|
|
let fileManager = FileManager.default
|
|
let appSupport = fileManager.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
|
|
let directory = appSupport
|
|
.appendingPathComponent(Bundle.main.bundleIdentifier ?? "net.24unix.iKeyMon", isDirectory: true)
|
|
|
|
do {
|
|
try fileManager.createDirectory(at: directory, withIntermediateDirectories: true)
|
|
} catch {
|
|
fatalError("Unable to create application support directory: \(error)")
|
|
}
|
|
|
|
return directory.appendingPathComponent("metric-history.store")
|
|
}
|
|
|
|
private static func resetMetricStore(at url: URL) {
|
|
let fileManager = FileManager.default
|
|
let sidecarURLs = [
|
|
url,
|
|
url.appendingPathExtension("shm"),
|
|
url.appendingPathExtension("wal")
|
|
]
|
|
|
|
for sidecarURL in sidecarURLs where fileManager.fileExists(atPath: sidecarURL.path) {
|
|
do {
|
|
try fileManager.removeItem(at: sidecarURL)
|
|
} catch {
|
|
print("⚠️ [SwiftData] Failed to remove \(sidecarURL.path): \(error)")
|
|
}
|
|
}
|
|
}
|
|
}
|