diff --git a/Nudge/UI/Defaults.swift b/Nudge/UI/Defaults.swift index 6056ce29..f42c7f92 100644 --- a/Nudge/UI/Defaults.swift +++ b/Nudge/UI/Defaults.swift @@ -98,13 +98,13 @@ class DNDConfig { self.rawValue = rawType.init() } else { self.rawValue = nil - utilsLog.error("DNDSAuxiliaryStateMonitor class could not be found.") + LogManager.error("DNDSAuxiliaryStateMonitor class could not be found.", logger: utilsLog) } } required init?(rawValue: NSObject?) { guard let rawType = Self.rawType, let unwrappedRawValue = rawValue, unwrappedRawValue.isKind(of: rawType) else { - utilsLog.error("Initialization with rawValue failed.") + LogManager.error("Initialization with rawValue failed.", logger: utilsLog) return nil } self.rawValue = unwrappedRawValue diff --git a/Nudge/UI/Main.swift b/Nudge/UI/Main.swift index 14b0307c..46264dc6 100644 --- a/Nudge/UI/Main.swift +++ b/Nudge/UI/Main.swift @@ -153,7 +153,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { return .terminateNow } else { // Log the attempt to exit the application if it should not exit yet - uiLog.warning("Attempt to exit Nudge was prevented.") + LogManager.warning("Attempt to exit Nudge was prevented.", logger: uiLog) return .terminateCancel } } @@ -186,7 +186,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { } @objc func logHiddenApplication(_ notification: Notification) { - utilsLog.info("Application hidden") + LogManager.info("Application hidden", logger: utilsLog) } @objc func scheduleLocal(applicationIdentifier: String) { @@ -199,13 +199,13 @@ class AppDelegate: NSObject, NSApplicationDelegate { switch settings.authorizationStatus { case .authorized, .provisional: center.add(request) - uiLog.info("Scheduled notification for terminated application \(applicationIdentifier)") + LogManager.info("Scheduled notification for terminated application \(applicationIdentifier)", logger: uiLog) case .denied: - uiLog.info("Notifications are denied; cannot schedule notification for \(applicationIdentifier)") + LogManager.info("Notifications are denied; cannot schedule notification for \(applicationIdentifier)", logger: uiLog) case .notDetermined: - uiLog.info("Notification status not determined; cannot schedule notification for \(applicationIdentifier)") + LogManager.info("Notification status not determined; cannot schedule notification for \(applicationIdentifier)", logger: uiLog) @unknown default: - uiLog.info("Unknown notification status; cannot schedule notification for \(applicationIdentifier)") + LogManager.info("Unknown notification status; cannot schedule notification for \(applicationIdentifier)", logger: uiLog) } } } @@ -213,32 +213,32 @@ class AppDelegate: NSObject, NSApplicationDelegate { // Observe screen locking. Maybe useful later @objc func screenLocked(_ notification: Notification) { nudgePrimaryState.screenCurrentlyLocked = true - utilsLog.info("Screen was locked") + LogManager.info("Screen was locked", logger: utilsLog) } @objc func screenParametersChanged(_ notification: Notification) { - utilsLog.info("Screen parameters changed - Notification Center") + LogManager.info("Screen parameters changed - Notification Center", logger: utilsLog) UIUtilities().centerNudge() } @objc func screenProfileChanged(_ notification: Notification) { - utilsLog.info("Display has changed profiles - Notification Center") + LogManager.info("Display has changed profiles - Notification Center", logger: utilsLog) UIUtilities().centerNudge() } @objc func screenUnlocked(_ notification: Notification) { nudgePrimaryState.screenCurrentlyLocked = false - utilsLog.info("Screen was unlocked") + LogManager.info("Screen was unlocked", logger: utilsLog) } @objc func spacesStateChanged(_ notification: Notification) { UIUtilities().centerNudge() - utilsLog.info("Spaces state changed") + LogManager.info("Spaces state changed", logger: utilsLog) nudgePrimaryState.afterFirstStateChange = true } @objc func terminateApplicationSender(_ notification: Notification) { - utilsLog.info("Application launched - checking if application should be terminated") + LogManager.info("Application launched - checking if application should be terminated", logger: utilsLog) terminateApplications() } @@ -252,7 +252,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { private func applyRandomDelayIfNecessary() { if UserExperienceVariables.randomDelay { let delaySeconds = Int.random(in: 1...UserExperienceVariables.maxRandomDelayInSeconds) - uiLog.notice("Delaying initial run (in seconds) by: \(delaySeconds)") + LogManager.notice("Delaying initial run (in seconds) by: \(delaySeconds)", logger: uiLog) sleep(UInt32(delaySeconds)) } } @@ -260,7 +260,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { private func checkForBadProfilePath() { let badProfilePath = "/Library/Managed Preferences/com.github.macadmins.Nudge.json.plist" if FileManager.default.fileExists(atPath: badProfilePath) { - prefsProfileLog.warning("Found bad profile path at \(badProfilePath)") + LogManager.warning("Found bad profile path at \(badProfilePath)", logger: prefsProfileLog) exit(1) } } @@ -293,35 +293,35 @@ class AppDelegate: NSObject, NSApplicationDelegate { switch event.modifierFlags.intersection(.deviceIndependentFlagsMask) { // Disable CMD + W - closes the Nudge window and breaks it case [.command] where event.charactersIgnoringModifiers == "w": - utilsLog.warning("Nudge detected an attempt to close the application via CMD + W shortcut key.") + LogManager.warning("Nudge detected an attempt to close the application via CMD + W shortcut key.", logger: utilsLog) return true // Disable CMD + N - closes the Nudge window and breaks it case [.command] where event.charactersIgnoringModifiers == "n": - utilsLog.warning("Nudge detected an attempt to close the application via CMD + N shortcut key.") + LogManager.warning("Nudge detected an attempt to close the application via CMD + N shortcut key.", logger: utilsLog) return true // Disable CMD + Q - fully closes Nudge case [.command] where event.charactersIgnoringModifiers == "q": - utilsLog.warning("Nudge detected an attempt to quit the application via CMD + Q shortcut key.") + LogManager.warning("Nudge detected an attempt to quit the application via CMD + Q shortcut key.", logger: utilsLog) return true // Disable CMD + M - Minimizes Nudge case [.command] where event.charactersIgnoringModifiers == "m": - utilsLog.warning("Nudge detected an attempt to minimize the application via CMD + M shortcut key.") + LogManager.warning("Nudge detected an attempt to minimize the application via CMD + M shortcut key.", logger: utilsLog) return true // Disable CMD + H - Hides Nudge case [.command] where event.charactersIgnoringModifiers == "h": - utilsLog.warning("Nudge detected an attempt to hide the application via CMD + H shortcut key.") + LogManager.warning("Nudge detected an attempt to hide the application via CMD + H shortcut key.", logger: utilsLog) return true // Disable CMD + Option + Esc (Force Quit Applications) case [.command, .option] where event.charactersIgnoringModifiers == "\u{1b}": // Escape key - utilsLog.warning("Nudge detected an attempt to open Force Quit Applications via CMD + Option + Esc.") + LogManager.warning("Nudge detected an attempt to open Force Quit Applications via CMD + Option + Esc.", logger: utilsLog) return true // Disable CMD + Option + M - Minimizes Nudge case [.command, .option] where event.charactersIgnoringModifiers == "ยต": - utilsLog.warning("Nudge detected an attempt to minimise the application via CMD + Option + M shortcut key.") + LogManager.warning("Nudge detected an attempt to minimise the application via CMD + Option + M shortcut key.", logger: utilsLog) return true // Disable CMD + Option + N - Add tabs to Nudge window case [.command, .option] where event.charactersIgnoringModifiers == "~": - utilsLog.warning("Nudge detected an attempt to add tabs to the application via CMD + Option + N shortcut key.") + LogManager.warning("Nudge detected an attempt to add tabs to the application via CMD + Option + N shortcut key.", logger: utilsLog) return true default: // Don't care about any other shortcut keys @@ -345,7 +345,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { private func handleAttemptToFetchMajorUpgrade() { if GlobalVariables.fetchMajorUpgradeSuccessful == false && !majorUpgradeAppPathExists && !majorUpgradeBackupAppPathExists { - uiLog.error("Unable to fetch major upgrade and application missing, exiting Nudge") + LogManager.error("Unable to fetch major upgrade and application missing, exiting Nudge", logger: uiLog) nudgePrimaryState.shouldExit = true exit(1) } @@ -353,7 +353,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { private func handleNoAttemptToFetchMajorUpgrade() { if !majorUpgradeAppPathExists && !majorUpgradeBackupAppPathExists { - uiLog.error("Unable to find major upgrade application, exiting Nudge") + LogManager.error("Unable to find major upgrade application, exiting Nudge", logger: uiLog) nudgePrimaryState.shouldExit = true exit(1) } @@ -385,7 +385,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { handleNoAttemptToFetchMajorUpgrade() } } else { - prefsProfileLog.warning("actionButtonPath is nil or empty - actionButton will be unable to trigger any action required for major upgrades") + LogManager.warning("actionButtonPath is nil or empty - actionButton will be unable to trigger any action required for major upgrades", logger: prefsProfileLog) return } } @@ -429,11 +429,11 @@ class AppDelegate: NSObject, NSApplicationDelegate { let center = UNUserNotificationCenter.current() center.requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in if granted { - utilsLog.info("User granted notifications - application blocking status now available") + LogManager.info("User granted notifications - application blocking status now available", logger: utilsLog) } else if let error = error { - utilsLog.error("Error requesting notifications authorization: \(error.localizedDescription)") + LogManager.error("Error requesting notifications authorization: \(error.localizedDescription)", logger: utilsLog) } else { - utilsLog.info("User denied notifications - application blocking status will be unavailable") + LogManager.info("User denied notifications - application blocking status will be unavailable", logger: utilsLog) } } } @@ -511,10 +511,10 @@ class AppDelegate: NSObject, NSApplicationDelegate { private func terminateApplication(_ application: NSRunningApplication) { guard application.terminate() else { - utilsLog.error("Failed to terminate application: \(application.bundleIdentifier ?? "")") + LogManager.error("Failed to terminate application: \(application.bundleIdentifier ?? "")", logger: utilsLog) return } - utilsLog.info("Successfully terminated application: \(application.bundleIdentifier ?? "")") + LogManager.info("Successfully terminated application: \(application.bundleIdentifier ?? "")", logger: utilsLog) } private func terminateApplications() { @@ -529,7 +529,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { continue } if OptionalFeatureVariables.blockedApplicationBundleIDs.contains(appBundleID) { - utilsLog.info("Found \(appBundleID), terminating application") + LogManager.info("Found \(appBundleID), terminating application", logger: utilsLog) terminateApplication(runningApplication) } } diff --git a/Nudge/Utilities/Logger.swift b/Nudge/Utilities/Logger.swift index ab38b049..9bd156f5 100644 --- a/Nudge/Utilities/Logger.swift +++ b/Nudge/Utilities/Logger.swift @@ -15,6 +15,26 @@ struct LogManager { static func createLogger(category: String) -> Logger { return Logger(subsystem: bundleID, category: category) } + + static func debug(_ message: String, logger: Logger) { + logger.debug("\(message, privacy: .public)") + } + + static func error(_ message: String, logger: Logger) { + logger.error("\(message, privacy: .public)") + } + + static func info(_ message: String, logger: Logger) { + logger.info("\(message, privacy: .public)") + } + + static func notice(_ message: String, logger: Logger) { + logger.notice("\(message, privacy: .public)") + } + + static func warning(_ message: String, logger: Logger) { + logger.warning("\(message, privacy: .public)") + } } // Usage of Logger Manager @@ -45,6 +65,6 @@ class LogState { // NudgeLogger class NudgeLogger { init() { - loggingLog.debug("Starting log events") + LogManager.debug("Starting log events", logger: loggingLog) } } diff --git a/Nudge/Utilities/Preferences.swift b/Nudge/Utilities/Preferences.swift index 9bab4c6e..f507d48a 100644 --- a/Nudge/Utilities/Preferences.swift +++ b/Nudge/Utilities/Preferences.swift @@ -45,7 +45,7 @@ func getOptionalFeaturesProfile() -> [String: Any]? { private func logEmptyKey(_ key: String, forJSON: Bool) { if !nudgeLogState.afterFirstLaunch { let log = forJSON ? prefsJSONLog : prefsProfileLog - log.info("\(key) key is empty") + LogManager.info("\(key) key is empty", logger: log) } } diff --git a/Nudge/Utilities/SoftwareUpdate.swift b/Nudge/Utilities/SoftwareUpdate.swift index 7d27412b..f799eae9 100644 --- a/Nudge/Utilities/SoftwareUpdate.swift +++ b/Nudge/Utilities/SoftwareUpdate.swift @@ -13,19 +13,19 @@ class SoftwareUpdate { let (output, error, exitCode) = runProcess(launchPath: "/usr/sbin/softwareupdate", arguments: ["--list", "--all"]) if exitCode != 0 { - softwareupdateListLog.error("Error listing software updates: \(error)") + LogManager.error("Error listing software updates: \(error)", logger: softwareupdateListLog) return error } else { - softwareupdateListLog.info("\(output)") + LogManager.info("\(output)", logger: softwareupdateListLog) return output } } func download() { - softwareupdateDownloadLog.notice("enforceMinorUpdates: \(OptionalFeatureVariables.enforceMinorUpdates)") + LogManager.notice("enforceMinorUpdates: \(OptionalFeatureVariables.enforceMinorUpdates)", logger: softwareupdateDownloadLog) if DeviceManager().getCPUTypeString() == "Apple Silicon" && !AppStateManager().requireMajorUpgrade() { - softwareupdateListLog.debug("Apple Silicon devices do not support automated softwareupdate downloads for minor updates. Please use MDM for this functionality.") + LogManager.debug("Apple Silicon devices do not support automated softwareupdate downloads for minor updates. Please use MDM for this functionality.", logger: softwareupdateListLog) return } @@ -33,39 +33,39 @@ class SoftwareUpdate { guard FeatureVariables.actionButtonPath == nil else { return } if OptionalFeatureVariables.attemptToFetchMajorUpgrade, !majorUpgradeAppPathExists, !majorUpgradeBackupAppPathExists { - softwareupdateListLog.notice("Device requires major upgrade - attempting download") + LogManager.notice("Device requires major upgrade - attempting download", logger: softwareupdateListLog) let (output, error, exitCode) = runProcess(launchPath: "/usr/sbin/softwareupdate", arguments: ["--fetch-full-installer", "--full-installer-version", OSVersionRequirementVariables.requiredMinimumOSVersion]) if exitCode != 0 { - softwareupdateDownloadLog.error("Error downloading software update: \(error)") + LogManager.error("Error downloading software update: \(error)", logger: softwareupdateDownloadLog) } else { - softwareupdateDownloadLog.info("\(output)") + LogManager.info("\(output)", logger: softwareupdateDownloadLog) GlobalVariables.fetchMajorUpgradeSuccessful = true // Update the state based on the download result } } else { - softwareupdateListLog.notice("Found major upgrade application or backup - skipping download") + LogManager.notice("Found major upgrade application or backup - skipping download", logger: softwareupdateListLog) } } else { if OptionalFeatureVariables.disableSoftwareUpdateWorkflow { - softwareupdateListLog.notice("Skipping running softwareupdate because it's disabled by a preference.") + LogManager.notice("Skipping running softwareupdate because it's disabled by a preference.", logger: softwareupdateListLog) return } let softwareupdateList = self.list() let updateLabel = extractUpdateLabel(from: softwareupdateList) if !softwareupdateList.contains(OSVersionRequirementVariables.requiredMinimumOSVersion) || updateLabel.isEmpty { - softwareupdateListLog.notice("Software update did not find \(OSVersionRequirementVariables.requiredMinimumOSVersion) available for download - skipping download attempt") + LogManager.notice("Software update did not find \(OSVersionRequirementVariables.requiredMinimumOSVersion) available for download - skipping download attempt", logger: softwareupdateListLog) return } - softwareupdateListLog.notice("Software update found \(updateLabel) available for download - attempting download") + LogManager.notice("Software update found \(updateLabel) available for download - attempting download", logger: softwareupdateListLog) let (output, error, exitCode) = runProcess(launchPath: "/usr/sbin/softwareupdate", arguments: ["--download", updateLabel]) if exitCode != 0 { - softwareupdateDownloadLog.error("Error downloading software updates: \(error)") + LogManager.error("Error downloading software updates: \(error)", logger: softwareupdateDownloadLog) } else { - softwareupdateDownloadLog.info("\(output)") + LogManager.info("\(output)", logger: softwareupdateDownloadLog) } } } diff --git a/Nudge/Utilities/UILogic.swift b/Nudge/Utilities/UILogic.swift index f239a9e6..788713cc 100644 --- a/Nudge/Utilities/UILogic.swift +++ b/Nudge/Utilities/UILogic.swift @@ -12,16 +12,16 @@ import SwiftUI func initialLaunchLogic() { guard !CommandLineUtilities().unitTestingEnabled() else { - uiLog.debug("App being ran in test mode") + LogManager.debug("App being ran in test mode", logger: uiLog) return } if CommandLineUtilities().simpleModeEnabled() { - uiLog.debug("Device in simple mode") + LogManager.debug("Device in simple mode", logger: uiLog) } if CommandLineUtilities().demoModeEnabled() { - uiLog.debug("Device in demo mode") + LogManager.debug("Device in demo mode", logger: uiLog) resetDeferralsForDemoMode() return } @@ -35,18 +35,18 @@ func initialLaunchLogic() { private func checkDeferralDate() { let deferralDate = nudgePrimaryState.deferRunUntil ?? nudgePrimaryState.lastRefreshTime if shouldExitBasedOnDeferralDate(deferralDate: deferralDate) { - uiLog.notice("User has selected a deferral date (\(nudgePrimaryState.deferRunUntil ?? nudgePrimaryState.lastRefreshTime)) that is greater than the launch date (\(DateManager().getCurrentDate())") + LogManager.notice("User has selected a deferral date (\(nudgePrimaryState.deferRunUntil ?? nudgePrimaryState.lastRefreshTime)) that is greater than the launch date (\(DateManager().getCurrentDate())", logger: uiLog) AppStateManager().exitNudge() } } private func handleDemoMode() -> Bool { if nudgeLogState.afterFirstRun { - uiLog.info("Ignoring Nudge activation - Device is in demo mode") + LogManager.info("Ignoring Nudge activation - Device is in demo mode", logger: uiLog) nudgeLogState.afterFirstRun = true return false } else { - uiLog.notice("Nudge activating - Launching demo mode UI") + LogManager.notice("Nudge activating - Launching demo mode UI", logger: uiLog) AppStateManager().activateNudge() return true } @@ -54,13 +54,13 @@ private func handleDemoMode() -> Bool { private func handleUpdateStatus() { if VersionManager.fullyUpdated() { - uiLog.notice("Device is fully updated") + LogManager.notice("Device is fully updated", logger: uiLog) // Because Nudge will bail if it detects installed OS >= required OS, this will cause the Xcode preview to fail. if !uiConstants.isPreview { AppStateManager().exitNudge() } } else if !OptionalFeatureVariables.enforceMinorUpdates && !AppStateManager().requireMajorUpgrade() { - uiLog.warning("Device requires a minor update but enforceMinorUpdates is false") + LogManager.warning("Device requires a minor update but enforceMinorUpdates is false", logger: uiLog) AppStateManager().exitNudge() } } @@ -68,7 +68,7 @@ private func handleUpdateStatus() { private func isAcceptableApplicationFrontmost(_ frontmostApplication: NSRunningApplication?) -> Bool { if builtInAcceptableApplicationBundleIDs.contains(frontmostApplication?.bundleIdentifier ?? "") || OptionalFeatureVariables.acceptableApplicationBundleIDs.contains(frontmostApplication?.bundleIdentifier ?? "") { - uiLog.info("Ignoring Nudge activation - acceptableApplication is currently the frontmostApplication") + LogManager.info("Ignoring Nudge activation - acceptableApplication is currently the frontmostApplication", logger: uiLog) return true } return false @@ -78,7 +78,7 @@ private func isAcceptableAssertionRunning() -> Bool { var assertions: Unmanaged? guard IOPMCopyAssertionsByProcess(&assertions) == kIOReturnSuccess, let assertionDict = assertions?.takeRetainedValue() as NSDictionary? else { - uiLog.info("Could not assess assertions") + LogManager.error("Could not assess assertions", logger: uiLog) return false } @@ -88,7 +88,7 @@ private func isAcceptableAssertionRunning() -> Bool { if let processName = assertion["Process Name"] as? String, let assertionType = assertion["AssertionTrueType"] as? String, OptionalFeatureVariables.acceptableAssertionApplicationNames.contains(processName) { - uiLog.info("Ignoring Nudge activation - Assertion \(assertionType) is set for \(processName)") + LogManager.info("Ignoring Nudge activation - Assertion \(assertionType) is set for \(processName)", logger: uiLog) return true } } @@ -119,7 +119,7 @@ private func isMajorUpgradeAppFrontmost(_ frontmostApplication: NSRunningApplica if majorUpgradeAppPathExists { let majorUpgradeAppURL = URL(fileURLWithPath: OSVersionRequirementVariables.majorUpgradeAppPath, isDirectory: false) if frontmostApplication?.bundleURL == majorUpgradeAppURL { - uiLog.info("Ignoring Nudge activation - majorUpgradeApp is currently the frontmostApplication") + LogManager.info("Ignoring Nudge activation - majorUpgradeApp is currently the frontmostApplication", logger: uiLog) return true } } @@ -127,7 +127,7 @@ private func isMajorUpgradeAppFrontmost(_ frontmostApplication: NSRunningApplica if majorUpgradeBackupAppPathExists { let backupAppURL = URL(fileURLWithPath: NetworkFileManager().getBackupMajorUpgradeAppPath(), isDirectory: false) if frontmostApplication?.bundleURL == backupAppURL { - uiLog.info("Ignoring Nudge activation - majorUpgradeBackupApp is currently the frontmostApplication") + LogManager.info("Ignoring Nudge activation - majorUpgradeBackupApp is currently the frontmostApplication", logger: uiLog) return true } } @@ -147,7 +147,7 @@ private func isRefreshTimerPassedThreshold() -> Bool { let currentTime = DateManager().getCurrentDate().timeIntervalSince1970 let timeSinceLastRefresh = currentTime - nudgePrimaryState.lastRefreshTime.timeIntervalSince1970 if nudgeLogState.afterFirstLaunch && Double(ConfigurationManager().getTimerController()) > timeSinceLastRefresh { - uiLog.info("Ignoring Nudge activation - Device is currently within current timer range") + LogManager.info("Ignoring Nudge activation - Device is currently within current timer range", logger: uiLog) return true } return false @@ -162,10 +162,10 @@ private func isScreenSharingActive() -> Bool { private func logControllers() { if !nudgeLogState.afterFirstRun { - uiLog.info("nudgeRefreshCycle: \(UserExperienceVariables.nudgeRefreshCycle)") + LogManager.info("nudgeRefreshCycle: \(UserExperienceVariables.nudgeRefreshCycle)", logger: uiLog) nudgeLogState.afterFirstRun = true if !UIConstants.DNDServer { - uiLog.error("acceptableScreenSharingUsage is set but DoNotDisturbServer framework is unavailable") + LogManager.error("acceptableScreenSharingUsage is set but DoNotDisturbServer framework is unavailable", logger: uiLog) } } } @@ -192,7 +192,7 @@ private func logUserSessionDeferrals(resetCount: Bool = false) { func needToActivateNudge() -> Bool { if NSApplication.shared.isActive { - uiLog.notice("Nudge is currently the frontmostApplication") + LogManager.notice("Nudge is currently the frontmostApplication", logger: uiLog) return false } @@ -219,7 +219,7 @@ func needToActivateNudge() -> Bool { private func processNudgeEvent() { if VersionManager.newNudgeEvent() { - uiLog.notice("New Nudge event detected - resetting all deferral values") + LogManager.notice("New Nudge event detected - resetting all deferral values", logger: uiLog) resetAllDeferralValues() } else { updateDeferralCounts() @@ -241,7 +241,7 @@ private func resetDeferralsForDemoMode() { private func shouldActivateNudgeBasedOnAggressiveExperience(_ runningApplications: [NSRunningApplication], _ frontmostApplication: NSRunningApplication?) -> Bool { if frontmostApplication?.bundleIdentifier != nil { - uiLog.info("\(frontmostApplication!.bundleIdentifier ?? "") is currently the frontmostApplication") + LogManager.info("\(frontmostApplication!.bundleIdentifier ?? "") is currently the frontmostApplication", logger: uiLog) } let shouldActivate = nudgePrimaryState.deferralCountPastThreshold || DateManager().pastRequiredInstallationDate() @@ -251,7 +251,7 @@ private func shouldActivateNudgeBasedOnAggressiveExperience(_ runningApplication for runningApplication in runningApplications { if shouldHideApplication(runningApplication) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.001) { - uiLog.info("Attempting to hide \(runningApplication.bundleIdentifier ?? "")") + LogManager.info("Attempting to hide \(runningApplication.bundleIdentifier ?? "")", logger: uiLog) runningApplication.hide() } } @@ -281,13 +281,13 @@ private func shouldBailOutEarly() -> Bool { // Check if admin has set noTimers if UserExperienceVariables.noTimers { - uiLog.info("Ignoring Nudge activation - noTimers is set") + LogManager.info("Ignoring Nudge activation - noTimers is set", logger: uiLog) return true } // Check if screen is locked if nudgePrimaryState.screenCurrentlyLocked { - uiLog.info("Ignoring Nudge activation - Screen is currently locked") + LogManager.info("Ignoring Nudge activation - Screen is currently locked", logger: uiLog) return true } @@ -298,13 +298,13 @@ private func shouldBailOutEarly() -> Bool { // Check if camera is on and it's before the required installation date if OptionalFeatureVariables.acceptableCameraUsage && !pastRequiredInstallationDate && isCameraOn() { - uiLog.info("Ignoring Nudge activation - Camera is currently on and not past required installation date") + LogManager.info("Ignoring Nudge activation - Camera is currently on and not past required installation date", logger: uiLog) return true } // Check if screen sharing is active and it's before the required installation date if OptionalFeatureVariables.acceptableScreenSharingUsage && !pastRequiredInstallationDate && isScreenSharingActive() { - uiLog.info("Ignoring Nudge activation - Screen sharing is currently active and not past required installation date") + LogManager.info("Ignoring Nudge activation - Screen sharing is currently active and not past required installation date", logger: uiLog) return true } @@ -363,23 +363,23 @@ private func updateNudgeState() { if nudgePrimaryState.deferralCountPastThreshold { if !nudgePrimaryState.hasLoggedDeferralCountPastThreshold { - uiLog.notice("allowedDeferrals has been passed") + LogManager.notice("allowedDeferrals has been passed", logger: uiLog) nudgePrimaryState.hasLoggedDeferralCountPastThreshold = true } } if nudgePrimaryState.userDeferrals > UserExperienceVariables.allowedDeferralsUntilForcedSecondaryQuitButton { if !nudgePrimaryState.hasLoggedDeferralCountPastThresholdDualQuitButtons { - uiLog.notice("allowedDeferralsUntilForcedSecondaryQuitButton has been passed: \(UserExperienceVariables.allowedDeferralsUntilForcedSecondaryQuitButton)") + LogManager.notice("allowedDeferralsUntilForcedSecondaryQuitButton has been passed: \(UserExperienceVariables.allowedDeferralsUntilForcedSecondaryQuitButton)", logger: uiLog) nudgePrimaryState.hasLoggedDeferralCountPastThresholdDualQuitButtons = true } } } func userHasClickedSecondaryQuitButton() { - uiLog.notice("User clicked secondaryQuitButton") + LogManager.notice("User clicked secondaryQuitButton", logger: uiLog) } func userHasClickedDeferralQuitButton(deferralTime: Date) { - uiLog.notice("User initiated a deferral: \(deferralTime)") + LogManager.notice("User initiated a deferral: \(deferralTime)", logger: uiLog) } diff --git a/Nudge/Utilities/Utils.swift b/Nudge/Utilities/Utils.swift index 9bfd318d..90cac559 100644 --- a/Nudge/Utilities/Utils.swift +++ b/Nudge/Utilities/Utils.swift @@ -16,7 +16,7 @@ import SystemConfiguration struct AppStateManager { func activateNudge() { - utilsLog.info("Activating Nudge") + LogManager.info("Activating Nudge", logger: utilsLog) nudgePrimaryState.lastRefreshTime = DateManager().getCurrentDate() guard let mainWindow = NSApp.windows.first else { return } @@ -29,7 +29,7 @@ struct AppStateManager { } if NSWorkspace.shared.isActiveSpaceFullScreen() && !nudgePrimaryState.afterFirstStateChange { - uiLog.notice("Bypassing activation due to full screen bugs in macOS") + LogManager.notice("Bypassing activation due to full screen bugs in macOS", logger: uiLog) } else { NSApp.activate(ignoringOtherApps: true) mainWindow.makeKeyAndOrderFront(nil) @@ -50,7 +50,7 @@ struct AppStateManager { private func applyBackgroundBlur(to window: NSWindow) { // load the blur background and send it to the back if we are past the required install date - uiLog.info("Enabling blurred background") + LogManager.info("Enabling blurred background", logger: uiLog) nudgePrimaryState.backgroundBlur.removeAll() UIConstants.screens.forEach { screen in let blurWindowController = BackgroundBlurWindowController() @@ -68,14 +68,14 @@ struct AppStateManager { if currentDate > PrefsWrapper.requiredInstallationDate || combinedGracePeriod > DateManager().getNumberOfHoursRemaining(currentDate: currentDate) { if UserExperienceVariables.gracePeriodLaunchDelay > gracePeriodPathCreationTimeInHours { - uiLog.info("Device within gracePeriodLaunchDelay, exiting Nudge") + LogManager.info("Device within gracePeriodLaunchDelay, exiting Nudge", logger: uiLog) nudgePrimaryState.shouldExit = true return currentDate } if UserExperienceVariables.gracePeriodInstallDelay > gracePeriodPathCreationTimeInHours { let newDate = gracePeriodPathCreationDate.addingTimeInterval(Double(combinedGracePeriod) * 3600) - uiLog.notice("Device permitted for gracePeriods - setting date to: \(newDate)") + LogManager.notice("Device permitted for gracePeriods - setting date to: \(newDate)", logger: uiLog) return newDate } } @@ -84,7 +84,7 @@ struct AppStateManager { } func exitNudge() { - uiLog.notice("Nudge is terminating due to condition met") + LogManager.notice("Nudge is terminating due to condition met", logger: uiLog) nudgePrimaryState.shouldExit = true exit(0) } @@ -102,7 +102,7 @@ struct AppStateManager { osStatus = SecStaticCodeCreateWithPath(Bundle.main.bundleURL as CFURL, [], &codeRef) guard osStatus == noErr, let code = codeRef else { - utilsLog.error("Failed to create static code: \(SecCopyErrorMessageString(osStatus, nil) as String? ?? "")") + LogManager.error("Failed to create static code: \(SecCopyErrorMessageString(osStatus, nil) as String? ?? "")", logger: utilsLog) return nil } @@ -110,19 +110,19 @@ struct AppStateManager { var codeInfoRef: CFDictionary? osStatus = SecCodeCopySigningInformation(code, flags, &codeInfoRef) guard osStatus == noErr, let codeInfo = codeInfoRef as? [String: Any] else { - utilsLog.error("Failed to copy code signing information: \(SecCopyErrorMessageString(osStatus, nil) as String? ?? "")") + LogManager.error("Failed to copy code signing information: \(SecCopyErrorMessageString(osStatus, nil) as String? ?? "")", logger: utilsLog) return nil } guard let teamIdentifier = codeInfo[kSecCodeInfoTeamIdentifier as String] as? String else { - utilsLog.error("No entry for team identifier in code signing info") + LogManager.error("No entry for team identifier in code signing info", logger: utilsLog) return nil } guard let certificates = codeInfo[kSecCodeInfoCertificates as String] as? [SecCertificate], let firstCertificate = certificates.first, let signingCertificateSummary = SecCertificateCopySubjectSummary(firstCertificate) as String? else { - utilsLog.error("Failed to get certificate summary - returning teamIdentifier") + LogManager.error("Failed to get certificate summary - returning teamIdentifier", logger: utilsLog) return teamIdentifier } @@ -138,7 +138,7 @@ struct AppStateManager { let gracePeriodPath = UserExperienceVariables.gracePeriodPath guard FileManager.default.fileExists(atPath: gracePeriodPath) || CommandLineUtilities().unitTestingEnabled(), let gracePeriodPathCreationDate = getCreationDateForPath(gracePeriodPath, testFileDate: testFileDate) else { - uiLog.error("Grace period path not found or unable to get creation date - bypassing allowGracePeriods logic") + LogManager.error("Grace period path not found or unable to get creation date - bypassing allowGracePeriods logic", logger: uiLog) return PrefsWrapper.requiredInstallationDate } @@ -152,14 +152,14 @@ struct AppStateManager { let hoursRemaining = DateManager().getNumberOfHoursRemaining() let isAllowed = hoursRemaining > threshold if !nudgeLogState.afterFirstRun { - uiLog.info("\(logMessage): \(isAllowed)") + LogManager.info("\(logMessage): \(isAllowed)", logger: uiLog) } return isAllowed } private func logOnce(_ message: String, state: inout Bool) { if !state { - uiLog.info("\(message)") + LogManager.info("\(message)", logger: uiLog) state = true } } @@ -270,7 +270,7 @@ struct CommandLineUtilities { func bundleModeEnabled() -> Bool { let argumentPassed = arguments.contains("-bundle-mode") if argumentPassed && !nudgeLogState.hasLoggedBundleMode { - uiLog.debug("-bundle-mode argument passed") + LogManager.debug("-bundle-mode argument passed", logger: uiLog) nudgeLogState.hasLoggedBundleMode = true } return argumentPassed @@ -279,7 +279,7 @@ struct CommandLineUtilities { func debugUIModeEnabled() -> Bool { let argumentPassed = arguments.contains("-debug-ui-mode") if argumentPassed && !nudgeLogState.afterFirstRun { - uiLog.debug("-debug-ui-mode argument passed") + LogManager.debug("-debug-ui-mode argument passed", logger: uiLog) } return argumentPassed } @@ -288,7 +288,7 @@ struct CommandLineUtilities { let argumentPassed = arguments.contains("-demo-mode") if argumentPassed && !nudgeLogState.hasLoggedDemoMode { nudgeLogState.hasLoggedDemoMode = true - uiLog.debug("-demo-mode argument passed") + LogManager.debug("-demo-mode argument passed", logger: uiLog) } return argumentPassed } @@ -297,7 +297,7 @@ struct CommandLineUtilities { let argumentPassed = arguments.contains("-force-screenshot-icon") if argumentPassed && !nudgeLogState.hasLoggedScreenshotIconMode { nudgeLogState.hasLoggedScreenshotIconMode = true - uiLog.debug("-force-screenshot-icon argument passed") + LogManager.debug("-force-screenshot-icon argument passed", logger: uiLog) } return argumentPassed } @@ -310,7 +310,7 @@ struct CommandLineUtilities { let argumentPassed = arguments.contains("-simple-mode") if argumentPassed && !nudgeLogState.hasLoggedSimpleMode { nudgeLogState.hasLoggedSimpleMode = true - uiLog.debug("-simple-mode argument passed") + LogManager.debug("-simple-mode argument passed", logger: uiLog) } return argumentPassed } @@ -320,7 +320,7 @@ struct CommandLineUtilities { if !nudgeLogState.hasLoggedUnitTestingMode { if argumentPassed { nudgeLogState.hasLoggedUnitTestingMode = true - uiLog.debug("-unit-testing argument passed") + LogManager.debug("-unit-testing argument passed", logger: uiLog) } } return argumentPassed @@ -333,7 +333,7 @@ struct CommandLineUtilities { func versionArgumentPassed() -> Bool { let argumentPassed = arguments.contains("-version") if argumentPassed { - uiLog.debug("-version argument passed") + LogManager.debug("-version argument passed", logger: uiLog) } return argumentPassed } @@ -360,7 +360,7 @@ struct ConfigurationManager { guard let nudgeJSONConfig = try? encoder.encode(Globals.nudgeJSONPreferences), let json = try? JSONSerialization.jsonObject(with: nudgeJSONConfig), let jsonData = try? JSONSerialization.data(withJSONObject: json, options: .prettyPrinted) else { - uiLog.error("Failed to serialize JSON configuration") + LogManager.error("Failed to serialize JSON configuration", logger: uiLog) return Data() } return jsonData @@ -376,7 +376,7 @@ struct ConfigurationManager { guard !nudgeProfileConfig.isEmpty, let plistData = try? PropertyListSerialization.data(fromPropertyList: nudgeProfileConfig, format: .xml, options: 0), let xmlPlistData = try? XMLDocument(data: plistData, options: .nodePreserveAll) else { - uiLog.error("Failed to serialize profile configuration") + LogManager.error("Failed to serialize profile configuration", logger: uiLog) return Data() } @@ -388,7 +388,7 @@ struct ConfigurationManager { let timerCycle = determineTimerCycle(basedOn: hoursRemaining) if timerCycle != nudgePrimaryState.timerCycle { - uiLog.info("timerCycle: \(timerCycle)") + LogManager.info("timerCycle: \(timerCycle)", logger: uiLog) nudgePrimaryState.timerCycle = timerCycle } return timerCycle @@ -452,7 +452,7 @@ struct DateManager { let isPast = getCurrentDate() > requiredInstallationDate if !CommandLineUtilities().demoModeEnabled() && !nudgeLogState.hasLoggedPastRequiredInstallationDate { nudgeLogState.hasLoggedPastRequiredInstallationDate = true - utilsLog.info("Device pastRequiredInstallationDate: \(isPast)") + LogManager.info("Device pastRequiredInstallationDate: \(isPast)", logger: utilsLog) } return isPast } @@ -478,13 +478,13 @@ struct DeviceManager { switch cpuArch { case Int(CPU_TYPE_X86) /* Intel */: - utilsLog.debug("CPU Type is Intel") + LogManager.debug("CPU Type is Intel", logger: utilsLog) return "Intel" case Int(CPU_TYPE_ARM) /* Apple Silicon */: - utilsLog.debug("CPU Type is Apple Silicon") + LogManager.debug("CPU Type is Apple Silicon", logger: utilsLog) return "Apple Silicon" default: - utilsLog.debug("Unknown CPU Type") + LogManager.debug("Unknown CPU Type", logger: utilsLog) return "unknown" } } @@ -499,7 +499,7 @@ struct DeviceManager { func getPatchOSVersion() -> Int { let PatchOSVersion = ProcessInfo().operatingSystemVersion.patchVersion - utilsLog.info("Patch OS Version: \(PatchOSVersion)") + LogManager.info("Patch OS Version: \(PatchOSVersion)", logger: utilsLog) return PatchOSVersion } @@ -526,7 +526,7 @@ struct DeviceManager { var uid: uid_t = 0 var gid: gid_t = 0 let username = SCDynamicStoreCopyConsoleUser(nil, &uid, &gid) as String? ?? "" - utilsLog.debug("System console username: \(username)") + LogManager.debug("System console username: \(username)", logger: utilsLog) return username } } @@ -542,12 +542,12 @@ struct ImageManager { let cleanBase64String = base64String.hasPrefix(base64Prefix) ? String(base64String.dropFirst(base64Prefix.count)) : base64String guard let imageData = Data(base64Encoded: cleanBase64String, options: .ignoreUnknownCharacters) else { - uiLog.error("Failed to decode base64 string to data") + LogManager.error("Failed to decode base64 string to data", logger: uiLog) return createErrorImage() } guard let image = NSImage(data: imageData) else { - uiLog.error("Failed to create image from decoded data") + LogManager.error("Failed to create image from decoded data", logger: uiLog) return createErrorImage() } @@ -556,7 +556,7 @@ struct ImageManager { func createImageData(fileImagePath: String) -> NSImage { guard let imageData = try? Data(contentsOf: URL(fileURLWithPath: fileImagePath)) else { - uiLog.error("Error accessing file \(fileImagePath). Incorrect permissions") + LogManager.error("Error accessing file \(fileImagePath). Incorrect permissions", logger: uiLog) return createErrorImage() } return NSImage(data: imageData) ?? createErrorImage() @@ -606,7 +606,7 @@ struct LoggerUtilities { } func userInitiatedDeviceInfo() { - uiLog.notice("User clicked deviceInfo") + LogManager.notice("User clicked deviceInfo", logger: uiLog) } } @@ -656,14 +656,14 @@ struct MemoizationManager { struct NetworkFileManager { private func decodeNudgePreferences(from url: URL) -> NudgePreferences? { guard let data = try? Data(contentsOf: url) else { - prefsJSONLog.error("Failed to load data from URL: \(url)") + LogManager.error("Failed to load data from URL: \(url)", logger: prefsJSONLog) return nil } do { return try NudgePreferences(data: data) } catch { - prefsJSONLog.error("Decoding error: \(error.localizedDescription)") + LogManager.error("Decoding error: \(error.localizedDescription)", logger: prefsJSONLog) return nil } } @@ -688,7 +688,7 @@ struct NetworkFileManager { func getNudgeJSONPreferences() -> NudgePreferences? { let url = getJSONUrl() - utilsLog.debug("JSON url: \(url)") + LogManager.debug("JSON url: \(url)", logger: utilsLog) if CommandLineUtilities().demoModeEnabled() || CommandLineUtilities().unitTestingEnabled() { return nil @@ -702,7 +702,7 @@ struct NetworkFileManager { return decodeNudgePreferences(from: jsonUrl) } - prefsJSONLog.error("Could not find or decode JSON configuration") + LogManager.error("Could not find or decode JSON configuration", logger: prefsJSONLog) return nil } } @@ -736,7 +736,7 @@ struct SMAppManager { print(message) if let code = exitCode { exit(Int32(code)) } } else { - osLog.info("\(message)") + LogManager.info("\(message)", logger: uiLog) } } @@ -772,7 +772,7 @@ struct UIUtilities { private func determineUpdateURL() -> URL? { if let actionButtonPath = FeatureVariables.actionButtonPath { if actionButtonPath.isEmpty { - utilsLog.warning("actionButtonPath is set but contains an empty string. No action will be triggered.") + LogManager.warning("actionButtonPath is set but contains an empty string. No action will be triggered.", logger: utilsLog) return nil } @@ -798,7 +798,7 @@ struct UIUtilities { func executeShellCommand(command: String, userClicked: Bool, configuration: NSWorkspace.OpenConfiguration) { let cmds = command.components(separatedBy: " ") guard let launchPath = cmds.first, let argument = cmds.last else { - uiLog.error("Invalid shell command format") + LogManager.error("Invalid shell command format", logger: uiLog) return } @@ -811,14 +811,14 @@ struct UIUtilities { do { try task.run() } catch { - uiLog.error("Error running script: \(error.localizedDescription)") + LogManager.error("Error running script: \(error.localizedDescription)", logger: uiLog) } } } else { do { try task.run() } catch { - uiLog.error("Error running script: \(error.localizedDescription)") + LogManager.error("Error running script: \(error.localizedDescription)", logger: uiLog) } } } @@ -832,20 +832,20 @@ struct UIUtilities { guard let url = URL(string: OSVersionRequirementVariables.aboutUpdateURL) else { return } - uiLog.notice("User clicked moreInfo button") + LogManager.notice("User clicked moreInfo button", logger: uiLog) NSWorkspace.shared.open(url) } private func postUpdateDeviceActions(userClicked: Bool) { if userClicked { - uiLog.notice("User clicked updateDevice") + LogManager.notice("User clicked updateDevice", logger: uiLog) // Remove forced blur and reset window level nudgePrimaryState.backgroundBlur.forEach { blurWindowController in blurWindowController.close() } NSApp.windows.first?.level = .normal } else { - uiLog.notice("Synthetically clicked updateDevice due to allowedDeferral count") + LogManager.notice("Synthetically clicked updateDevice due to allowedDeferral count", logger: uiLog) } } @@ -885,7 +885,7 @@ struct UIUtilities { } func userInitiatedExit() { - uiLog.notice("User clicked primaryQuitButton") + LogManager.notice("User clicked primaryQuitButton", logger: uiLog) nudgePrimaryState.shouldExit = true exit(0) } @@ -897,7 +897,7 @@ struct VersionManager { let requiredMinimumOSVersion = OSVersionRequirementVariables.requiredMinimumOSVersion let fullyUpdated = versionGreaterThanOrEqual(currentVersion: currentOSVersion, newVersion: requiredMinimumOSVersion) if fullyUpdated { - utilsLog.notice("Current operating system (\(currentOSVersion)) is greater than or equal to required operating system (\(requiredMinimumOSVersion))") + LogManager.notice("Current operating system (\(currentOSVersion)) is greater than or equal to required operating system (\(requiredMinimumOSVersion))", logger: utilsLog) return true } return false @@ -911,7 +911,7 @@ struct VersionManager { static func getMajorRequiredNudgeOSVersion() -> Int { guard let majorVersion = Int(OSVersionRequirementVariables.requiredMinimumOSVersion.split(separator: ".").first ?? "") else { - utilsLog.error("Invalid format for requiredMinimumOSVersion") + LogManager.error("Invalid format for requiredMinimumOSVersion", logger: utilsLog) return 0 } logOSVersion(majorVersion, for: "Major required OS version") @@ -929,7 +929,7 @@ struct VersionManager { } private static func logOSVersion(_ version: Int, for description: String) { - utilsLog.info("\(description): \(version)") + LogManager.info("\(description): \(version)", logger: utilsLog) } static func newNudgeEvent() -> Bool {