You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Swift/Objective-C获取macOS系统重启与系统更新的通知并执行后续操作?

嘿,这个需求在macOS开发里挺常见的,我来给你拆解清楚怎么实现👇

一、检测系统重启完成的通知

系统重启的检测分为两种场景:App运行时监听即将重启的信号,以及重启后App启动时判断是否刚完成重启。

1. 运行时监听系统即将重启的通知

你可以通过NSWorkspace提供的通知来捕获系统即将重启的事件,提前记录标记,方便重启后执行操作。

Swift 实现

// 在App启动阶段注册监听(比如AppDelegate的applicationDidFinishLaunching里)
NotificationCenter.default.addObserver(forName: NSWorkspace.willRestartNotification, 
                                       object: NSWorkspace.shared, 
                                       queue: .main) { _ in
    // 把重启标记存入UserDefaults,重启后App启动时读取
    UserDefaults.standard.set(true, forKey: "didTriggerSystemRestart")
}

Objective-C 实现

// 在AppDelegate的applicationDidFinishLaunching方法中注册监听
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(handleSystemRestart:)
                                             name:NSWorkspaceWillRestartNotification
                                           object:[NSWorkspace sharedWorkspace]];

// 实现通知处理方法
- (void)handleSystemRestart:(NSNotification *)notification {
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"didTriggerSystemRestart"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

2. 重启完成后执行操作(App启动时)

如果你的App设置了开机自启,重启后会自动启动,这时候读取之前存的标记就能判断是否刚完成重启:

Swift 实现

func applicationDidFinishLaunching(_ aNotification: Notification) {
    let didRestart = UserDefaults.standard.bool(forKey: "didTriggerSystemRestart")
    if didRestart {
        // 这里执行你需要的操作,比如同步数据、弹窗提示等
        print("系统刚完成重启,执行后续操作")
        // 记得清除标记,避免下次启动重复执行
        UserDefaults.standard.set(false, forKey: "didTriggerSystemRestart")
    }
}

Objective-C 实现

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    BOOL didRestart = [[NSUserDefaults standardUserDefaults] boolForKey:@"didTriggerSystemRestart"];
    if (didRestart) {
        NSLog(@"系统刚完成重启,执行后续操作");
        // 执行你的业务逻辑
        [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"didTriggerSystemRestart"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
}

备选方案:通过系统启动时间判断

如果你的App没有开机自启,下次手动启动时可以对比系统启动时间和App上次退出时间,来判断是否经历过重启:

Swift 实现

// 获取系统启动时间
func getSystemBootTime() -> Date? {
    var tv = timeval()
    var size = MemoryLayout<timeval>.stride
    let result = sysctlbyname("kern.boottime", &tv, &size, nil, 0)
    guard result == 0 else { return nil }
    return Date(timeIntervalSince1970: Double(tv.tv_sec) + Double(tv.tv_usec)/1_000_000)
}

// 在applicationDidFinishLaunching中判断
func applicationDidFinishLaunching(_ aNotification: Notification) {
    guard let bootTime = getSystemBootTime(), 
          let lastQuitTime = UserDefaults.standard.object(forKey: "lastAppQuitTime") as? Date else {
        // 首次启动,记录当前时间
        UserDefaults.standard.set(Date(), forKey: "lastAppQuitTime")
        return
    }
    
    if bootTime > lastQuitTime {
        print("系统刚完成重启,执行操作")
    }
}

// 在App退出时记录时间
func applicationWillTerminate(_ aNotification: Notification) {
    UserDefaults.standard.set(Date(), forKey: "lastAppQuitTime")
}
二、检测系统更新完成的通知

系统更新的检测可以通过监听系统分布式通知,或者对比系统版本变化来实现,两种方式结合更可靠。

1. 监听系统更新完成的分布式通知

macOS的软件更新服务会发送分布式通知,你可以通过DistributedNotificationCenter监听:

Swift 实现

// 在App启动时注册监听
DistributedNotificationCenter.default().addObserver(forName: NSNotification.Name("com.apple.SoftwareUpdate.NotifyUpdateInstalled"), 
                                                    object: nil, 
                                                    queue: .main) { _ in
    print("系统更新已完成,执行后续操作")
    // 这里写你的业务逻辑
}

Objective-C 实现

// 在AppDelegate的applicationDidFinishLaunching中注册
[[NSDistributedNotificationCenter defaultCenter] addObserver:self
                                                    selector:@selector(handleUpdateInstalled:)
                                                        name:@"com.apple.SoftwareUpdate.NotifyUpdateInstalled"
                                                      object:nil];

// 实现处理方法
- (void)handleUpdateInstalled:(NSNotification *)notification {
    NSLog(@"系统更新已完成,执行后续操作");
    // 执行你的操作
}

2. 通过系统版本变化判断更新完成

有些更新可能不会触发通知(比如小版本更新),这时候可以记录上次运行时的系统版本,下次启动时对比:

Swift 实现

func applicationDidFinishLaunching(_ aNotification: Notification) {
    let currentOSVersion = ProcessInfo.processInfo.operatingSystemVersionString
    let lastOSVersion = UserDefaults.standard.string(forKey: "lastRecordedOSVersion")
    
    if let lastVersion = lastOSVersion, lastVersion != currentOSVersion {
        print("系统已更新,执行操作")
    }
    // 更新记录的版本
    UserDefaults.standard.set(currentOSVersion, forKey: "lastRecordedOSVersion")
}

Objective-C 实现

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    NSString *currentOSVersion = [[NSProcessInfo processInfo] operatingSystemVersionString];
    NSString *lastOSVersion = [[NSUserDefaults standardUserDefaults] stringForKey:@"lastRecordedOSVersion"];
    
    if (lastOSVersion && ![lastOSVersion isEqualToString:currentOSVersion]) {
        NSLog(@"系统已更新,执行操作");
    }
    [[NSUserDefaults standardUserDefaults] setObject:currentOSVersion forKey:@"lastRecordedOSVersion"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}
三、一些重要注意事项
  • 如果要在重启后自动执行操作,务必确保你的App已添加到系统设置的登录项中(系统设置 > 通用 > 登录项),否则重启后App不会自动启动。
  • 分布式通知可能存在延迟或遗漏,建议结合版本对比的方式,提升检测的可靠性。
  • 记得在App退出时移除通知观察者,避免内存泄漏(比如在applicationWillTerminate中调用removeObserver:)。

内容的提问来源于stack exchange,提问作者Ajay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 19:59:08