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
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
//! 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::*;
extern_class!(
/// [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderextension?language=objc)
#[unsafe(super(NSObject))]
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct NSFileProviderExtension;
);
extern_conformance!(
unsafe impl NSObjectProtocol for NSFileProviderExtension {}
);
impl NSFileProviderExtension {
extern_methods!(
#[cfg(feature = "NSFileProviderItem")]
#[unsafe(method(itemForIdentifier:error:_))]
#[unsafe(method_family = none)]
pub unsafe fn itemForIdentifier_error(
&self,
identifier: &NSFileProviderItemIdentifier,
) -> Result<Retained<NSFileProviderItem>, Retained<NSError>>;
#[cfg(feature = "NSFileProviderItem")]
/// Should return the URL corresponding to a specific identifier. Fail if it's not
/// a subpath of documentStorageURL.
///
/// This is a static mapping; each identifier must always return a path
/// corresponding to the same file. By default, this returns the path relative to
/// the path returned by documentStorageURL.
#[unsafe(method(URLForItemWithPersistentIdentifier:))]
#[unsafe(method_family = none)]
pub unsafe fn URLForItemWithPersistentIdentifier(
&self,
identifier: &NSFileProviderItemIdentifier,
) -> Option<Retained<NSURL>>;
#[cfg(feature = "NSFileProviderItem")]
#[unsafe(method(persistentIdentifierForItemAtURL:))]
#[unsafe(method_family = none)]
pub unsafe fn persistentIdentifierForItemAtURL(
&self,
url: &NSURL,
) -> Option<Retained<NSFileProviderItemIdentifier>>;
#[cfg(feature = "block2")]
/// This method is called when a placeholder URL should be provided for the item at
/// the given URL.
///
/// The implementation of this method should call +[NSFileProviderManager
/// writePlaceholderAtURL:withMetadata:error:] with the URL returned by
/// +[NSFileProviderManager placeholderURLForURL:], then call the completion
/// handler.
#[unsafe(method(providePlaceholderAtURL:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn providePlaceholderAtURL_completionHandler(
&self,
url: &NSURL,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
#[cfg(feature = "block2")]
/// Should ensure that the actual file is in the position returned by
/// URLForItemWithPersistentIdentifier:, then call the completion handler.
#[unsafe(method(startProvidingItemAtURL:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn startProvidingItemAtURL_completionHandler(
&self,
url: &NSURL,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
/// Called after the last claim to the file has been released. At this point, it is
/// safe for the file provider to remove the content file.
///
/// Care should be taken that the corresponding placeholder file stays behind after
/// the content file has been deleted.
#[unsafe(method(stopProvidingItemAtURL:))]
#[unsafe(method_family = none)]
pub unsafe fn stopProvidingItemAtURL(&self, url: &NSURL);
/// Called at some point after the file has changed; the provider may then trigger
/// an upload.
#[unsafe(method(itemChangedAtURL:))]
#[unsafe(method_family = none)]
pub unsafe fn itemChangedAtURL(&self, url: &NSURL);
);
}
/// Methods declared on superclass `NSObject`.
impl NSFileProviderExtension {
extern_methods!(
#[unsafe(method(init))]
#[unsafe(method_family = init)]
pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
#[unsafe(method(new))]
#[unsafe(method_family = new)]
pub unsafe fn new() -> Retained<Self>;
);
}
/// Deprecated.
impl NSFileProviderExtension {
extern_methods!(
/// Writes out a placeholder at the specified URL. The URL should be one returned
/// by placeholderURLForURL:; if URL resource values are requested, the system will
/// consult the placeholder before consulting your app extension.
///
/// Metadata contains NSURLNameKey, NSURLFileSizeKey, NSURLIsPackageKey.
///
/// # Safety
///
/// `metadata` generic should be of the correct type.
#[deprecated = "Use the corresponding method on NSFileProviderManager instead"]
#[unsafe(method(writePlaceholderAtURL:withMetadata:error:_))]
#[unsafe(method_family = none)]
pub unsafe fn writePlaceholderAtURL_withMetadata_error(
placeholder_url: &NSURL,
metadata: &NSDictionary<NSURLResourceKey, AnyObject>,
) -> Result<(), Retained<NSError>>;
/// Returns the designated placeholder URL for a given URL. This placeholder will
/// be consulted before falling back to your app extension to enhance
/// performance. To write out a placeholder, use the writePlaceHolderAtURL: method
/// above.
#[deprecated]
#[unsafe(method(placeholderURLForURL:))]
#[unsafe(method_family = none)]
pub unsafe fn placeholderURLForURL(url: &NSURL) -> Retained<NSURL>;
/// An identifier unique to this provider.
///
/// When modifying the files stored in the directory returned by
/// documentStorageURL, you should pass this identifier to your file coordinator's
/// setPurposeIdentifier: method.
#[deprecated]
#[unsafe(method(providerIdentifier))]
#[unsafe(method_family = none)]
pub unsafe fn providerIdentifier(&self) -> Retained<NSString>;
/// The root URL for provided documents. This URL is derived by consulting the
/// NSExtensionFileProviderDocumentGroup property on your extension. The document
/// storage URL is the folder "File Provider Storage" in the corresponding
/// container.
#[deprecated]
#[unsafe(method(documentStorageURL))]
#[unsafe(method_family = none)]
pub unsafe fn documentStorageURL(&self) -> Retained<NSURL>;
);
}
/// [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderdomainremovalmode?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSFileProviderDomainRemovalMode(pub NSInteger);
impl NSFileProviderDomainRemovalMode {
/// Don't keep any files that are current in the domain
#[doc(alias = "NSFileProviderDomainRemovalModeRemoveAll")]
pub const RemoveAll: Self = Self(0);
/// Delete the domain from the system but keeps the at least all the
/// dirty corresponding user data around.
#[doc(alias = "NSFileProviderDomainRemovalModePreserveDirtyUserData")]
pub const PreserveDirtyUserData: Self = Self(1);
/// Delete the domain from the system but keeps all the downloaded
/// corresponding user data around.
#[doc(alias = "NSFileProviderDomainRemovalModePreserveDownloadedUserData")]
pub const PreserveDownloadedUserData: Self = Self(2);
}
unsafe impl Encode for NSFileProviderDomainRemovalMode {
const ENCODING: Encoding = NSInteger::ENCODING;
}
unsafe impl RefEncode for NSFileProviderDomainRemovalMode {
const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}
extern_class!(
/// The file provider manager allows you to communicate with the file provider
/// framework from both the extension and related processes.
///
/// NSFileProviderManager can be used from the following processes:
/// - the extension
/// - the main app containing the extension
/// - sibling extensions to the extension
/// - executables contained in the main app bundle (on macOS only)
///
/// Executables contained in the main app bundle need to have a bundle identifier that is
/// prefixed by the bundle identifier of the main app (note that this is generally required
/// for extensions). They must also have access to the document group defined for the provider
/// (via its `NSExtensionFileProviderDocumentGroup` key).
///
/// The file provider framework will invoke your file provider extension in response
/// to those calls if appropriate.
///
/// The class also provides methods to manage provider domains. Each domain has a
/// corresponding manager.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileprovidermanager?language=objc)
#[unsafe(super(NSObject))]
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct NSFileProviderManager;
);
extern_conformance!(
unsafe impl NSObjectProtocol for NSFileProviderManager {}
);
impl NSFileProviderManager {
extern_methods!(
#[unsafe(method(init))]
#[unsafe(method_family = init)]
pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
/// Return the manager responsible for the default domain.
#[unsafe(method(defaultManager))]
#[unsafe(method_family = none)]
pub unsafe fn defaultManager() -> Retained<NSFileProviderManager>;
#[cfg(feature = "NSFileProviderDomain")]
/// Return the manager for the specified domain.
#[unsafe(method(managerForDomain:))]
#[unsafe(method_family = none)]
pub unsafe fn managerForDomain(domain: &NSFileProviderDomain) -> Option<Retained<Self>>;
#[cfg(all(feature = "NSFileProviderItem", feature = "block2"))]
/// Call this method either in the app or in the extension to trigger an
/// enumeration, typically in response to a push.
///
/// When using NSFileProviderExtension, the system will enumerate containers
/// while the user is viewing them in the UI. If there are changes to the container
/// while an enumerator is open, call this method with the identifier of that
/// container. This will trigger another call to
/// -[NSFileProviderEnumerator enumerateChangesForObserver:fromSyncAnchor:] on
/// that enumerator, and the UI will be refreshed, giving the user live updates on
/// the presented enumeration.
///
/// If there are changes in the working set, call this method with
/// containerItemIdentifier set to NSFileProviderWorkingSetContainerItemIdentifier,
/// even if there is no live enumeration for the working set container.
///
/// When using NSFileProviderReplicatedExtension, only call this
/// method with NSFileProviderWorkingSetContainerItemIdentifier. Other container
/// identifiers are ignored. The system will automatically propagate
/// working set changes to the UI, without explicitly signaling the
/// containers currently being viewed in the UI.
///
/// In addition to using this method, your application/extension can register for
/// pushes using the PKPushTypeFileProvider push type. Pushes of the form
/// {
/// "container-identifier": "<identifier>",
/// "domain": "<domain identifier>"
/// }
/// with a topic of "<your application identifier>.pushkit.fileprovider" will be
/// translated into a call to signalEnumeratorForContainerItemIdentifier:completionHandler:.
#[unsafe(method(signalEnumeratorForContainerItemIdentifier:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn signalEnumeratorForContainerItemIdentifier_completionHandler(
&self,
container_item_identifier: &NSFileProviderItemIdentifier,
completion: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
#[cfg(all(feature = "NSFileProviderItem", feature = "block2"))]
/// Return the security scoped URL to the user visible location for an item identifier.
///
/// The caller must use file coordination (see NSFileCoordinator) if it wishes to read the
/// content or list the children of the URL. The caller should not try to manipulate files
/// in the user visible location. All changes coming from the provider should go through
/// updates in the working set that will be applied to the user visible items by the
/// system.
///
/// The location may differ from the logical parentURL/filename.
/// If an item on disk cannot be assigned the requested name (e.g. because the local
/// file system has different case collision rules from the provider), one of the items can be assigned
/// a different local name. In that case, the "com.apple.fileprovider.before-bounce#PX" extended
/// attribute will contain the filename before collision resolution.
/// This attribute is only set if the item has been assigned a different local name following
/// a collision. Such local names are not synced up to the provider; the purpose of the attribute is
/// to enable consistency checkers to detect this case.
///
/// Before accessing the content of the returned URL, the caller must call `-[NSURL startAccessingSecurityScopedResource]
/// on the returned URL and call `-[NSURL stopAccessingSecurityScopedResource]` when done accessing the content.
///
/// The returned URL grants read-write access to the user visible location for the corresponding item.
///
/// On iOS, for replicated domains, the extension process will never be granted access to the user
/// visible location, this function will always fail with `NSFileReadNoPermissionError`.
#[unsafe(method(getUserVisibleURLForItemIdentifier:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn getUserVisibleURLForItemIdentifier_completionHandler(
&self,
item_identifier: &NSFileProviderItemIdentifier,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSURL, *mut NSError)>,
);
#[cfg(all(
feature = "NSFileProviderDomain",
feature = "NSFileProviderItem",
feature = "block2"
))]
/// Return the identifier and domain for a user visible URL.
///
/// This method returns the identifier and domain of a user visible URL if
/// applicable. Calling this method on a file which doesn't reside in your
/// provider/domain, or which hasn't yet been assigned an identifier by
/// the provider will return the Cocoa error NSFileNoSuchFileError.
#[unsafe(method(getIdentifierForUserVisibleFileAtURL:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn getIdentifierForUserVisibleFileAtURL_completionHandler(
url: &NSURL,
completion_handler: &block2::DynBlock<
dyn Fn(
*mut NSFileProviderItemIdentifier,
*mut NSFileProviderDomainIdentifier,
*mut NSError,
),
>,
);
#[cfg(all(feature = "NSFileProviderItem", feature = "block2"))]
/// Registers the given NSURLSessionTask to be responsible for the specified item.
/// A given item can only have one task registered at a time. The task must be
/// suspended at the time of calling.
/// The task's progress is displayed on the item when the task is executed.
#[unsafe(method(registerURLSessionTask:forItemWithIdentifier:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn registerURLSessionTask_forItemWithIdentifier_completionHandler(
&self,
task: &NSURLSessionTask,
identifier: &NSFileProviderItemIdentifier,
completion: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
/// The purpose identifier of your file provider extension. A coordination using a
/// file coordinator with this purpose identifier set will not trigger your file
/// provider extension. You can use this to e.g. perform speculative work on behalf
/// of the file provider from the main app.
#[unsafe(method(providerIdentifier))]
#[unsafe(method_family = none)]
pub unsafe fn providerIdentifier(&self) -> Retained<NSString>;
/// The root URL for provided documents. This URL is derived by consulting the
/// NSExtensionFileProviderDocumentGroup property on your extension. The document
/// storage URL is the folder "File Provider Storage" in the corresponding
/// container.
///
/// If the NSExtensionFileProviderDocumentGroup property is not set, calling this
/// method will result in an error.
#[unsafe(method(documentStorageURL))]
#[unsafe(method_family = none)]
pub unsafe fn documentStorageURL(&self) -> Retained<NSURL>;
/// A temporary directory suitable to store files that will be exchanged with the system.
///
/// The returned URL is guaranteed to be on the same volume as the user visible URL, making sure the system
/// can atomatically clone/move files from that location to the user visible URL. The provider can also use
/// that directory as a target for moves and clones of content URL passed to createItemBasedOnTemplate
/// or modifyItem.
///
/// If the system cannot find a suitable directory, this calls will fail. This could happen e.g. if the domain
/// does not exist or is in instance of initialization.
///
/// This call succeeds when called from the extension process with an instance of the extension for the domain
/// unless domain was disconnected by
/// `-[NSFileProviderExternalVolumeHandling shouldConnectExternalDomainWithCompletionHandler:]`.
/// It can also fail in the extension process if the domain (external) is being setup for the very first time
/// (meaning it never existed).
#[unsafe(method(temporaryDirectoryURLWithError:_))]
#[unsafe(method_family = none)]
pub unsafe fn temporaryDirectoryURLWithError(
&self,
) -> Result<Retained<NSURL>, Retained<NSError>>;
#[cfg(feature = "NSFileProviderItem")]
/// Writes out a placeholder at the specified URL. The placeholder is used in place
/// of the actual file for operations that do not require the file's actual data to
/// be on disk:
/// - if attributes are requested by an application via the
/// getPromisedItemResourceValue: method on NSURL
/// - or via a coordination with the
/// NSFileCoordinatorReadingImmediatelyAvailableMetadataOnly flag set
/// - to verify whether an application has access to a file
///
/// Your extension should provide placeholders by implementing the
/// providePlaceholderAtURL: method, but your application may choose to proactively
/// write out placeholders to facilitate access to files. This is especially useful
/// if your application wants to actively hand out a file URL, e.g. using
/// UIActivityViewController, in which case it should ensure that either the file
/// or a placeholder is present on disk first.
///
/// The path of the placeholder is fixed and must be determined in advance by
/// calling the placeholderURLForURL: method.
#[unsafe(method(writePlaceholderAtURL:withMetadata:error:_))]
#[unsafe(method_family = none)]
pub unsafe fn writePlaceholderAtURL_withMetadata_error(
placeholder_url: &NSURL,
metadata: &NSFileProviderItem,
) -> Result<(), Retained<NSError>>;
/// Returns the designated placeholder URL for a given file URL. Used in
/// conjunction with writePlaceholderAtURL.
#[unsafe(method(placeholderURLForURL:))]
#[unsafe(method_family = none)]
pub unsafe fn placeholderURLForURL(url: &NSURL) -> Retained<NSURL>;
#[cfg(all(feature = "NSFileProviderDomain", feature = "block2"))]
/// Register a domain in which items can be stored.
///
/// If a domain with the same identifier already exists, `addDomain` will update the display name
/// and hidden state of the domain and succeed.
///
/// When the domain is backed by a NSFileProviderReplicatedExtension, the system will create
/// a disk location where the domain will be replicated. If that location already exists on disk
/// this call will fail with the code NSFileWriteFileExistsError.
#[unsafe(method(addDomain:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn addDomain_completionHandler(
domain: &NSFileProviderDomain,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
#[cfg(all(feature = "NSFileProviderDomain", feature = "block2"))]
/// Remove a domain.
#[unsafe(method(removeDomain:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn removeDomain_completionHandler(
domain: &NSFileProviderDomain,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
#[cfg(all(feature = "NSFileProviderDomain", feature = "block2"))]
/// Remove a domain with options
#[unsafe(method(removeDomain:mode:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn removeDomain_mode_completionHandler(
domain: &NSFileProviderDomain,
mode: NSFileProviderDomainRemovalMode,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSURL, *mut NSError)>,
);
#[cfg(all(feature = "NSFileProviderDomain", feature = "block2"))]
/// Get all registered domains.
#[unsafe(method(getDomainsWithCompletionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn getDomainsWithCompletionHandler(
completion_handler: &block2::DynBlock<
dyn Fn(NonNull<NSArray<NSFileProviderDomain>>, *mut NSError),
>,
);
#[cfg(feature = "block2")]
/// Remove all registered domains.
#[unsafe(method(removeAllDomainsWithCompletionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn removeAllDomainsWithCompletionHandler(
completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
#[cfg(feature = "block2")]
/// Calling this method will cause the system to cancel throttling on every item which has been throttled due to the given error.
///
/// This call supports the following errors:
/// - NSFileProviderErrorNotAuthenticated
/// - NSFileProviderErrorInsufficientQuota
/// - NSFileProviderErrorServerUnreachable
/// - NSFileProviderErrorCannotSynchronize
/// - NSFileProviderErrorExcludedFromSync
#[unsafe(method(signalErrorResolved:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn signalErrorResolved_completionHandler(
&self,
error: &NSError,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
/// Returns the global progress for the specified kind of operations
///
/// This progress tracks all the ongoing kind of operations (from disk to the provider).
/// Uploading operations are the operations from disk to the provider.
/// Downloading operations are the operations from the provider to the disk.
///
/// The global progress exposes the two following data:
/// - Number of items with an ongoing matching kind operation along with the grand total;
/// - Number of bytes already transferred along with the total amount of bytes to transfer.
///
/// `totalUnitCount` will only be reset when there are no operations left. If new operations of the matching
/// kind arrive while the global progress is already ongoing, they will just be summed to the existing global
/// progress.
///
/// By default, when no matching kind operations are active, the progress has its values set to 1 and its state set
/// to finished.
///
/// The progress will be updated on the main queue. It is to be retained by the caller and to be observed through
/// KVO.
///
/// The two only supported values for kind are:
/// - NSProgressFileOperationKindUploading
/// - NSProgressFileOperationKindDownloading
///
/// The returned progress will have its fileOperationKind property set.
#[unsafe(method(globalProgressForKind:))]
#[unsafe(method_family = none)]
pub unsafe fn globalProgressForKind(
&self,
kind: &NSProgressFileOperationKind,
) -> Retained<NSProgress>;
);
}
/// Methods declared on superclass `NSObject`.
impl NSFileProviderManager {
extern_methods!(
#[unsafe(method(new))]
#[unsafe(method_family = new)]
pub unsafe fn new() -> Retained<Self>;
);
}
extern "C" {
/// Posted when the materialized set has changed.
///
/// Interested clients can then use the materialized set enumerator returned by -enumeratorForMaterializedItems to enumerate changes on the materialized set.
///
/// Note, this notification starts to be posted only after `+[NSFileProviderManager getDomainsWithCompletionHandler:]` is called.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileprovidermaterializedsetdidchange?language=objc)
pub static NSFileProviderMaterializedSetDidChange: &'static NSNotificationName;
}
/// MaterializedSet.
impl NSFileProviderManager {
extern_methods!(
#[cfg(feature = "NSFileProviderEnumerating")]
/// Returns an enumerator for the set of materialized items.
///
/// When calling -[NSFileProviderEnumerator enumerateItemsForObserver:startingAtPage:] on the returned
/// enumerator, pass the result of [NSData new] as the starting page. The sorting page constants
/// (NSFileProviderInitialPageSortedByName and NSFileProviderInitialPageSortedByDate) will not influence
/// the order of the items enumerated from the materialized set.
///
/// This enumerator is unlike other enumerators because the roles of the system
/// and the app/extension are reversed:
/// - The system enumerates the working set after the extension calls
/// 'signalEnumeratorForContainerItemIdentifier';
/// - The app/extension enumerates the materialized set after the system calls
/// 'materializedItemsDidChangeWithCompletionHandler'.
#[unsafe(method(enumeratorForMaterializedItems))]
#[unsafe(method_family = none)]
pub unsafe fn enumeratorForMaterializedItems(
&self,
) -> Retained<ProtocolObject<dyn NSFileProviderEnumerator>>;
);
}
extern "C" {
/// Posted when the pending set has changed.
///
/// Interested clients can then use the pending set enumerator returned by -enumeratorForPendingItems to enumerate changes on the pending set.
///
/// Note, this notification starts to be posted only after `+[NSFileProviderManager getDomainsWithCompletionHandler:]` is called.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderpendingsetdidchange?language=objc)
pub static NSFileProviderPendingSetDidChange: &'static NSNotificationName;
}
extern_protocol!(
/// [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderpendingsetenumerator?language=objc)
#[cfg(feature = "NSFileProviderEnumerating")]
pub unsafe trait NSFileProviderPendingSetEnumerator: NSFileProviderEnumerator {
#[cfg(feature = "NSFileProviderDomain")]
/// The version of the domain when the pending set was last refreshed by the system.
///
/// This property is updated when the enumeration methods are called on the pending set enumerator. The value
/// is initially nil.
#[unsafe(method(domainVersion))]
#[unsafe(method_family = none)]
unsafe fn domainVersion(&self) -> Option<Retained<NSFileProviderDomainVersion>>;
/// The amount of time in seconds at which the pending set is refreshed on modifications.
#[unsafe(method(refreshInterval))]
#[unsafe(method_family = none)]
unsafe fn refreshInterval(&self) -> NSTimeInterval;
/// This property is set to YES when the enumeration of the pending set was capped at or below its maximum size.
/// Under normal conditions, the count of items pending sync will get lower as sync progresses, and this variable
/// will eventually be set to NO when the pending set again includes all items pending sync.
#[unsafe(method(isMaximumSizeReached))]
#[unsafe(method_family = none)]
unsafe fn isMaximumSizeReached(&self) -> bool;
}
);
/// PendingSet.
impl NSFileProviderManager {
extern_methods!(
#[cfg(feature = "NSFileProviderEnumerating")]
/// Returns an enumerator for the set of pending items.
///
/// This enumerator behaves like the materialized set enumerator.
/// On later modifications in the set, the system will call
/// 'pendingItemsDidChangeWithCompletionHandler'.
#[unsafe(method(enumeratorForPendingItems))]
#[unsafe(method_family = none)]
pub unsafe fn enumeratorForPendingItems(
&self,
) -> Retained<ProtocolObject<dyn NSFileProviderPendingSetEnumerator>>;
);
}
/// Import.
impl NSFileProviderManager {
extern_methods!(
#[cfg(all(feature = "NSFileProviderDomain", feature = "block2"))]
/// Request the creation of a new domain that will take ownership of on-disk data that
/// were previously managed without a file provider.
///
/// You can use this method in order to migrate from a software that managed a file hierarchy
/// on disk to a NSFileProviderExtension without having to redownload the data that was
/// already on disk.
///
/// The URL is expected to point to a directory. That directory will be moved away, its
/// ownership being taken by the system. From this point, your extension's
/// createItemFromTemplate method will be called for every item found in the directory
/// with the special NSFileProviderCreateItemMayAlreadyExist option.
///
/// In case a domain with the same name already exists in the file provider manager, the
/// call will fail with the code NSFileWriteFileExistsError. The URL will remain untouched.
/// In case the system does not allow the extension to request a migration, the call will
/// fail with NSFeatureUnsupportedError.
///
/// In case of success, the URL will become invalid and the domain will be created. The
/// completion handler is called as soon as the domain is created. Your provider will
/// receive calls to createItemBasedOnTemplate afterward.
///
/// When the import of the file hierarchy is finished, the system calls
/// -[NSFileProviderExtension signalDidFinishImportingItemsFromDiskWithCompletionHandler:].
/// In case -[NSFileProviderManager reimportItemsBelowItemWithIdentifier:completionHandler:]
/// is called before the end of the import, a single call to importDidFinishWithCompletionHandler
/// will be received for both the import and the scan.
#[unsafe(method(importDomain:fromDirectoryAtURL:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn importDomain_fromDirectoryAtURL_completionHandler(
domain: &NSFileProviderDomain,
url: &NSURL,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
#[cfg(all(feature = "NSFileProviderItem", feature = "block2"))]
/// Notify the system that the itemIdentifiers known by the system are not valid anymore.
///
/// This can be called by an extension in case it has lost track of its synchronisation state
/// and as a consequence is not able to guarantee the stability of the itemIdentifiers anymore.
/// In that case, the system will trigger a scan of any data that is cached on disk and call
/// createItemBasedOnTemplate with the special NSFileProviderCreateItemMayAlreadyExist
/// option so that the extension can specify the new itemIdentifier for those items. The provided
/// item identifier is inclusive, meaning the specified item will be re-import as well as any
/// children in case it is a container.
///
/// In case the extension has lost its synchronisation state but is still able to guarantee the
/// stability of the itemIdentifiers, it should make sure that querying the working set
/// enumerator with an anchor that predates the synchronisation loss will cause a
/// NSFileProviderErrorSyncAnchorExpired error.
///
/// In case the extension has lost its synchronisation state and is not interested in preserving
/// the data cached on disk, it can remove and re-add the affected domain.
///
/// The completion handler is called as soon as the reimport is initiated and does not not reflect
/// the end of the import. When the import of the file hierarchy is finished, the system calls
/// -[NSFileProviderExtension importDidFinishWithCompletionHandler:].
///
/// In some circumstances, in particular in case the requested item is the root item, calling
/// reimport will cause the system to stop the extension process. If the call is initiated
/// from the extension, the system does not guarantee that the completion handler will be called
/// before the extension is stopped. When called on the root item, reimport will cause the system
/// to rebuild its backing store for the domain. See `-[NSFileProviderDomain backingStoreIdentity]`.
///
/// If this method succeeds, the system will reimport at least the requested sub-tree, but may
/// import more.
///
/// If the requested item has no on-disk representation, the completion handler will be called with
/// a NSFileProviderErrorNoSuchItem error. The same error will be reported if the reimport request
/// happens quickly after a previous import / reimport and the corresponding item hasn't been
/// reimported yet.
#[unsafe(method(reimportItemsBelowItemWithIdentifier:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn reimportItemsBelowItemWithIdentifier_completionHandler(
&self,
item_identifier: &NSFileProviderItemIdentifier,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
#[cfg(all(
feature = "NSFileProviderItem",
feature = "NSFileProviderModifyItemOptions",
feature = "block2"
))]
/// Request that the system schedules a call to -[NSFileProviderReplicatedExtension modifyItem:] for the given item identifier.
/// The fields passed to modifyItem will contain at least the set requested via the `fields` parameter.
/// The completion handler is called when the system has persisted the request. There is no guarantee as to when the
/// modifyItem call will be scheduled.
/// The completion handler may be called with an error. If the provider passes the `.content` field when the item
/// is not downloaded, or when the item is a folder, then the system will return CocoaError(.ubiquitousFileUnavailable).
#[unsafe(method(requestModificationOfFields:forItemWithIdentifier:options:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn requestModificationOfFields_forItemWithIdentifier_options_completionHandler(
&self,
fields: NSFileProviderItemFields,
item_identifier: &NSFileProviderItemIdentifier,
options: NSFileProviderModifyItemOptions,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
);
}
/// Eviction.
impl NSFileProviderManager {
extern_methods!(
#[cfg(all(feature = "NSFileProviderItem", feature = "block2"))]
/// Request that the system remove an item from its cache.
///
/// When called on a file, the file will be made dataless.
///
/// When called on a directory, first each of the directory's children will be evicted (child files are made
/// dataless, child directories are recursively evicted). Then the directory itself will be made dataless.
/// If a non-evictable child is encountered, eviction will stop immediately and the completionHandler will be called with
/// the NSFileProviderErrorNonEvictableChildren error. The error will include information on why and which
/// children could not be evicted in -[NSError underlyingErrors].
///
/// The materialization state of the remaining items may be either materialized or evicted, depending on the traversal order.
///
/// The completion handler is called after the items have been evicted from disk or immediately when an error occurs.
///
/// Eviction might fail with the following errors :
/// - NSFileProviderErrorDomain.NSFileProviderErrorUnsyncedEdits if the item had non-uploaded changes.
/// - NSFileProviderErrorDomain.NSFileProviderErrorNonEvictable if the item has been marked as non-purgeable by the provider.
/// - NSPOSIXErrorDomain.EBUSY : if the item has open file descriptors on it.
/// - NSPOSIXErrorDomain.EMLINK : if the item has several hardlinks.
/// - other NSPOSIXErrorDomain error codes if the system was unable to access or manipulate the corresponding file.
#[unsafe(method(evictItemWithIdentifier:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn evictItemWithIdentifier_completionHandler(
&self,
item_identifier: &NSFileProviderItemIdentifier,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
);
}
/// Barrier.
impl NSFileProviderManager {
extern_methods!(
#[cfg(all(feature = "NSFileProviderItem", feature = "block2"))]
/// Wait for all changes on disk in the sub-hierarchy of the item to be acknowledged by the extension.
///
/// This call can be used to guarantee operation ordering in a sub-hierarchy of the provider. The completion
/// handler is called when all the changes for descendents of the item have been acknowledged by the extension.
/// If any error is met during that process, an error will be raised, in which case the caller should not
/// assume all the changes have been received.
///
/// This call will only wait for changes affecting items that were already descendents of the requested item
/// in the provider, or items that have been newly created on disk. It will not wait for items that are already
/// known from the provider and are being moved in the directory. As a consequence, that call can be used from within a call
/// to -[NSFileProviderReplicatedExtension modifyItem:baseVersion:changedFields:contents:options:completionHandler:].
/// Also note that the call will return immediately on items that are not directories.
///
/// In case a change cannot be applied to the provider, the call will fail with NSFileProviderErrorCannotSynchronize
/// including the NSFileProviderErrorItemKey with the identifier of the item that could not be synced if that item
/// is known by the provider.
#[unsafe(method(waitForChangesOnItemsBelowItemWithIdentifier:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn waitForChangesOnItemsBelowItemWithIdentifier_completionHandler(
&self,
item_identifier: &NSFileProviderItemIdentifier,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
);
}
/// Stabilization.
impl NSFileProviderManager {
extern_methods!(
#[cfg(feature = "block2")]
/// Wait for stabilization of the domain.
///
/// The system will wait until it is caught up with the file system's changes up to
/// the time of the call, then wait until it is caught up with the provider's changes up to
/// the time of the call.
///
/// The completion handler is called when both sets of changes are caught up to at least the time
/// of the call. This is useful to enforce a consistent state for testing.
#[unsafe(method(waitForStabilizationWithCompletionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn waitForStabilizationWithCompletionHandler(
&self,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
);
}
/// [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileprovidermanagerdisconnectionoptions?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSFileProviderManagerDisconnectionOptions(pub NSUInteger);
bitflags::bitflags! {
impl NSFileProviderManagerDisconnectionOptions: NSUInteger {
#[doc(alias = "NSFileProviderManagerDisconnectionOptionsTemporary")]
const Temporary = 1<<0;
}
}
unsafe impl Encode for NSFileProviderManagerDisconnectionOptions {
const ENCODING: Encoding = NSUInteger::ENCODING;
}
unsafe impl RefEncode for NSFileProviderManagerDisconnectionOptions {
const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}
/// Disconnection.
impl NSFileProviderManager {
extern_methods!(
#[cfg(feature = "block2")]
#[unsafe(method(disconnectWithReason:options:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn disconnectWithReason_options_completionHandler(
&self,
localized_reason: &NSString,
options: NSFileProviderManagerDisconnectionOptions,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
#[cfg(feature = "block2")]
#[unsafe(method(reconnectWithCompletionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn reconnectWithCompletionHandler(
&self,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
);
}
/// Materialize.
impl NSFileProviderManager {
extern_methods!(
#[cfg(all(feature = "NSFileProviderItem", feature = "block2"))]
/// Request that the system schedule a download for an item.
///
/// The completion handler is called when the system acknowledges the download request,
/// or with an error indicating why it didn't (e.g NSFileProviderErrorNoSuchItem.)
/// The system will then call -fetchContentsForItemWithIdentifier at the earliest
/// convenient time.
///
/// Set rangeToMaterialize to NSMakeRange(offset, nbytes) to request a partial download.
/// The system will then invoke -fetchPartialContentsForItemWithIdentifier instead of
/// fetchContentsForItemWithIdentifier. For a full download, set rangeToMaterialize to
/// NSMakeRange(NSNotFound, 0). -[NSFileProviderManager evictItemWithIdentifier:completionHandler:]
/// must be called on a partially materialized file before requesting an extent to be downloaded from a
/// later version of the file.
///
/// This method cannot be used to download directories recursively. When invoked on a
/// dataless directory, it will trigger an enumeration of the directory, causing a
/// materialization of the directory one level down only. All the children of the
/// directory will remain dataless after the enumeration.
#[unsafe(method(requestDownloadForItemWithIdentifier:requestedRange:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn requestDownloadForItemWithIdentifier_requestedRange_completionHandler(
&self,
item_identifier: &NSFileProviderItemIdentifier,
range_to_materialize: NSRange,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
);
}
/// StateDirectory.
impl NSFileProviderManager {
extern_methods!(
/// A directory suitable for storing state information for the domain.
///
/// The returned URL is guaranteed to be on the same volume as the user visible URL and the temporary URL, making sure
/// the system can atomatically clone/move files from that location to the user visible URL.
/// The caller is responsible for managing the security scope of the returned URL.
///
/// When syncing a domain on an external volume, all information about the sync state must be kept in this directory
/// if the volume is to be shared between multiple machines.
///
/// If the system cannot find a suitable directory, this call will fail. This could happen e.g. if the domain
/// does not exist or is in instance of initialization.
///
/// This call will not fail when called from the extension process with an active instance of the extension
/// for that domain unless the domain is being setup for the very first time (meaning it never existed).
///
/// Removing the domain will remove the corresponding directory along with it.
#[unsafe(method(stateDirectoryURLWithError:_))]
#[unsafe(method_family = none)]
pub unsafe fn stateDirectoryURLWithError(
&self,
) -> Result<Retained<NSURL>, Retained<NSError>>;
);
}
/// [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileprovidervolumeunsupportedreason?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSFileProviderVolumeUnsupportedReason(pub NSUInteger);
bitflags::bitflags! {
impl NSFileProviderVolumeUnsupportedReason: NSUInteger {
#[doc(alias = "NSFileProviderVolumeUnsupportedReasonNone")]
const None = 0;
#[doc(alias = "NSFileProviderVolumeUnsupportedReasonUnknown")]
const Unknown = 1<<0;
#[doc(alias = "NSFileProviderVolumeUnsupportedReasonNonAPFS")]
const NonAPFS = 1<<1;
#[doc(alias = "NSFileProviderVolumeUnsupportedReasonNonEncrypted")]
const NonEncrypted = 1<<2;
#[doc(alias = "NSFileProviderVolumeUnsupportedReasonReadOnly")]
const ReadOnly = 1<<3;
#[doc(alias = "NSFileProviderVolumeUnsupportedReasonNetwork")]
const Network = 1<<4;
#[doc(alias = "NSFileProviderVolumeUnsupportedReasonQuarantined")]
const Quarantined = 1<<5;
}
}
unsafe impl Encode for NSFileProviderVolumeUnsupportedReason {
const ENCODING: Encoding = NSUInteger::ENCODING;
}
unsafe impl RefEncode for NSFileProviderVolumeUnsupportedReason {
const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}
/// ExternalDomain.
impl NSFileProviderManager {
extern_methods!(
/// Check if a URL is eligible for storing a domain.
///
/// This returns whether the check has been performed succesfully - NOT whether the drive is eligible.
///
/// If an error was encountered while checking, this method returns FALSE and an error describing
/// the problem will be set.
///
/// The eligible parameter will contain the result of the check and indicate whether the volume can be
/// used to store FP domains. Its value is only defined if the call returns YES.
///
/// The url can be any existing and accessible URL on the volume for which you want to assess eligibility.
/// The checks are volume-wide and the exact location on the volume doesn't impact them.
///
/// If a drive is eligible, unsupportedReason will be empty (0). Otherwise it will contain the list of identified
/// conditions that currently prevent this drive from being used to store FP domains.
///
/// # Safety
///
/// - `eligible` must be a valid pointer.
/// - `unsupported_reason` must be a valid pointer or null.
#[unsafe(method(checkDomainsCanBeStored:onVolumeAtURL:unsupportedReason:error:_))]
#[unsafe(method_family = none)]
pub unsafe fn checkDomainsCanBeStored_onVolumeAtURL_unsupportedReason_error(
eligible: NonNull<Bool>,
url: &NSURL,
unsupported_reason: *mut NSFileProviderVolumeUnsupportedReason,
) -> Result<(), Retained<NSError>>;
);
}
/// Diagnostics.
impl NSFileProviderManager {
extern_methods!(
#[cfg(all(feature = "NSFileProviderItem", feature = "block2"))]
/// Request diagnostics collection for the item.
///
/// This will prompt the user about an issue with the sync in the provider and ask their permission
/// to collection diagnostic information and to send them to Apple for further analysis.
///
/// This call is to be used wisely with care given there's global throttling on it preventing
/// spamming the users. Furthermore it should be used in collaboration with Apple when you
/// detect a misbehavior in the sync in your provider likely caused by a system bug and you need to
/// work with Apple in order to resolve it.
///
/// This will return whether the call was allowed or not - not if it suceed
/// This method will only return an error if the user was not on a Seed build
///
/// It is mandatory to provide an error for the item why the collection is requested.
/// The error won't be shown to the user (a generic message will be shown instead)
/// It will surface in the generated report though
///
/// It is important to note that even if the call is allowed, it might not trigger diagnostic collection
/// nor prompt to the user depending on the system state and other throttling parameters
#[unsafe(method(requestDiagnosticCollectionForItemWithIdentifier:errorReason:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn requestDiagnosticCollectionForItemWithIdentifier_errorReason_completionHandler(
&self,
item_identifier: &NSFileProviderItemIdentifier,
error_reason: &NSError,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
);
);
}