1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ffi::*;
use core::ptr::NonNull;
use objc2::__framework_prelude::*;
use objc2_foundation::*;
use crate::*;
/// [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderextensionactionidentifier?language=objc)
// NS_TYPED_EXTENSIBLE_ENUM
pub type NSFileProviderExtensionActionIdentifier = NSString;
/// NSFileProviderActions.
///
/// This category encapsulates common user-driven actions on FileProvider's items.
#[cfg(feature = "Extension")]
impl NSFileProviderExtension {
extern_methods!(
#[cfg(all(feature = "NSFileProviderItem", feature = "block2"))]
/// Import a document.
///
/// The file or package at fileURL should be moved on disk into the file provider's
/// own storage, where it will later be uploaded. The completion block should be
/// executed after the move on disk, but before the upload. Before doing any
/// network, actually.
///
/// In the completion block, importedDocumentItem should have these properties set:
/// - itemIdentifier
/// - parentItemIdentifier (to the value passed in to this method)
/// - filename (to fileURL's resource value for key NSURLNameKey)
/// - creationDate (to NSURLCreationDateKey)
/// - contentModificationDate (to NSURLContentModificationDateKey)
/// - contentType (to NSURLContentTypeKey)
/// - documentSize (to NSURLTotalFileSizeKey on a flat file, or to the sum of the
/// files sizes for a package)
/// - capabilities
///
/// [fileURL startAccessingSecurityScopedResource] needs to be called prior to
/// accessing this security scoped URL, and stopAccessingSecurityScopedResource
/// needs to be called when done.
///
/// Note that itemIdentifier should be set with no network call. It doesn't have
/// to be the final identifier. If the identifier changes after talking to the
/// server then the file provider should send a delete for the temporary, local
/// identifier immediately followed by an add with the final identifier.
///
/// A reasonable way of organizing files in the file provider storage is:
/// <file
/// provider storage path>/
/// <itemIdentifier
/// >/
/// <filename
/// >.
/// <extension
/// >
/// If the item identifier was to change, you should move the file on disk to
/// update its path, under coordination with NSFileCoordinatorWritingForMoving.
///
/// This is expected to work offline even if there might be a collision (another
/// item with the same filename and parentItemIdentifier) only detected when later
/// syncing up this change to the server. In that case, it is suggested that a
/// follow up update to the item change its filename to something unique. This
/// wouldn't be considered an error to import.
///
/// If however you can tell right away, with no communication to your server, that
/// there is a collision then this call should fail with error code
/// NSFileProviderErrorFilenameCollision generated with this method:
/// -[NSError (NSFileProviderError) fileProviderErrorForCollisionWithItem:].
///
/// The existing item set in this error will be used to handle the collision, and
/// ask the user if she or he would like to replace the existing item. This takes
/// into account the existing item's capabilities (particularly
/// NSFileProviderItemCapabilitiesAllowsTrashing and AllowsDeleting.)
///
/// Collision checks should be case insensitive even if the filesystem or file
/// provider might allow two coexisting filenames differing only by their case.
///
/// Upload errors (such as NSFileProviderErrorInsufficientQuota) should be handled
/// with a subsequent update to the item, setting its uploadingError property.
/// Upload errors should not prevent creating or importing a document, because they
/// can be resolved at a later date (for example, when the user has quota again.)
///
/// Other errors will be presented to the user, but are unexpected. If you want to
/// prevent imports in a given directory, then the directory item's capacities
/// should exclude NSFileProviderItemCapabilitiesAllowsAddingSubItems.
#[unsafe(method(importDocumentAtURL:toParentItemIdentifier:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn importDocumentAtURL_toParentItemIdentifier_completionHandler(
&self,
file_url: &NSURL,
parent_item_identifier: &NSFileProviderItemIdentifier,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSFileProviderItem, *mut NSError)>,
);
#[cfg(all(feature = "NSFileProviderItem", feature = "block2"))]
/// Create a directory.
///
/// This is expected to complete before doing any network.
///
/// In the completion block, createdDirectoryItem should have these properties set:
/// - itemIdentifier
/// - parentItemIdentifier (to the value passed in to this method)
/// - filename (to directoryName)
/// - creationDate (to the current date and time)
/// - contentType (to "public.folder" - UTTypeFolder)
/// - childItemCount (to 0)
/// - capabilities
///
/// Errors (including collision errors) are handled as documented for the import
/// method above. Directory creation is gated by the capabilities of the
/// destination directory, with NSFileProviderItemCapabilitiesAllowsAddingSubItems.
#[unsafe(method(createDirectoryWithName:inParentItemIdentifier:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn createDirectoryWithName_inParentItemIdentifier_completionHandler(
&self,
directory_name: &NSString,
parent_item_identifier: &NSFileProviderItemIdentifier,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSFileProviderItem, *mut NSError)>,
);
#[cfg(all(feature = "NSFileProviderItem", feature = "block2"))]
/// Rename a document or a directory.
///
/// This is expected to complete before doing any network.
///
/// itemName is the full file or directory name, complete with its file extension.
/// In the completion block, property renamedItem.filename should change to
/// itemName. Property renamedItem.displayName should also be updated if you
/// chose to overwrite that method.
///
/// Errors (including collision errors) are handled as documented for the import
/// method above. Renames are gated by the capabilities of the renamed item, with
/// NSFileProviderItemCapabilitiesAllowsRenaming.
#[unsafe(method(renameItemWithIdentifier:toName:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn renameItemWithIdentifier_toName_completionHandler(
&self,
item_identifier: &NSFileProviderItemIdentifier,
item_name: &NSString,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSFileProviderItem, *mut NSError)>,
);
#[cfg(all(feature = "NSFileProviderItem", feature = "block2"))]
/// Move an item to a new directory.
///
/// This is expected to complete before doing any network.
///
/// If newName is non null, the moved item should be renamed to newName.
///
/// Errors (including collision errors) are handled as documented for the import
/// method above. Moves are gated by the capabilities of both the moved item with
/// NSFileProviderItemCapabilitiesAllowsReparenting, and the destination directory
/// with NSFileProviderItemCapabilitiesAllowsAddingSubItems.
#[unsafe(method(reparentItemWithIdentifier:toParentItemWithIdentifier:newName:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn reparentItemWithIdentifier_toParentItemWithIdentifier_newName_completionHandler(
&self,
item_identifier: &NSFileProviderItemIdentifier,
parent_item_identifier: &NSFileProviderItemIdentifier,
new_name: Option<&NSString>,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSFileProviderItem, *mut NSError)>,
);
#[cfg(all(feature = "NSFileProviderItem", feature = "block2"))]
/// Move an item to the trash.
///
/// In the completion block, property trashedItem.isTrashed should be set to YES.
/// You should keep track of the original parentItemIdentifier of the item before
/// it was moved to trash, so you can move the item back where it used to be in the
/// untrash method. You could use the trashedItem.parentItemIdentifier property
/// for that.
///
/// The trashed item should continue to belong to the working set of documents
/// cached on the device and visible offline to the user. But if it is a
/// directory, then all of its children should be removed from the working set and
/// the file provider extension should send deletion events to make sure that they
/// no longer appear in the recent lists.
///
/// It is also suggested that shared documents be unshared when trashed.
///
/// Trash is gated by the capabilities of the trashed item with
/// NSFileProviderItemCapabilitiesAllowsTrashing.
#[unsafe(method(trashItemWithIdentifier:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn trashItemWithIdentifier_completionHandler(
&self,
item_identifier: &NSFileProviderItemIdentifier,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSFileProviderItem, *mut NSError)>,
);
#[cfg(all(feature = "NSFileProviderItem", feature = "block2"))]
/// Move an item out of the trash.
///
/// If parentItemIdentifier is nil, the file provider should attempt to put the
/// item back where it was when it was moved to the trash; otherwise it should move
/// it to this new parent.
///
/// If the item is a directory, then the file provider extension should enumerate
/// the children and send addition events in the working set so that the documents
/// in the now untrashed directory may be reindexed.
///
/// Untrash is gated by the capabilities of the destination directory, with
/// NSFileProviderItemCapabilitiesAllowsAddingSubItems.
#[unsafe(method(untrashItemWithIdentifier:toParentItemIdentifier:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn untrashItemWithIdentifier_toParentItemIdentifier_completionHandler(
&self,
item_identifier: &NSFileProviderItemIdentifier,
parent_item_identifier: Option<&NSFileProviderItemIdentifier>,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSFileProviderItem, *mut NSError)>,
);
#[cfg(all(feature = "NSFileProviderItem", feature = "block2"))]
/// Delete an item forever.
///
/// This is called when the user deletes an item that was already in the Trash and
/// the item should no longer appear there after this call. This call should
/// remove the item from the working set.
///
/// Delete is gated by the capabilities of the removed item with
/// NSFileProviderItemCapabilitiesAllowsDeleting.
#[unsafe(method(deleteItemWithIdentifier:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn deleteItemWithIdentifier_completionHandler(
&self,
item_identifier: &NSFileProviderItemIdentifier,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
#[cfg(all(feature = "NSFileProviderItem", feature = "block2"))]
/// Mark an item as recently used, or clear its lastUsedDate if nil.
///
/// This last used date is the sort key for the recent lists. It is the primary
/// hint that an item must belong to the working set cached and indexed on the
/// user's device.
///
/// The file provider is asked to persist the new last used date on disk, then call
/// the completion callback with the updated last used date. At a later point, the
/// file provider should sync the new last used date to their server.
///
/// The error parameter is here for debugging purposes alone; it won't be presented
/// to the user or otherwise handled, but it will be logged.
#[unsafe(method(setLastUsedDate:forItemIdentifier:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn setLastUsedDate_forItemIdentifier_completionHandler(
&self,
last_used_date: Option<&NSDate>,
item_identifier: &NSFileProviderItemIdentifier,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSFileProviderItem, *mut NSError)>,
);
#[cfg(all(feature = "NSFileProviderItem", feature = "block2"))]
/// Tag an item, or untag it if tagData is nil.
///
/// The file provider is asked to persist the new tag data on disk, then call the
/// completion callback with the updated tagged data. At a later point, the file
/// provider should sync the new tag data to their server.
///
/// Tagged items are relevant to the user and should be in the working set even if
/// they haven't been used recently.
///
/// If set, the error will be immediately presented to the user and the item just
/// won't be tagged.
///
/// On shared items, tags should sync across the devices of any one participant but
/// shouldn't sync across users.
#[unsafe(method(setTagData:forItemIdentifier:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn setTagData_forItemIdentifier_completionHandler(
&self,
tag_data: Option<&NSData>,
item_identifier: &NSFileProviderItemIdentifier,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSFileProviderItem, *mut NSError)>,
);
#[cfg(all(feature = "NSFileProviderItem", feature = "block2"))]
/// Mark a directory as favorite (or no longer favorite if favoriteRank is nil.)
///
/// The favorite rank is used to represent the relative order of two favorite
/// directories in the UI. It is a 64 bit unsigned integer. It needs to be synced.
///
/// Favorite directories are relevant to the user and should be in the working set
/// even if they haven't been used recently. The documents and directories in the
/// favorite directory however don't all have to be in the working set, and don't
/// all have to be made accessible offline.
///
/// The file provider is asked to persist the new favorite rank on disk, then call
/// the completion callback with the updated favorite rank. At a later point, the
/// file provider should sync the new favorite rank to their server.
#[unsafe(method(setFavoriteRank:forItemIdentifier:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn setFavoriteRank_forItemIdentifier_completionHandler(
&self,
favorite_rank: Option<&NSNumber>,
item_identifier: &NSFileProviderItemIdentifier,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSFileProviderItem, *mut NSError)>,
);
);
}