If I'm reading this guide correctly, macOS will automatically/implicitly startAccessingSecurityScopedResource for files opened via drag to Dock icon or NSOpenPanel.
And I'm expected to call stopAccessingSecurityScopedResource to balance it once I'm done. Does that mean that if I don't, I'm leaking kernel resources as per the docs?
If you fail to relinquish your access to file-system resources when you no longer need them, your app leaks kernel resources. If sufficient kernel resources leak, your app loses its ability to add file-system locations to its sandbox, such as with Powerbox or security-scoped bookmarks, until relaunched.
What is this limit in practice for macOS and iOS? I've seen number ranging from 1000-2500.
From my testing, iOS does not provide the same implicit startAccessingSecurityScopedResource when using UIDocumentPickerViewController. Is this a correct observation/per design?
Now, in the cases where I'm creating an NSURL by resolving a saved bookmark, I'm expected to explicitly startAccessingSecurityScopedResource.
Based on this, from what I can tell, this means that I can't universally call startAccessingSecurityScopedResource whenever I access a resource by URL, balanced with a stopAccessingSecurityScopedResource when done, as depending on how I got the URL it might already be implicitly started.
Is this a correct observation? Do I need to explicitly check whether I'm on iOS (never implicit?), or macOS (sometimes implicit?), and selectively startAccessingSecurityScopedResource based on every call site that may give me a security-scoped file? If so, is there a complete list of the entrypoints that may give me such files (file dialog, drag and drop, etc)?
Thanks!
OK, I had a conversation with a Foundation framework engineer and my colleague Kevin Elliott, and would like to confirm that the behavior the guide describes is right:
-
On iOS (and its variants), you need to call
startAccessingSecurityScopedResourcebefore accessing a URL from a file picker, and match with astopAccessingSecurityScopedResourcecall when you are done with the file. -
On macOS, you can access a URL from a file picker without calling
startAccessingSecurityScopedResourcebeforehand, but need to callstopAccessingSecurityScopedResourcewhen you are done with the file. This is so that existing code written before sandboxing being introduced can still consume URLs from a picker. Failing to callstopAccessingSecurityScopedResourcewill leak a security scope resource.
With this in mind, now to your questions:
From my testing, iOS does not provide the same implicit startAccessingSecurityScopedResource when using UIDocumentPickerViewController. Is this a correct observation/per design?
Correct.
Now, in the cases where I'm creating an NSURL by resolving a saved bookmark, I'm expected to explicitly startAccessingSecurityScopedResource.
Based on this, from what I can tell, this means that I can't universally call startAccessingSecurityScopedResource whenever I access a resource by URL, balanced with a stopAccessingSecurityScopedResource when done, as depending on how I got the URL it might already be implicitly started.
Is this a correct observation?
Correct.
Do I need to explicitly check whether I'm on iOS (never implicit?), or macOS (sometimes implicit?), and selectively startAccessingSecurityScopedResource based on every call site that may give me a security-scoped file?
Yeah, you will need an extra stopAccessingSecurityScopedResource call on macOS. Here is an example flow that makes the URL access structured:
- Call
startAccessingSecurityScopedResourceon a picked URL. - Convert the URL to a piece of security scoped bookmark data using bookmarkData(options:includingResourceValuesForKeys:relativeTo:).
- Call
stopAccessingSecurityScopedResourceto match step 1. - On macOS, call
stopAccessingSecurityScopedResourceagain to release the resource implicitly started by the picker.
From now on, when you need to use the URL, create it with the bookmark data (init(resolvingBookmarkData:options:relativeTo:bookmarkDataIsStale:), and use start/stopAccessingSecurityScopedResource to access it.
Best,
——
Ziqiao Chen
Worldwide Developer Relations.