general: logging cleanup
This commit is contained in:
@@ -14,55 +14,40 @@ class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
|
||||
@Published var timerEngine: TimerEngine?
|
||||
private let settingsManager: SettingsManager = .shared
|
||||
private var updateManager: UpdateManager?
|
||||
private var reminderWindowController: NSWindowController?
|
||||
private var overlayReminderWindowController: NSWindowController?
|
||||
private var subtleReminderWindowController: NSWindowController?
|
||||
private var settingsWindowController: NSWindowController?
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
private var hasStartedTimers = false
|
||||
|
||||
func applicationDidFinishLaunching(_ notification: Notification) {
|
||||
print("🚀 Gaze: applicationDidFinishLaunching")
|
||||
|
||||
// Set activation policy to hide dock icon
|
||||
NSApplication.shared.setActivationPolicy(.accessory)
|
||||
print("✓ Activation policy set to accessory")
|
||||
|
||||
timerEngine = TimerEngine(settingsManager: settingsManager)
|
||||
print("✓ TimerEngine initialized")
|
||||
|
||||
// Initialize update manager after onboarding is complete
|
||||
if settingsManager.settings.hasCompletedOnboarding {
|
||||
print("✓ Onboarding completed, initializing UpdateManager")
|
||||
updateManager = UpdateManager.shared
|
||||
} else {
|
||||
print("ℹ️ Onboarding not completed, skipping UpdateManager")
|
||||
}
|
||||
|
||||
// Detect App Store version asynchronously at launch
|
||||
Task {
|
||||
do {
|
||||
print("🔍 Detecting App Store version...")
|
||||
await settingsManager.detectAppStoreVersion()
|
||||
print("✓ App Store detection complete: \(settingsManager.settings.isAppStoreVersion)")
|
||||
} catch {
|
||||
print("⚠️ Failed to detect App Store version: \(error)")
|
||||
// Handle error silently in production
|
||||
}
|
||||
}
|
||||
|
||||
setupLifecycleObservers()
|
||||
print("✓ Lifecycle observers set up")
|
||||
|
||||
observeSettingsChanges()
|
||||
print("✓ Settings change observer set up")
|
||||
|
||||
// Start timers if onboarding is complete
|
||||
if settingsManager.settings.hasCompletedOnboarding {
|
||||
print("▶️ Starting timers (onboarding complete)")
|
||||
startTimers()
|
||||
} else {
|
||||
print("⏸️ Timers not started (onboarding incomplete)")
|
||||
}
|
||||
|
||||
print("✅ Gaze: Launch complete")
|
||||
}
|
||||
|
||||
func onboardingCompleted() {
|
||||
@@ -130,7 +115,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
|
||||
timerEngine?.$activeReminder
|
||||
.sink { [weak self] reminder in
|
||||
guard let reminder = reminder else {
|
||||
self?.dismissReminder()
|
||||
self?.dismissOverlayReminder()
|
||||
return
|
||||
}
|
||||
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 }
|
||||
|
||||
let window: NSWindow
|
||||
@@ -229,12 +214,24 @@ class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
|
||||
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() {
|
||||
reminderWindowController?.close()
|
||||
reminderWindowController = nil
|
||||
private func dismissOverlayReminder() {
|
||||
overlayReminderWindowController?.close()
|
||||
overlayReminderWindowController = nil
|
||||
}
|
||||
|
||||
private func dismissSubtleReminder() {
|
||||
subtleReminderWindowController?.close()
|
||||
subtleReminderWindowController = nil
|
||||
}
|
||||
|
||||
// Public method to open settings window
|
||||
|
||||
@@ -13,18 +13,12 @@ struct GazeApp: App {
|
||||
@StateObject private var settingsManager = SettingsManager.shared
|
||||
|
||||
init() {
|
||||
print("🚀 GazeApp: init")
|
||||
|
||||
// Handle test launch arguments
|
||||
if TestingEnvironment.shouldSkipOnboarding {
|
||||
print("ℹ️ Test mode: Skipping onboarding")
|
||||
SettingsManager.shared.settings.hasCompletedOnboarding = true
|
||||
} else if TestingEnvironment.shouldResetOnboarding {
|
||||
print("ℹ️ Test mode: Resetting onboarding")
|
||||
SettingsManager.shared.settings.hasCompletedOnboarding = false
|
||||
}
|
||||
|
||||
print("✓ GazeApp initialized")
|
||||
}
|
||||
|
||||
var body: some Scene {
|
||||
|
||||
@@ -17,53 +17,38 @@ enum AppStoreDetector {
|
||||
/// This method is asynchronous due to the use of StoreKit's async API.
|
||||
static func isAppStoreVersion() async -> Bool {
|
||||
#if DEBUG
|
||||
print("🔍 AppStoreDetector: DEBUG build, returning false")
|
||||
return false
|
||||
#else
|
||||
print("🔍 AppStoreDetector: Checking App Store status...")
|
||||
if #available(macOS 15.0, *) {
|
||||
print(" ℹ️ Using macOS 15+ AppTransaction API")
|
||||
do {
|
||||
let transaction = try await AppTransaction.shared
|
||||
print(" ✅ AppTransaction found: This is an App Store version")
|
||||
return true
|
||||
} catch {
|
||||
print(" ⚠️ AppTransaction error: \(error.localizedDescription)")
|
||||
print(" → Assuming NOT an App Store version")
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
// Fallback for older macOS: use legacy receipt check
|
||||
print(" ℹ️ Using legacy receipt check (macOS <15)")
|
||||
|
||||
guard let receiptURL = Bundle.main.appStoreReceiptURL else {
|
||||
print(" ⚠️ No receipt URL available")
|
||||
return false
|
||||
}
|
||||
print(" 📄 Receipt URL: \(receiptURL.path)")
|
||||
|
||||
do {
|
||||
let fileExists = FileManager.default.fileExists(atPath: receiptURL.path)
|
||||
guard fileExists else {
|
||||
print(" ⚠️ Receipt file does not exist")
|
||||
return false
|
||||
}
|
||||
print(" ✓ Receipt file exists")
|
||||
|
||||
guard let receiptData = try? Data(contentsOf: receiptURL),
|
||||
receiptData.count > 2
|
||||
else {
|
||||
print(" ⚠️ Receipt file is empty or unreadable")
|
||||
return false
|
||||
}
|
||||
print(" ✓ Receipt data loaded (\(receiptData.count) bytes)")
|
||||
|
||||
let bytes = [UInt8](receiptData.prefix(2))
|
||||
let isValid = bytes[0] == 0x30 && bytes[1] == 0x82
|
||||
print(" \(isValid ? "✅" : "⚠️") Receipt validation: \(isValid)")
|
||||
return isValid
|
||||
} catch {
|
||||
print(" ❌ Receipt check error: \(error.localizedDescription)")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,9 +27,6 @@ class SettingsManager: ObservableObject {
|
||||
|
||||
private init() {
|
||||
self.settings = Self.loadSettings()
|
||||
#if DEBUG
|
||||
validateTimerConfigMappings()
|
||||
#endif
|
||||
setupDebouncedSave()
|
||||
}
|
||||
|
||||
@@ -49,34 +46,13 @@ class SettingsManager: ObservableObject {
|
||||
|
||||
private static func loadSettings() -> AppSettings {
|
||||
guard let data = UserDefaults.standard.data(forKey: "gazeAppSettings") else {
|
||||
#if DEBUG
|
||||
print("ℹ️ No saved settings found, using defaults")
|
||||
#endif
|
||||
return .defaults
|
||||
}
|
||||
|
||||
do {
|
||||
let settings = try JSONDecoder().decode(AppSettings.self, from: data)
|
||||
#if DEBUG
|
||||
print("✅ Settings loaded successfully (\(data.count) bytes)")
|
||||
#endif
|
||||
return settings
|
||||
} 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
|
||||
}
|
||||
}
|
||||
@@ -90,20 +66,7 @@ class SettingsManager: ObservableObject {
|
||||
encoder.outputFormatting = .prettyPrinted
|
||||
let data = try encoder.encode(settings)
|
||||
userDefaults.set(data, forKey: settingsKey)
|
||||
|
||||
#if DEBUG
|
||||
print("✅ Settings saved successfully (\(data.count) bytes)")
|
||||
#endif
|
||||
} 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)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ class UpdateManager: NSObject, ObservableObject {
|
||||
)
|
||||
|
||||
guard let updater = updaterController?.updater else {
|
||||
print("Failed to initialize Sparkle updater")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -69,12 +68,10 @@ class UpdateManager: NSObject, ObservableObject {
|
||||
func checkForUpdates() {
|
||||
#if !APPSTORE
|
||||
guard let updater = updaterController?.updater else {
|
||||
print("Updater not initialized")
|
||||
return
|
||||
}
|
||||
updater.checkForUpdates()
|
||||
#else
|
||||
print("Updates are managed by the App Store")
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -225,7 +225,7 @@ struct GeneralSetupView: View {
|
||||
try LaunchAtLoginManager.disable()
|
||||
}
|
||||
} catch {
|
||||
print("Failed to set launch at login: \(error)")
|
||||
// Failed to set launch at login - handled silently in production
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user