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
//! 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::*;
/// A user-defined chunk of data that defines a starting point to enumerate changes
/// from.
///
/// The size of a sync anchor should not exceed a combined 500 bytes.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileprovidersyncanchor?language=objc)
// NS_TYPED_EXTENSIBLE_ENUM
pub type NSFileProviderSyncAnchor = NSData;
/// A user- or system-defined chunk of data that defines a page to continue the
/// enumeration from. Initial enumeration is started from one of the below
/// system-defined pages.
///
/// The size of a page should not exceed 500 bytes.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderpage?language=objc)
// NS_TYPED_EXTENSIBLE_ENUM
pub type NSFileProviderPage = NSData;
extern "C" {
/// [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderinitialpagesortedbydate?language=objc)
pub static NSFileProviderInitialPageSortedByDate: &'static NSFileProviderPage;
}
extern "C" {
/// [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderinitialpagesortedbyname?language=objc)
pub static NSFileProviderInitialPageSortedByName: &'static NSFileProviderPage;
}
extern_protocol!(
/// [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderenumerationobserver?language=objc)
pub unsafe trait NSFileProviderEnumerationObserver: NSObjectProtocol {
#[cfg(feature = "NSFileProviderItem")]
#[unsafe(method(didEnumerateItems:))]
#[unsafe(method_family = none)]
unsafe fn didEnumerateItems(
&self,
updated_items: &NSArray<ProtocolObject<dyn NSFileProviderItemProtocol>>,
);
/// Call this method after enumerating a full page of items. If you set a non-nil
/// nextPage, -[NSFileProviderEnumerator enumerateItemsToObserver:startingAtPage:]
/// might be called with nextPage to enumerate more items. This is typically
/// driven by the user scrolling a UIDocumentBrowserViewController presenting a
/// directory containing more child items that would fit in the view.
///
/// Page data is limited to 500 bytes. Setting a larger nextPage interrupts the
/// enumeration.
#[unsafe(method(finishEnumeratingUpToPage:))]
#[unsafe(method_family = none)]
unsafe fn finishEnumeratingUpToPage(&self, next_page: Option<&NSFileProviderPage>);
#[unsafe(method(finishEnumeratingWithError:))]
#[unsafe(method_family = none)]
unsafe fn finishEnumeratingWithError(&self, error: &NSError);
/// Size of the page suggested by the system for better performance.
///
/// The system will set that property to the value it considers is best suited for the current enumeration. The
/// system can enumerate a container in various cases (container presenter in the UI, file opened in an application,
/// materialization of the folder by the system, ...). Each case has its own performance profile.
///
/// By taking into account the suggested size, the enumeration will guarantee the best user experience possible. The
/// system enforces a maximum of 100 times the suggested size.
#[optional]
#[unsafe(method(suggestedPageSize))]
#[unsafe(method_family = none)]
unsafe fn suggestedPageSize(&self) -> NSInteger;
}
);
extern_protocol!(
/// [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderchangeobserver?language=objc)
pub unsafe trait NSFileProviderChangeObserver: NSObjectProtocol {
#[cfg(feature = "NSFileProviderItem")]
/// Send updates to existing items, or insert new items.
#[unsafe(method(didUpdateItems:))]
#[unsafe(method_family = none)]
unsafe fn didUpdateItems(
&self,
updated_items: &NSArray<ProtocolObject<dyn NSFileProviderItemProtocol>>,
);
#[cfg(feature = "NSFileProviderItem")]
/// Delete existing items. No-op if the item was unknown.
#[unsafe(method(didDeleteItemsWithIdentifiers:))]
#[unsafe(method_family = none)]
unsafe fn didDeleteItemsWithIdentifiers(
&self,
deleted_item_identifiers: &NSArray<NSFileProviderItemIdentifier>,
);
/// This method is used to complete a batch of changes. Follow the advice
/// in -[NSFileProviderChangeObserver suggestedBatchSize] to determine when to
/// call this method.
///
/// It is expected that the sync anchor passed here be different than the sync
/// anchor that the enumeration started at, unless the client was already up to
/// date on all the changes on the server, and didn't have any pending updates or
/// deletions.
///
/// Additionally, if the client is up to date on all the changes on the server it
/// should set moreComing to NO.
///
/// Sync anchor data is limited to 500 bytes. Setting a larger anchor has the
/// same effect as calling finishEnumeratingWithError with an expired sync anchor
/// error.
#[unsafe(method(finishEnumeratingChangesUpToSyncAnchor:moreComing:))]
#[unsafe(method_family = none)]
unsafe fn finishEnumeratingChangesUpToSyncAnchor_moreComing(
&self,
anchor: &NSFileProviderSyncAnchor,
more_coming: bool,
);
/// If the enumeration fails with NSFileProviderErrorSyncAnchorExpired, we will
/// drop all cached data and start the enumeration over starting with sync anchor
/// nil.
#[unsafe(method(finishEnumeratingWithError:))]
#[unsafe(method_family = none)]
unsafe fn finishEnumeratingWithError(&self, error: &NSError);
/// Size of the batch suggested by the system for better performance.
///
/// The system will set that property to the value it considers is best suited for the current enumeration. The
/// system can enumerate changes on a container in various cases (container presenter in the UI, file opened in an
/// application, ...). Each case has its own performance profile.
///
/// In case the enumerator has already more than suggestedBatchSize pending changes ready to enumerate, it is suggested
/// it split the list of changes into several batches. If the enumerator does not have suggestedBatchSize ready to
/// enumerator, the enumerator should finish immediately and not wait for more incoming changes to enumerate.
///
/// By taking into account the suggested size, the enumeration will guarantee the best user experience possible. Large
/// batches can cause performance issues. And when the device reboots, enumerations will resume from the latest
/// known sync anchor. Telling the system about the latest sync anchor more frequently will reduce the number
/// of re-enumerations on system reboot.
///
/// The system enforces a maximum of 100 times the suggested size.
#[optional]
#[unsafe(method(suggestedBatchSize))]
#[unsafe(method_family = none)]
unsafe fn suggestedBatchSize(&self) -> NSInteger;
}
);
extern_protocol!(
/// [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderenumerator?language=objc)
pub unsafe trait NSFileProviderEnumerator: NSObjectProtocol {
#[unsafe(method(invalidate))]
#[unsafe(method_family = none)]
unsafe fn invalidate(&self);
/// Enumerate items starting from the specified page, typically
/// NSFileProviderInitialPageSortedByDate or NSFileProviderInitialPageSortedByName.
///
/// Pagination allows large collections to be enumerated in multiple batches. The
/// sort order specified in the initial page is important even if the enumeration
/// results will actually be sorted again before display. If results are sorted
/// correctly across pages, then the new results will be appended at the bottom of
/// the list, probably not on screen, which is the best user experience. Otherwise
/// results from the second page might be inserted in the results from the first
/// page, causing bizarre animations.
///
/// The page data should contain whatever information is needed to resume the
/// enumeration after the previous page. If a file provider sends batches of 200
/// items to -[NSFileProviderEnumerationObserver didEnumerateItems:] for example,
/// then successive pages might contain offsets in increments of 200.
///
/// Execution time:
/// ---------------
/// This method is not expected to take more than a few seconds to complete the
/// enumeration of a page of items. If the enumeration may not complete in a reasonable
/// amount of time because, for instance, of bad network conditions, it is recommended
/// to either report an error (for instance NSFileProviderErrorServerUnreachable) or
/// return everything that is readily available and wait for the enumeration of the
/// next page.
#[unsafe(method(enumerateItemsForObserver:startingAtPage:))]
#[unsafe(method_family = none)]
unsafe fn enumerateItemsForObserver_startingAtPage(
&self,
observer: &ProtocolObject<dyn NSFileProviderEnumerationObserver>,
page: &NSFileProviderPage,
);
/// Enumerate changes starting from a sync anchor. This should enumerate /all/
/// changes (not restricted to a specific page) since the given sync anchor.
///
/// Until the enumeration update is invalidated, a call to -[NSFileProviderManager
/// signalEnumeratorForContainerItemIdentifier:completionHandler:] will trigger a
/// call to enumerateFromSyncAnchor with the latest known sync anchor, giving the
/// file provider (app or extension) a chance to notify about changes.
///
/// The anchor data should contain whatever information is needed to resume
/// enumerating changes from the previous synchronization point. A naive sync
/// anchor might for example be the date of the last change that was sent from the
/// server to the client, meaning that at that date, the client was in sync with
/// all the server changes. A request to enumerate changes from that sync anchor
/// would only return the changes that happened after that date, which are
/// therefore changes that the client doesn't yet know about.
///
/// NOTE that the change-based observation methods are marked optional for historical
/// reasons, but are really required. System performance will be severely degraded if
/// they are not implemented.
///
/// Execution time:
/// ---------------
/// This method is not expected to take more than a few seconds to complete the
/// enumeration of a batch of items. If the enumeration may not complete in a reasonable
/// amount of time because, for instance, of bad network conditions, it is recommended
/// to either report an error (for instance NSFileProviderErrorServerUnreachable) or
/// return everything that is readily available and wait for the enumeration of the
/// next batch.
#[optional]
#[unsafe(method(enumerateChangesForObserver:fromSyncAnchor:))]
#[unsafe(method_family = none)]
unsafe fn enumerateChangesForObserver_fromSyncAnchor(
&self,
observer: &ProtocolObject<dyn NSFileProviderChangeObserver>,
sync_anchor: &NSFileProviderSyncAnchor,
);
#[cfg(feature = "block2")]
/// Request the current sync anchor.
///
/// To keep an enumeration updated, the system will typically
/// - request the current sync anchor (1)
/// - enumerate items starting with an initial page
/// - continue enumerating pages, each time from the page returned in the previous
/// enumeration, until finishEnumeratingUpToPage: is called with nextPage set to
/// nil
/// - enumerate changes starting from the sync anchor returned in (1), until
/// finishEnumeratingChangesUpToSyncAnchor: is called with the latest sync anchor.
/// If moreComing is YES, continue enumerating changes, using the latest sync anchor returned.
/// If moreComing is NO, stop enumerating.
/// - When the extension calls -[NSFileProviderManager signalEnumeratorForContainerItemIdentifier:
/// completionHandler:] to signal more changes, the system will again enumerate changes,
/// starting at the latest known sync anchor from finishEnumeratingChangesUpToSyncAnchor.
///
/// NOTE that the change-based observation methods are marked optional for historical
/// reasons, but are really required. System performance will be severely degraded if
/// they are not implemented.
#[optional]
#[unsafe(method(currentSyncAnchorWithCompletionHandler:))]
#[unsafe(method_family = none)]
unsafe fn currentSyncAnchorWithCompletionHandler(
&self,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSFileProviderSyncAnchor)>,
);
}
);
/// NSFileProviderEnumeration.
#[cfg(feature = "Extension")]
impl NSFileProviderExtension {
extern_methods!(
#[cfg(feature = "NSFileProviderItem")]
/// Create an enumerator for an item.
///
/// When the user opens the browse tab of the UIDocumentsBrowserViewController and
/// selects a file provider, this is called with
/// NSFileProviderRootContainerItemIdentifier, and -[NSFileProviderEnumerator
/// enumerateItemsForObserver:startingAtPage:] is immediately called to list the
/// first items available under at the root level of the file provider.
///
/// As the user navigates down into directories, new enumerators are created with
/// this method, passing in the itemIdentifier of those directories. Past
/// enumerators are then invalidated.
///
/// This method is also called with
/// NSFileProviderWorkingSetContainerItemIdentifier, which is enumerated with
/// -[NSFileProviderEnumerator enumerateChangesForObserver:fromSyncAnchor:]. That
/// enumeration is special in that it isn't driven by the
/// UIDocumentsBrowserViewController. It happens in the background to sync the
/// working set down to the device.
///
/// This is also used to subscribe to live updates for a single document. In that
/// case, -[NSFileProviderEnumerator enumerateChangesToObserver:fromSyncAnchor:]
/// will be called and the enumeration results shouldn't include items other than
/// the very item that the enumeration was started on.
///
/// If returning nil, you must set the error out parameter.
#[unsafe(method(enumeratorForContainerItemIdentifier:error:_))]
#[unsafe(method_family = none)]
pub unsafe fn enumeratorForContainerItemIdentifier_error(
&self,
container_item_identifier: &NSFileProviderItemIdentifier,
) -> Result<Retained<ProtocolObject<dyn NSFileProviderEnumerator>>, Retained<NSError>>;
);
}