Skip to content

Conversation

@onehumandev
Copy link
Contributor

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:

  1. A copy of the file needs to be made to the internal app sandbox
  2. 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 calling startAccessingSecurityScopedResource.

This is called by startFileAccess in the TS API, and when done accessing the file, endFileAccess should be called.

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.

@onehumandev onehumandev requested a review from a team as a code owner December 1, 2025 15:32
@onehumandev
Copy link
Contributor Author

c. @velocitysystems Here is the MR for the changes to support startAccessingSecurityScopedResource for working with Cloud providers without requiring making a local copy of the file. Thanks!

…i-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:
1) A copy of the file needs to be made to the internal app sandbox
2) 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 calling `startAccessingSecurityScopedResource`.

This is called by `startFileAccess` in the TS API, and when done accessing the file,
`endFileAccess` should be called.

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.
@onehumandev onehumandev force-pushed the aldewaal/ios_security_scoping branch from d4c8e4b to 749a149 Compare December 2, 2025 20:00
@velocitysystems
Copy link
Contributor

Thanks @onehumandev (and for your comments in #3716).
Will review this PR and leave comments below.


// Dictionary to keep strong references to URLs with active security-scoped access
// Key: resource ID (UUID string), Value: URL object
private var activeSecurityScopedURLs: [String: URL] = [:]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possible race condition: activeSecurityScopedURLs dictionary is accessed from multiple threads (main thread via invoke handlers, potentially background threads) without synchronization.

Can we make this thread-safe?

} else {
// Resource ID not found - might have already been cleaned up or never existed
// This is not necessarily an error, so we'll return success
invoke.resolve(["success": true])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could mask bugs where developers pass incorrect resource IDs. Should we at least log a warning?


#[command]
pub(crate) async fn end_file_access<R: Runtime>(
_window: Window<R>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_window is unused here.

}
}

@objc public func endFileAccess(_ invoke: Invoke) throws {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iOS may revoke security-scoped access when the app backgrounds. The current implementation doesn't handle this scenario. Should document this limitation and/or handle it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants