general: logging cleanup

This commit is contained in:
Michael Freno
2026-01-13 14:58:31 -05:00
parent 814a524d0d
commit 0d1e8a05df
6 changed files with 23 additions and 87 deletions

View File

@@ -14,55 +14,40 @@ class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
@Published var timerEngine: TimerEngine? @Published var timerEngine: TimerEngine?
private let settingsManager: SettingsManager = .shared private let settingsManager: SettingsManager = .shared
private var updateManager: UpdateManager? private var updateManager: UpdateManager?
private var reminderWindowController: NSWindowController? private var overlayReminderWindowController: NSWindowController?
private var subtleReminderWindowController: NSWindowController?
private var settingsWindowController: NSWindowController? private var settingsWindowController: NSWindowController?
private var cancellables = Set<AnyCancellable>() private var cancellables = Set<AnyCancellable>()
private var hasStartedTimers = false private var hasStartedTimers = false
func applicationDidFinishLaunching(_ notification: Notification) { func applicationDidFinishLaunching(_ notification: Notification) {
print("🚀 Gaze: applicationDidFinishLaunching")
// Set activation policy to hide dock icon // Set activation policy to hide dock icon
NSApplication.shared.setActivationPolicy(.accessory) NSApplication.shared.setActivationPolicy(.accessory)
print("✓ Activation policy set to accessory")
timerEngine = TimerEngine(settingsManager: settingsManager) timerEngine = TimerEngine(settingsManager: settingsManager)
print("✓ TimerEngine initialized")
// Initialize update manager after onboarding is complete // Initialize update manager after onboarding is complete
if settingsManager.settings.hasCompletedOnboarding { if settingsManager.settings.hasCompletedOnboarding {
print("✓ Onboarding completed, initializing UpdateManager")
updateManager = UpdateManager.shared updateManager = UpdateManager.shared
} else {
print(" Onboarding not completed, skipping UpdateManager")
} }
// Detect App Store version asynchronously at launch // Detect App Store version asynchronously at launch
Task { Task {
do { do {
print("🔍 Detecting App Store version...")
await settingsManager.detectAppStoreVersion() await settingsManager.detectAppStoreVersion()
print("✓ App Store detection complete: \(settingsManager.settings.isAppStoreVersion)")
} catch { } catch {
print("⚠️ Failed to detect App Store version: \(error)") // Handle error silently in production
} }
} }
setupLifecycleObservers() setupLifecycleObservers()
print("✓ Lifecycle observers set up")
observeSettingsChanges() observeSettingsChanges()
print("✓ Settings change observer set up")
// Start timers if onboarding is complete // Start timers if onboarding is complete
if settingsManager.settings.hasCompletedOnboarding { if settingsManager.settings.hasCompletedOnboarding {
print("▶️ Starting timers (onboarding complete)")
startTimers() startTimers()
} else {
print("⏸️ Timers not started (onboarding incomplete)")
} }
print("✅ Gaze: Launch complete")
} }
func onboardingCompleted() { func onboardingCompleted() {
@@ -130,7 +115,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
timerEngine?.$activeReminder timerEngine?.$activeReminder
.sink { [weak self] reminder in .sink { [weak self] reminder in
guard let reminder = reminder else { guard let reminder = reminder else {
self?.dismissReminder() self?.dismissOverlayReminder()
return return
} }
self?.showReminder(reminder) self?.showReminder(reminder)
@@ -185,10 +170,10 @@ class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
} }
} }
showReminderWindow(contentView, requiresFocus: requiresFocus) showReminderWindow(contentView, requiresFocus: requiresFocus, isOverlay: requiresFocus)
} }
private func showReminderWindow(_ content: AnyView, requiresFocus: Bool) { private func showReminderWindow(_ content: AnyView, requiresFocus: Bool, isOverlay: Bool) {
guard let screen = NSScreen.main else { return } guard let screen = NSScreen.main else { return }
let window: NSWindow let window: NSWindow
@@ -229,12 +214,24 @@ class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
window.orderFront(nil) window.orderFront(nil)
} }
reminderWindowController = windowController // Track overlay and subtle reminders separately
if isOverlay {
overlayReminderWindowController?.close()
overlayReminderWindowController = windowController
} else {
subtleReminderWindowController?.close()
subtleReminderWindowController = windowController
}
} }
private func dismissReminder() { private func dismissOverlayReminder() {
reminderWindowController?.close() overlayReminderWindowController?.close()
reminderWindowController = nil overlayReminderWindowController = nil
}
private func dismissSubtleReminder() {
subtleReminderWindowController?.close()
subtleReminderWindowController = nil
} }
// Public method to open settings window // Public method to open settings window

