SwiftUI如何阻止应用进程重启恢复到之前的状态

原创 吴就业 61 0 2024-09-02

本文为博主原创文章,未经博主允许不得转载。

本文链接:https://wujiuye.com/article/47fb81764b4440ce855192fc31e2cc0e

作者:吴就业
链接:https://wujiuye.com/article/47fb81764b4440ce855192fc31e2cc0e
来源:吴就业的网络日记
本文为博主原创文章,未经博主允许不得转载。

当我们在macos上打开一个app,我们操作app打开了一堆窗口,如果这个时候我们不关闭这些窗口,而是直接退出应用。那么默认情况下,我们再次启动时,macos就会恢复打开上次使用的窗口。这种情况在xcode开发应用我们调试应用的过程中最容易出现。

假如你不希望你的应用重启时,恢复到上次用户打开的窗口,而是想每次都从启动页开始。那么怎么做呢?

通过摸索尝试n次后,我找到了一种可行的方法。

先来理解macos是怎么恢复一个应用的:

当我们操作app打开一些窗口时,macos会在~/Library/Containers/{your app bundleIdentifier}/Data/Library/Saved Application State/目录下,以你应用的bundleIdentifier加“.savedState”创建一个用于存储应用状态的目录:~/Library/Containers/{your app bundleIdentifier}/Data/Library/Saved Application State/{your app bundleIdentifier}.savedState,然后在这个目录下存储应用的状态。

我们只需要在适当的时候,删除这个目录就可以。

class MyAppDelegate: NSObject, NSApplicationDelegate {
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        print("applicationDidFinishLaunching")
        // 在这里删除没用,此时已经读取了,还是会恢复状态
        // clearSavedApplicationState()
    }

    // 是否在最后一个窗口关闭后终止进程
    func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
        // 不终止进程,只是清理一下状态
        print("applicationShouldTerminateAfterLastWindowClosed")
        clearSavedApplicationState()
        return false
    }

    func applicationWillTerminate(_ aNotification: Notification) {
        print("applicationWillTerminate")
        clearSavedApplicationState()
    }

    // 删除状态文件,阻止下次启动应用还恢复之前的窗口
    func clearSavedApplicationState() {
        // 获取应用程序的 bundle identifier
        let bundleIdentifier = Bundle.main.bundleIdentifier!
        // 构建 Saved Application State 目录的路径
        let savedStateDirectory = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask)[0]
        let savedStatePath = savedStateDirectory.appendingPathComponent("Saved Application State").appendingPathComponent("\(bundleIdentifier).savedState").path
        // 检查文件夹是否存在
        if FileManager.default.fileExists(atPath: savedStatePath) {
            do {
                // 尝试删除文件夹及其内容
                try FileManager.default.removeItem(atPath: savedStatePath)
                print("Saved application state cleared successfully.")
            } catch {
                // 如果删除失败,打印错误信息
                print("Error clearing saved application state: \(error)")
            }
        } else {
            print("Saved application state directory \(savedStatePath) does not exist.")
        }
    }
}

@main
struct MyApp: App {
    @NSApplicationDelegateAdaptor(MyAppDelegate.self) var appDelegate: MyAppDelegate
		......
}

你可能关心的点:

  1. 本地xcode开发启动应用,也是这个目录,跟应用发布后是一致的,至少在macOS14.x版本的系统上验证是这个结论。
  2. 关于沙盒环境下有没有权限删除这个目录,实测是成功的。

此篇文章的结论都是我在应用发版后确认得出。

#前端

声明:公众号、CSDN、掘金的曾用名:“Java艺术”,因此您可能看到一些早期的文章的图片有“Java艺术”的水印。

文章推荐

SwiftUI原生Chart组件如何实现鼠标移动选中才显示数值

使用SwiftUI的原生Chart组件,堆叠柱形图如何实现像网站使用ercharts实现的鼠标移动到柱状图上面才弹窗显示对应数值的效果。

微信小程序原生开发获取input光标位置和监听光标位置改变问题

input失去焦点后,用户点击input重新获取焦点,怎么获取光标位置?如果用户获取到焦点之后,没有输入,而是移动光标,怎么获取移动后的光标位置呢?

SwiftUI开发macOS APP,如何自定义标题栏(TitleBar)

macOS APP应用的标题栏(TitleBar)是指包含“交通信号灯”(红黄绿三个小按钮)的一栏,通常TitleBar只包括“交通信号灯”和一个title,使用SwiftUI开发macOS APP,怎么把TitleBar隐藏掉呢?

如何将macOS app发布到app store?

开发完一个macOS app之后,我们应该如何将其发布到app store呢?这个文档记录了笔者从零开始一步步学习将自己开发好的macOS app发布到app store的过程。

如何编译构建一个同时支持多cpu架构的静态链接库(.a文件)

我想要让自己的mac OS应用支持更多用户可以使用,就必须要打出一个能同在amd64架构cpu的mac os设备上运行,也需要能在arm64架构cpu的mac os设备上运行。

使用node:alpine基础镜像今天突然就构建不了了

我的一个nextjs项目使用node:alpine基础镜像,在此之前部署到线上都能正常构建和运行,今天修改点代码提交到生产环境,发现竟然镜像构建失败了。