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

SwiftUI macOS应用中何时调用stopAccessingSecurityScopedResource?

关于安全作用域URL的退出处理方案

是的,在应用退出时调用stopAccessingSecurityScopedResource()是符合你场景的合理方案——既然你的应用在运行全程都需要访问这些资源,保持访问直到应用终止是合适的,只要严格遵守“每次startAccessingSecurityScopedResource()对应一次stopAccessingSecurityScopedResource()”的要求即可。

如何在SwiftUI macOS应用关闭时调用该方法

方法1:通过AppDelegate全局管理

这种方式适合统一管控所有需要长期访问的安全作用域URL:

  1. 定义AppDelegate类,实现应用终止回调:
import Cocoa

class AppDelegate: NSObject, NSApplicationDelegate {
    // 存储所有需要跟踪的安全作用域URL
    var trackedSecurityURLs: [URL] = []
    
    func applicationWillTerminate(_ notification: Notification) {
        // 遍历所有URL,执行停止访问操作
        trackedSecurityURLs.forEach { url in
            if url.startAccessingSecurityScopedResource() {
                url.stopAccessingSecurityScopedResource()
                print("stopAccessingSecurityScopedResource: \(url)")
            }
        }
    }
}
  1. 在App结构体中注入该委托:
import SwiftUI

@main
struct YourMacApp: App {
    @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(appDelegate) // 传递给视图以便添加URL
        }
    }
}
  1. 在启动访问资源的地方,将URL加入跟踪列表:
import SwiftUI

struct ContentView: View {
    @EnvironmentObject var appDelegate: AppDelegate
    
    func startAccessingResource(_ restoredURL: URL) {
        if restoredURL.startAccessingSecurityScopedResource() {
            print("startAccessingSecurityScopedResource: \(restoredURL)")
            // 添加到跟踪列表,确保退出时能被处理
            appDelegate.trackedSecurityURLs.append(restoredURL)
        }
    }
}

方法2:直接监听应用终止通知

如果不需要全局管理,也可以在视图中直接监听系统通知:

import SwiftUI

struct ContentView: View {
    @State private var activeSecurityURLs: [URL] = []
    
    var body: some View {
        Text("Your App Content")
            .onAppear {
                // 示例:启动访问资源
                let restoredURL: URL = // 你的URL来源
                if restoredURL.startAccessingSecurityScopedResource() {
                    print("startAccessingSecurityScopedResource: \(restoredURL)")
                    activeSecurityURLs.append(restoredURL)
                }
                
                // 监听应用即将终止的通知
                NotificationCenter.default.addObserver(
                    forName: NSApplication.willTerminateNotification,
                    object: nil,
                    queue: .main
                ) { _ in
                    activeSecurityURLs.forEach { url in
                        if url.startAccessingSecurityScopedResource() {
                            url.stopAccessingSecurityScopedResource()
                            print("stopAccessingSecurityScopedResource: \(url)")
                        }
                    }
                }
            }
    }
}

注意事项

  • 如果你的应用存在临时访问资源的场景(比如单次读取文件后就不再需要),要在操作完成后立即调用stopAccessingSecurityScopedResource(),仅把长期需要的URL留到应用退出时处理。
  • 建议用全局状态容器(比如ObservableObject)统一管理所有安全作用域URL,避免因多窗口/场景导致的遗漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:05:04