You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
Copy file name to clipboardExpand all lines: plugins/dialog/guest-js/index.ts
+35Lines changed: 35 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -76,6 +76,31 @@ interface OpenDialogOptions {
76
76
* On desktop, this option is ignored.
77
77
*/
78
78
pickerMode?: PickerMode
79
+
/**
80
+
* The file access mode of the dialog.
81
+
* If not provided, `copy` is used, which matches the behavior of the {@linkcode open} method before the introduction of this option.
82
+
*
83
+
* **Usage**
84
+
* If a file is opened with {@linkcode fileAccessMode: 'copy'}, it will be copied to the app's sandbox.
85
+
* This means the file can be read, edited, deleted, copied, or any other operation without any issues, since the file
86
+
* now belongs to the app.
87
+
* This also means that the caller has responsibility of deleting the file if this file is not meant to be retained
88
+
* in the app sandbox.
89
+
*
90
+
* If a file is opened with {@linkcode fileAccessMode: 'scoped'}, the file will remain in its original location
91
+
* and security-scoped access will be automatically managed by the system.
92
+
*
93
+
* **Note**
94
+
* This is specifically meant for document pickers on iOS or MacOS, in conjunction with [security scoped resources](https://developer.apple.com/documentation/foundation/nsurl/startaccessingsecurityscopedresource()).
95
+
*
96
+
* Why only document pickers, and not image or video pickers?
97
+
* The image and video pickers on iOS behave differently from the document pickers, and return [NSItemProvider](https://developer.apple.com/documentation/foundation/nsitemprovider) objects instead of file URLs.
98
+
* These are meant to be ephemeral (only available within the callback of the picker), and are not accessible outside of the callback.
99
+
* So for image and video pickers, the only way to access the file is to copy it to the app's sandbox, and this is the URL that is returned from this API.
100
+
* This means there is no provision for using `scoped` mode with image or video pickers.
101
+
* If an image or video picker is used, `copy` is always used.
Copy file name to clipboardExpand all lines: plugins/dialog/ios/Sources/FilePickerController.swift
+23-3Lines changed: 23 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -95,16 +95,33 @@ public class FilePickerController: NSObject {
95
95
returnnil
96
96
}
97
97
}
98
-
98
+
99
+
/// ## In which cases do we need to save a copy of a file selected by a user to the app sandbox?
100
+
/// In short, only when the file is **not** selected using UIDocumentPickerDelegate.
101
+
/// For the rest of the cases, we need to write a copy of the file to the app sandbox.
102
+
///
103
+
/// For PHPicker (used for photos and videos), `NSItemProvider.loadFileRepresentation` returns a temporary file URL that is deleted after the completion handler.
104
+
/// The recommendation is to [Persist](https://developer.apple.com/documentation/foundation/nsitemprovider/2888338-loadfilerepresentation) the file by moving/copying
105
+
/// it to your app’s directory within the completion handler.
106
+
///
107
+
/// If available, `loadInPlaceFileRepresentation` can open a file in place; Photos assets typically do not support true in-place access,
// We have to make a copy of the file to the app sandbox here, as PHPicker returns an NSItemProvider with either an ephemeral file URL or content that is deleted after the completion handler.
211
+
// This is a different behavior from UIDocumentPicker, where the file can either be copied to the app sandbox or opened in place, and then accessed with `startAccessingSecurityScopedResource`.
// We have to make a copy of the file to the app sandbox here, as PHPicker returns an NSItemProvider with either an ephemeral file URL or content that is deleted after the completion handler.
234
+
// This is a different behavior from UIDocumentPicker, where the file can either be copied to the app sandbox or opened in place, and then accessed with `startAccessingSecurityScopedResource`.
0 commit comments