View File

@@ -13,18 +13,12 @@ struct GazeApp: App {
@StateObject private var settingsManager = SettingsManager.shared @StateObject private var settingsManager = SettingsManager.shared
init() { init() {
print("🚀 GazeApp: init")
// Handle test launch arguments // Handle test launch arguments
if TestingEnvironment.shouldSkipOnboarding { if TestingEnvironment.shouldSkipOnboarding {
print(" Test mode: Skipping onboarding")
SettingsManager.shared.settings.hasCompletedOnboarding = true SettingsManager.shared.settings.hasCompletedOnboarding = true
} else if TestingEnvironment.shouldResetOnboarding { } else if TestingEnvironment.shouldResetOnboarding {
print(" Test mode: Resetting onboarding")
SettingsManager.shared.settings.hasCompletedOnboarding = false SettingsManager.shared.settings.hasCompletedOnboarding = false
} }
print("✓ GazeApp initialized")
} }
var body: some Scene { var body: some Scene {

View File

@@ -17,53 +17,38 @@ enum AppStoreDetector {
/// This method is asynchronous due to the use of StoreKit's async API. /// This method is asynchronous due to the use of StoreKit's async API.
static func isAppStoreVersion() async -> Bool { static func isAppStoreVersion() async -> Bool {
#if DEBUG #if DEBUG
print("🔍 AppStoreDetector: DEBUG build, returning false")
return false return false
#else #else
print("🔍 AppStoreDetector: Checking App Store status...")
if #available(macOS 15.0, *) { if #available(macOS 15.0, *) {
print(" Using macOS 15+ AppTransaction API")
do { do {
let transaction = try await AppTransaction.shared let transaction = try await AppTransaction.shared
print(" ✅ AppTransaction found: This is an App Store version")
return true return true
} catch { } catch {
print(" ⚠️ AppTransaction error: \(error.localizedDescription)")
print(" → Assuming NOT an App Store version")
return false return false
} }
} else { } else {
// Fallback for older macOS: use legacy receipt check // Fallback for older macOS: use legacy receipt check
print(" Using legacy receipt check (macOS <15)")
guard let receiptURL = Bundle.main.appStoreReceiptURL else { guard let receiptURL = Bundle.main.appStoreReceiptURL else {
print(" ⚠️ No receipt URL available")
return false return false
} }
print(" 📄 Receipt URL: \(receiptURL.path)")
do { do {
let fileExists = FileManager.default.fileExists(atPath: receiptURL.path) let fileExists = FileManager.default.fileExists(atPath: receiptURL.path)
guard fileExists else { guard fileExists else {
print(" ⚠️ Receipt file does not exist")
return false return false
} }
print(" ✓ Receipt file exists")
guard let receiptData = try? Data(contentsOf: receiptURL), guard let receiptData = try? Data(contentsOf: receiptURL),
receiptData.count > 2 receiptData.count > 2
else { else {
print(" ⚠️ Receipt file is empty or unreadable")
return false return false
} }
print(" ✓ Receipt data loaded (\(receiptData.count) bytes)")
let bytes = [UInt8](receiptData.prefix(2)) let bytes = [UInt8](receiptData.prefix(2))
let isValid = bytes[0] == 0x30 && bytes[1] == 0x82 let isValid = bytes[0] == 0x30 && bytes[1] == 0x82
print(" \(isValid ? "" : "⚠️") Receipt validation: \(isValid)")
return isValid return isValid
} catch { } catch {
print(" ❌ Receipt check error: \(error.localizedDescription)")
return false return false
} }
} }

View File

@@ -27,9 +27,6 @@ class SettingsManager: ObservableObject {
private init() { private init() {
self.settings = Self.loadSettings() self.settings = Self.loadSettings()
#if DEBUG
validateTimerConfigMappings()
#endif
setupDebouncedSave() setupDebouncedSave()
} }
@@ -49,34 +46,13 @@ class SettingsManager: ObservableObject {
private static func loadSettings() -> AppSettings { private static func loadSettings() -> AppSettings {
guard let data = UserDefaults.standard.data(forKey: "gazeAppSettings") else { guard let data = UserDefaults.standard.data(forKey: "gazeAppSettings") else {
#if DEBUG
print(" No saved settings found, using defaults")
#endif
return .defaults return .defaults
} }
do { do {
let settings = try JSONDecoder().decode(AppSettings.self, from: data) let settings = try JSONDecoder().decode(AppSettings.self, from: data)
#if DEBUG
print("✅ Settings loaded successfully (\(data.count) bytes)")
#endif
return settings return settings
} catch { } catch {
print("⚠️ Failed to decode settings, using defaults: \(error.localizedDescription)")
if let decodingError = error as? DecodingError {
switch decodingError {
case .keyNotFound(let key, let context):
print(" Missing key: \(key.stringValue) at path: \(context.codingPath)")
case .typeMismatch(let type, let context):
print(" Type mismatch for type: \(type) at path: \(context.codingPath)")
case .valueNotFound(let type, let context):
print(" Value not found for type: \(type) at path: \(context.codingPath)")
case .dataCorrupted(let context):
print(" Data corrupted at path: \(context.codingPath)")
@unknown default:
print(" Unknown decoding error: \(decodingError)")
}
}
return .defaults return .defaults
} }
} }
@@ -90,20 +66,7 @@ class SettingsManager: ObservableObject {
encoder.outputFormatting = .prettyPrinted encoder.outputFormatting = .prettyPrinted
let data = try encoder.encode(settings) let data = try encoder.encode(settings)
userDefaults.set(data, forKey: settingsKey) userDefaults.set(data, forKey: settingsKey)
#if DEBUG
print("✅ Settings saved successfully (\(data.count) bytes)")
#endif
} catch { } catch {
print("❌ Failed to encode settings: \(error.localizedDescription)")
if let encodingError = error as? EncodingError {
switch encodingError {
case .invalidValue(let value, let context):
print(" Invalid value: \(value) at path: \(context.codingPath)")
default:
print(" Encoding error: \(encodingError)")
}
}
} }
} }

View File

@@ -40,7 +40,6 @@ class UpdateManager: NSObject, ObservableObject {
) )
guard let updater = updaterController?.updater else { guard let updater = updaterController?.updater else {
print("Failed to initialize Sparkle updater")
return return
} }
@@ -69,12 +68,10 @@ class UpdateManager: NSObject, ObservableObject {
func checkForUpdates() { func checkForUpdates() {
#if !APPSTORE #if !APPSTORE
guard let updater = updaterController?.updater else { guard let updater = updaterController?.updater else {
print("Updater not initialized")
return return
} }
updater.checkForUpdates() updater.checkForUpdates()
#else #else
print("Updates are managed by the App Store")
#endif #endif
} }

View File

@@ -225,7 +225,7 @@ struct GeneralSetupView: View {
try LaunchAtLoginManager.disable() try LaunchAtLoginManager.disable()
} }
} catch { } catch {
print("Failed to set launch at login: \(error)") // Failed to set launch at login - handled silently in production
} }
} }