feat(fs): access security scoped resources on iOS#3185
Conversation
Package Changes Through 526e2e1There are 10 changes which include fs with minor, fs-js with minor, http with patch, http-js with patch, updater with patch, updater-js with patch, dialog with minor, dialog-js with minor, deep-link with patch, deep-link-js with patch Planned Package VersionsThe following package releases are the planned based on the context of changes in this pull request.
Add another change file through the GitHub UI by following this link. Read about change files or the docs at github.com/jbolda/covector |
| // the file handle needs to remain accessible while the File is in use. | ||
| // The access will be automatically stopped when the app is backgrounded or terminated. | ||
| unsafe { | ||
| let _ = ns_url.startAccessingSecurityScopedResource(); |
There was a problem hiding this comment.
The return value indicates whether the URL is actually a security-scoped resource. Ignoring it means:
- No way to know if the call was necessary
- No error handling if the resource can't be accessed
Recommendation: Check the return value and potentially log/warn if it returns false for a URL that was expected to be security-scoped.
| // This is required for files outside the app's sandbox (e.g., from file picker) | ||
| // Note: We don't call stopAccessingSecurityScopedResource here because | ||
| // the file handle needs to remain accessible while the File is in use. | ||
| // The access will be automatically stopped when the app is backgrounded or terminated. |
There was a problem hiding this comment.
This comment is not entirely correct. Apple's documentation states: "You must balance every call to this method with a call to stopAccessingSecurityScopedResource()."
While the OS will eventually reclaim resources on termination, this doesn't constitute proper resource management for several reasons:
- Resource exhaustion — The system limits how many security-scoped resources can be active
- Long-running apps — Apps that stay active may accumulate leaked handles.
- Bookmark invalidation — Improperly managed access can contribute to security-scoped bookmark staleness.
Recommendation: Consider implementing RAII-style cleanup or at minimum document the requirement to call stopAccessingSecurityScopedResource() explicitly.
There was a problem hiding this comment.
direct cleanup can't be implemented without breaking changes in this case :/ we'll have to update the docs
There was a problem hiding this comment.
direct cleanup can't be implemented without breaking changes in this case
How would these look like? Mind adding a TODO comment (or issue) so we can follow up in v3? Edit: or would it be too ugly and therefore won't be implemented?
|
@onehumandev Can you please take a look at this and compare with changes in PR 3136? |
|
c. @velocitysystems Short version: AFAIK, for Long version: This means that For In other words, it would essentially be an "open mode"; either "copy" (the current production behavior) or "scoped" (which would include a call to PR #3136 includes these changes; however, if that is not the path the project would like to take, I am happy to help with whatever alternative is preferred :) Further explanation, from comment in above linked PR: |
|
@onehumandev I love the dialog plugin changes you suggested. What I don't really agree with is adding startFileAccess and endFileAccess to the dialog plugin - the same mechanism will be required to e.g. read file association input. That's why I decided to make some changes to the filesystem plugin instead. If you can drop the file access APIs from your PR I can merge it to include the changes required to not create a file copy on the dialog APIs. |
On iOS, when trying to access a file that exists outside of the app sandbox, one of 2 things need to happen to be able to perform any operations on said file: * A copy of the file needs to be made to the internal app sandbox * The method startAccessingSecurityScopedResource needs to be called. Previously, a copy of the file was always being made when a file was selected through the picker dialog. While this did ensure there were no file access exceptions when reading from the file, it does not scale well for large files. To resolve this, we now support `fileAccessMode`, which allows a file handle to be returned without copying the file to the app sandbox. This MR only supports this change for iOS; MacOS has a different set of needs for security scoped resources. See discussion in #3716 for more discussion of the difference between iOS and MacOS. See MR tauri-apps#3185 to see how these scoped files will be accessible using security scoping.
On iOS, when trying to access a file that exists outside of the app sandbox, one of 2 things need to happen to be able to perform any operations on said file: * A copy of the file needs to be made to the internal app sandbox * The method startAccessingSecurityScopedResource needs to be called. Previously, a copy of the file was always being made when a file was selected through the picker dialog. While this did ensure there were no file access exceptions when reading from the file, it does not scale well for large files. To resolve this, we now support `fileAccessMode`, which allows a file handle to be returned without copying the file to the app sandbox. This MR only supports this change for iOS; MacOS has a different set of needs for security scoped resources. See discussion in #3716 for more discussion of the difference between iOS and MacOS. See MR tauri-apps#3185 to see how these scoped files will be accessible using security scoping.
|
@lucasfernog Sounds good; updated #3136 in accord with latest comments |
|
Thanks @lucasfernog @onehumandev. I think this is a great solution all around. 🎉 So...We have new APIs for handling security scoped resources available in the |
* feat(dialog) - Support fileAccessMode for open dialog (#3030) On iOS, when trying to access a file that exists outside of the app sandbox, one of 2 things need to happen to be able to perform any operations on said file: * A copy of the file needs to be made to the internal app sandbox * The method startAccessingSecurityScopedResource needs to be called. Previously, a copy of the file was always being made when a file was selected through the picker dialog. While this did ensure there were no file access exceptions when reading from the file, it does not scale well for large files. To resolve this, we now support `fileAccessMode`, which allows a file handle to be returned without copying the file to the app sandbox. This MR only supports this change for iOS; MacOS has a different set of needs for security scoped resources. See discussion in #3716 for more discussion of the difference between iOS and MacOS. See MR #3185 to see how these scoped files will be accessible using security scoping. * fmt, clippy * use enum --------- Co-authored-by: Lucas Nogueira <lucas@tauri.app>
velocitysystems
left a comment
There was a problem hiding this comment.
Looks good @lucasfernog. Please see my above comment. What further changes are required in the dialog plugin to make this work with this functionality in the fs plugin?
cc: @onehumandev
I will deep dive into this tomorrow and Friday and make sure everything works as expected, and if there are any wires needing connecting. |
@velocitysystems I tried this branch with #3136 and seems like everything is working fine now. Should be good to go. |
@velocitysystems Confirmed; I tested it locally as well with our current use cases, and all works as expected. |
… (tauri-apps#3136) * feat(dialog) - Support fileAccessMode for open dialog (tauri-apps#3030) On iOS, when trying to access a file that exists outside of the app sandbox, one of 2 things need to happen to be able to perform any operations on said file: * A copy of the file needs to be made to the internal app sandbox * The method startAccessingSecurityScopedResource needs to be called. Previously, a copy of the file was always being made when a file was selected through the picker dialog. While this did ensure there were no file access exceptions when reading from the file, it does not scale well for large files. To resolve this, we now support `fileAccessMode`, which allows a file handle to be returned without copying the file to the app sandbox. This MR only supports this change for iOS; MacOS has a different set of needs for security scoped resources. See discussion in #3716 for more discussion of the difference between iOS and MacOS. See MR tauri-apps#3185 to see how these scoped files will be accessible using security scoping. * fmt, clippy * use enum --------- Co-authored-by: Lucas Nogueira <lucas@tauri.app>
Add iOS security-scoped resource support
Summary
Adds support for handling security-scoped URLs on iOS, enabling access to files outside the app's sandbox (e.g., files selected via file picker).
Changes
open()method inios.rsnow automatically callsstartAccessingSecurityScopedResource()when opening files viafile://URLsstopAccessingSecurityScopedResource()command and guest-js binding to manually stop accessing security-scoped resources when doneresolve_path()to start accessing security-scoped resources early in the path resolution processmobile.rsinto separateios.rsandandroid.rsfiles for better maintainabilityobjc2-foundationdependency for iOS to interact with NSURL APIsPlatform-specific behavior
Breaking changes
None.