SwiftUI macOS应用中何时调用stopAccessingSecurityScopedResource?
关于安全作用域URL的退出处理方案
是的,在应用退出时调用stopAccessingSecurityScopedResource()是符合你场景的合理方案——既然你的应用在运行全程都需要访问这些资源,保持访问直到应用终止是合适的,只要严格遵守“每次startAccessingSecurityScopedResource()对应一次stopAccessingSecurityScopedResource()”的要求即可。
如何在SwiftUI macOS应用关闭时调用该方法
方法1:通过AppDelegate全局管理
这种方式适合统一管控所有需要长期访问的安全作用域URL:
- 定义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)") } } } }
- 在App结构体中注入该委托:
import SwiftUI @main struct YourMacApp: App { @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate var body: some Scene { WindowGroup { ContentView() .environmentObject(appDelegate) // 传递给视图以便添加URL } } }
- 在启动访问资源的地方,将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
相关产品推荐
相关产品推荐

