objc2-file-provider 0.3.2

Bindings to the FileProvider framework
Documentation
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
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
//! 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::*;
#[cfg(feature = "objc2-core-foundation")]
use objc2_core_foundation::*;
use objc2_foundation::*;

use crate::*;

/// Options passed on item creation.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileprovidercreateitemoptions?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSFileProviderCreateItemOptions(pub NSUInteger);
bitflags::bitflags! {
    impl NSFileProviderCreateItemOptions: NSUInteger {
/// The imported item may already exist.
///
/// This can happen because:
///
/// 1. The imported item was found on disk after the synchronisation state was
/// lost, for example following the restoration of a backup, or the migration
/// to a new device.
///
/// 2. Two directories are merged together, due to the extension returning
/// the same itemIdentifier for both directories on the createItem completion handler.
/// Each child resulting of the merge may be recreated with the
/// mayAlreadyExist option. This allows the extension to recursively merge
/// directories.
///
/// The Extension should assess whether the item could actually be a disk
/// representation of an already existing item.
///
/// The best user experience is to match the requested item to one on the server,
/// if the extension is able to confirm that the disk item is representing an item already on
/// the server.
///
/// Given that this flag may be set when the system is reimporting all items from disk,
/// it is advised that the Extension attempts assessment methods for each item
/// in order from cheapest to most expensive (in terms of CPU and network), in order
/// to avoid unnecessary work.
///
/// When all the items pending reimport have been processed, the system
/// will call -[NSFileProviderExtension importDidFinishWithCompletionHandler:].
        #[doc(alias = "NSFileProviderCreateItemMayAlreadyExist")]
        const MayAlreadyExist = 1<<0;
/// This item is recreated after the system failed to apply a deletion requested
/// by the extension because the item was found to be edited locally.
/// This happens only if the edit wasn't yet known by the system at the time the
/// deletion was requested.
        #[doc(alias = "NSFileProviderCreateItemDeletionConflicted")]
        const DeletionConflicted = 1<<1;
    }
}

unsafe impl Encode for NSFileProviderCreateItemOptions {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

unsafe impl RefEncode for NSFileProviderCreateItemOptions {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// Options passed on item deletion.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderdeleteitemoptions?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSFileProviderDeleteItemOptions(pub NSUInteger);
bitflags::bitflags! {
    impl NSFileProviderDeleteItemOptions: NSUInteger {
/// The deletion of the item is recursive.
        #[doc(alias = "NSFileProviderDeleteItemRecursive")]
        const Recursive = 1<<0;
    }
}

unsafe impl Encode for NSFileProviderDeleteItemOptions {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

unsafe impl RefEncode for NSFileProviderDeleteItemOptions {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// NSFileProviderMaterializationFlags are used to inform the system about specific conditions
/// that apply to the content retrieved by the provider in fetchPartialContentsForItemWithIdentifier.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileprovidermaterializationflags?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSFileProviderMaterializationFlags(pub NSUInteger);
bitflags::bitflags! {
    impl NSFileProviderMaterializationFlags: NSUInteger {
/// By default, the system will track which parts of the returned file are sparse; those parts will remain non-materialized
/// and trigger subsequent calls to the materialization methods on access. Returning this flag will instead cause the entire
/// file to be marked as materialized. This is useful if the resulting file is known to contain sparse parts,
/// and all the remaining parts have been filled in.
/// This flag is ignored if the provided range doesn't cover the entire file (ie. [0, EOF]).
/// This flag is not functional prior to macOS 13.3.
        #[doc(alias = "NSFileProviderMaterializationFlagsKnownSparseRanges")]
        const KnownSparseRanges = 1<<0;
    }
}

unsafe impl Encode for NSFileProviderMaterializationFlags {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

unsafe impl RefEncode for NSFileProviderMaterializationFlags {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// Used by the system to express options and constraints to the provider in fetchPartialContentsForItemWithIdentifier.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderfetchcontentsoptions?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSFileProviderFetchContentsOptions(pub NSUInteger);
bitflags::bitflags! {
    impl NSFileProviderFetchContentsOptions: NSUInteger {
/// Set by the system to inform the provider that any other content version than the requested one
/// will be discarded.
/// If the provider cannot supply this version, it should fail with NSFileProviderErrorVersionNoLongerAvailable.
        #[doc(alias = "NSFileProviderFetchContentsOptionsStrictVersioning")]
        const StrictVersioning = 1<<0;
    }
}

unsafe impl Encode for NSFileProviderFetchContentsOptions {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

unsafe impl RefEncode for NSFileProviderFetchContentsOptions {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderenumerating?language=objc)
    pub unsafe trait NSFileProviderEnumerating: NSObjectProtocol {
        #[cfg(all(
            feature = "NSFileProviderEnumerating",
            feature = "NSFileProviderItem",
            feature = "NSFileProviderRequest"
        ))]
        /// Create an enumerator for an item.
        ///
        /// This method is called when the user lists the content of folder it never accessed
        /// before. This can happen either when using Finder or when listing the content of
        /// the directory from a Terminal (for instance using the `ls` command line tool). The
        /// system will use the enumerator to list the children of the directory by calling
        /// -[NSFileProviderEnumerator enumerateItemsForObserver:startingAtPage:] until nil
        /// is passed to -[NSFileProviderEnumerationObserver finishEnumeratingUpToPage:].
        /// Once this has been called, the directory and its children should be included in the
        /// working set.
        ///
        /// This is also used to subscribe to live updates for a single document.
        ///
        /// The system will keep an enumerator open in the extension on directories that are
        /// presented to the user (for instance, in Finder), and on document on which an application
        /// has a NSFilePresenter. The provider can use the existence of that enumerator as a hint
        /// that the user is actively seeing / using the item in question, and prioritize the delivery
        /// of updates on the item or its children in the working set.
        ///
        /// If returning nil, you must set the error out parameter.
        ///
        /// Working set enumerator:
        /// -----------------------
        /// The working set enumerator is a special enumerator (NSFileProviderWorkingSetContainerItemIdentifier)
        /// the system uses to detect changes that should be synced to the disk and/or searchable
        /// in Spotlight. Because that enumerator is by definition used for change detection, the
        /// working set enumerator must implement
        /// -[NSFileProviderEnumerator enumerateChangesForObserver:fromSyncAnchor:] and
        /// -[NSFileProviderEnumerator currentSyncAnchorWithCompletionHandler:].
        ///
        /// The system guarantees that it has a single consumer for the working set. This means there
        /// will never be two concurrent enumerations of the working set and will always do forward
        /// progress: the system will only ask for changes from the last requested sync anchor or
        /// the last returned sync anchor and the extension should be prepared for it.
        ///
        /// The expiration of the sync anchor of the working set will cause a very expensive scan
        /// of all the items known by the system.
        ///
        /// The system ingests the changes from the working set and applies the changes to the
        /// disk replicate and the spotlight index. Before ingesting the update for an item,
        /// the system will check if the enumeration of the item races against a call to
        /// createItemBasedOnTemplate, modifyItem, ... that may affect the item. If a potential race
        /// is detected, the system will call itemForItemIdentifier in order to resolve the race.
        ///
        /// If the provider exposes the key NSExtensionFileProviderAppliesChangesAtomically with value
        /// YES in its Info.plist, it is considered to apply the changes atomically, in which case the
        /// system does not need to check for potential races.
        ///
        /// Execution time:
        /// ---------------
        /// The system expects this call to complete quickly, it should build the object that will be
        /// used for enumeration and return it. The enumeration logic should happen when the system
        /// calls `-[NSFileProviderEnumerator enumerateItemsForObserver:startingAtPage:]` or
        /// `-[NSFileProviderEnumerator enumerateChangesForObserver:fromSyncAnchor:]`.
        ///
        /// Error cases:
        /// ------------
        /// If containerItemIdentifier is NSFileProviderTrashContainerItemIdentifier and
        /// the extension does not support trashing items, then it should fail the call
        /// with the NSFeatureUnsupportedError error code from the NSCocoaErrorDomain
        /// domain.
        ///
        /// If the item requested containerItemIdentifier does not exist in the provider,
        /// the extension should fail with NSFileProviderErrorNoSuchItem. In that case,
        /// the system will consider the item has been deleted and attempt to delete the
        /// item from disk.
        ///
        /// The extension can also report the NSFileProviderErrorNotAuthenticated,
        /// NSFileProviderErrorServerUnreachable in case the item cannot be fetched
        /// because of the current state of the system / domain. In that case, the
        /// system will present an appropriate error message and back off until the
        /// next time it is signalled.
        ///
        /// Any other error, including crashes of the extension process, will be considered to be transient
        /// and will cause the enumeration to be retried.
        ///
        /// Errors must be in one of the following domains: NSCocoaErrorDomain, NSFileProviderErrorDomain.
        ///
        /// For errors which can not be represented using an existing error code in one of these domains, the extension
        /// should construct an NSError with domain NSCocoaErrorDomain and code NSXPCConnectionReplyInvalid.
        /// The extension should set the NSUnderlyingErrorKey in the NSError's userInfo to the error which could not
        /// be represented.
        #[unsafe(method(enumeratorForContainerItemIdentifier:request:error:_))]
        #[unsafe(method_family = none)]
        unsafe fn enumeratorForContainerItemIdentifier_request_error(
            &self,
            container_item_identifier: &NSFileProviderItemIdentifier,
            request: &NSFileProviderRequest,
        ) -> Result<Retained<ProtocolObject<dyn NSFileProviderEnumerator>>, Retained<NSError>>;
    }
);

extern_protocol!(
    /// FileProvider extension for which the system replicates the content on disk.
    ///
    /// The extension exposes a hierarchy of NSFileProviderItem instances that the system
    /// will replicate on disk as a file hierarchy. The file hierarchy reflects the filename,
    /// parent, content, and metadata described by the NSFileProviderItem. In case two items
    /// are at the same disk location (same parent and filename), the system may choose to
    /// "bounce" an item.
    ///
    /// The system lazily replicates the item hierarchy: items are created "dataless" on disk
    /// and the content (for files) or list of children (for folders) is fetched on first
    /// access by calling fetchContentsForItemWithIdentifier, or enumeratorForContainerItemIdentifier.
    ///
    /// The provider can notify the system of changes on the items by publishing those on the
    /// enumerator for the working set. The system notifies the extension of changes made by the
    /// user on disk by calling createItemBasedOnTemplate, modifyItem, or deleteItemWithIdentifier.
    ///
    /// Concurrency:
    /// ------------
    /// A replicated extension class must be prepared to handle multiple concurrent calls since the
    /// system may perform several concurrent operations (for instance, modifying an item, while enumerating
    /// the working set, creating another item, and fetching the contents of yet another item).
    ///
    /// The system has limits to the number of concurrent operations.When the number of concurrent
    /// operations is reached, the system will not schedule additional operations falling in that category
    /// until at least one of the running operation has completed by calling its completion handler.
    ///
    /// The system currently separates the operations into the following categories:
    /// - enumeration of the working set. At most 1 enumeration of the working set can happen at a given time
    /// - downloads. The system has a per-domain limit on the number of concurrent calls to fetchContents and similar calls.
    /// That limit is configurable by setting the NSExtensionFileProviderDownloadPipelineDepth key to an integer
    /// value (between 1 and 128) in the Info.plist of the extension.
    /// The configuration key is honored starting in macOS 11.0 and iOS 16.0.
    /// - uploads. The system has a per-domain limit on the number of concurrent calls to createItemBasedOnTemplate and
    /// modifyItem when the call includes new content to be uploaded.
    /// That limit is configurable by setting the NSExtensionFileProviderUploadPipelineDepth key to an integer value
    /// (between 1 and 128) in the Info.plist of the extension.
    /// The configuration key is honored starting in macOS 12.0 and iOS 16.0.
    /// - metadata-only uploads. The system has a per-domain limit on the number of concurrent calls to createItemBasedOnTemplate
    /// and modifyItem when the call does not include new content to be uploaded.
    /// That limit is configurable by setting the NSExtensionFileProviderMetadataOnlyUploadPipelineDepth key to an
    /// integer value (between 1 and 128) in the Info.plist of the extension.
    /// The configuration key is honored starting in macOS 15.0 and iOS 18.0.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderreplicatedextension?language=objc)
    pub unsafe trait NSFileProviderReplicatedExtension:
        NSObjectProtocol + NSFileProviderEnumerating
    {
        #[cfg(feature = "NSFileProviderDomain")]
        /// Create a new instance of the replicated provider for the specified domain.
        #[unsafe(method(initWithDomain:))]
        #[unsafe(method_family = init)]
        unsafe fn initWithDomain(
            this: Allocated<Self>,
            domain: &NSFileProviderDomain,
        ) -> Retained<Self>;

        /// Called before the instance is discarded.
        ///
        /// Several instances of a replicated provider can be hosted by the same process, either because
        /// the user has several active domains, or because an instance got discarded and a new one
        /// is created by the system. This method is called before an instance is discarded and should
        /// make sure that all references to the instance are released so that the instance can be
        /// deallocated.
        #[unsafe(method(invalidate))]
        #[unsafe(method_family = none)]
        unsafe fn invalidate(&self);

        #[cfg(all(
            feature = "NSFileProviderItem",
            feature = "NSFileProviderRequest",
            feature = "block2"
        ))]
        /// Fetch the metadata for the item with the provider identifier.
        ///
        /// Error cases:
        /// ------------
        /// If the metadata lookup fails because the item is unknown, the call should
        /// fail with the NSFileProviderErrorNoSuchItem error. In that case, the system
        /// will consider the item has been removed from the domain and will attempt to
        /// delete it from disk. In case that deletion fails because there are local
        /// changes on this item, the system will re-create the item using createItemBasedOnTemplate.
        ///
        /// The extension can also report the NSFileProviderErrorNotAuthenticated,
        /// NSFileProviderErrorServerUnreachable in case the item cannot be fetched
        /// because of the current state of the system / domain. In that case, the
        /// system will present an appropriate error message and back off until the
        /// next time it is signalled.
        ///
        /// Any other error, including crashes of the extension process, will be considered to be
        /// transient and will cause the lookup to be retried.
        ///
        /// Errors must be in one of the following domains: NSCocoaErrorDomain, NSFileProviderErrorDomain.
        ///
        /// For errors which can not be represented using an existing error code in one of these domains, the extension
        /// should construct an NSError with domain NSCocoaErrorDomain and code NSXPCConnectionReplyInvalid.
        /// The extension should set the NSUnderlyingErrorKey in the NSError's userInfo to the error which could not
        /// be represented.
        ///
        /// Cancellations:
        /// ------------
        /// If the NSProgress returned by this method is cancelled, the extension should
        /// call the completion handler with (nil, NSUserCancelledError) in the NSProgress
        /// cancellation handler.
        ///
        /// Execution time:
        /// ---------------
        /// This method is not expected to take more than a few seconds to complete the retrieval of the
        /// metadata of the item. If the operation may not complete in a reasonable amount of time because,
        /// for instance, of bad network conditions, it is recommended to report an error (for instance
        /// NSFileProviderErrorServerUnreachable). The system will call `cancel` on the progress if the
        /// operation takes too much time. The extension is then expected to quickly call the completion
        /// handler.
        #[unsafe(method(itemForIdentifier:request:completionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn itemForIdentifier_request_completionHandler(
            &self,
            identifier: &NSFileProviderItemIdentifier,
            request: &NSFileProviderRequest,
            completion_handler: &block2::DynBlock<dyn Fn(*mut NSFileProviderItem, *mut NSError)>,
        ) -> Retained<NSProgress>;

        #[cfg(all(
            feature = "NSFileProviderItem",
            feature = "NSFileProviderRequest",
            feature = "block2"
        ))]
        /// Download the item for the given identifier and return it via the completion handler.
        ///
        /// The system learns of items through enumerations. Initially, this means that the
        /// system is aware that an item (with a specific version) exists on the device.
        ///
        /// When the user accesses the item, the system makes a request for the contents of
        /// the item. The provider can then fulfill the request by providing the item.
        ///
        /// The system takes ownership of the item and will move it out of the sandbox of
        /// the provider.
        ///
        /// If the provider wishes to force materialization of a given item, the provider should use
        /// `-[NSFileProviderManager requestDownloadForItemWithIdentifier:requestedRange:completionHandler:]`,
        /// or configure the `-[NSFileProviderItem contentPolicy]`.
        ///
        /// The requestedVersion parameter specifies which version should be returned. A nil value
        /// means that the latest known version should be returned. Except for the error case, the
        /// version of the returned item is assumed to be identical to what was requested.
        ///
        /// requestedVersion is currently always set to nil.
        ///
        /// Concurrent Downloads:
        /// ----------
        /// The system will call fetchContents concurrently if there are multiple outstanding file download requests.
        /// The provider can control the concurrency by setting the key NSExtensionFileProviderDownloadPipelineDepth
        /// in the Info.plist of the extension to the number of concurrent downloads that the system should create
        /// per domain. This number must be between 1 and 128, inclusive.
        ///
        /// File ownership:
        /// ---------------
        /// The retrieved content at `fileContents` URL must be a regular file on the same volume as the user-visible URL.
        /// A suitable location can be retrieved using -[NSFileProviderManager temporaryDirectoryURLWithError:].
        /// The system clones and unlinks the received fileContents. The extension should not mutate the corresponding
        /// file after calling the completion handler. If the extension wishes to keep a copy of the content, it must
        /// provide a clone of the that content as the URL passed to the completion handler.
        ///
        /// In case the extension or the system crashes between the moment the completion handler is called and the
        /// moment the system unlinks the file, the file may unexpectedly still be on disk the next time an instance
        /// of the extension is created. The extension is then responsible for deleting that file.
        ///
        /// Disallowing processes from fetching items:
        /// ---------------
        ///
        /// The system automatically downloads files on POSIX accesses. The extension may wish to disallow this class of
        /// downloads for specific applications.
        ///
        /// The extension can set an array of strings into the UserDefault key
        /// "NSFileProviderExtensionNonMaterializingProcessNames". A process whose executable's filename on disk is an
        /// exact match for an entry in this array will not be allowed to fetch items in the extension's domains. The comparison
        /// is case sensitive.
        ///
        /// In macOS 11.0 and later, this list will be checked when a download is initiated through a POSIX filesystem call.
        /// In macOS 11.4 and later, this list will also be checked for downloads initiated through file coordination.
        ///
        /// Error cases:
        /// ------------
        /// If the download fails because the item was deleted on the server, the call should
        /// fail with the NSFileProviderErrorNoSuchItem error. In that case, the system
        /// will consider the item has been removed from the domain and will attempt to
        /// delete it from disk. In case that deletion fails because there are local
        /// changes on this item, the system will re-create the item using createItemBasedOnTemplate,
        /// passing the NSFileProviderCreateItemDeletionConflicted flag.
        ///
        /// If the user does not have access to the content of the file, the provider
        /// can fail the call with NSCocoaErrorDomain and code NSFileReadNoPermissionError.
        /// That error will then be presented to the user. The extension can also report
        /// the NSFileProviderErrorNotAuthenticated, NSFileProviderErrorServerUnreachable
        /// in case the item cannot be fetched because of the current state of the system / domain.
        /// In those cases, the system will present an appropriate error message and back off
        /// until the next time it is signalled.
        ///
        /// Any other error, including crashes of the extension process, will be considered to be transient
        /// and will cause the download to be retried.
        ///
        /// Errors must be in one of the following domains: NSCocoaErrorDomain, NSFileProviderErrorDomain.
        ///
        /// For errors which can not be represented using an existing error code in one of these domains, the extension
        /// should construct an NSError with domain NSCocoaErrorDomain and code NSXPCConnectionReplyInvalid.
        /// The extension should set the NSUnderlyingErrorKey in the NSError's userInfo to the error which could not
        /// be represented.
        ///
        /// Cancellations:
        /// ------------
        /// If the NSProgress returned by this method is cancelled, the extension should
        /// call the completion handler with (nil, nil, NSUserCancelledError) in the NSProgress
        /// cancellation handler.
        ///
        /// The returned NSProgress is used to show progress to the user. If the user cancels the
        /// fetch, the extension should stop fetching the item, as it is no longer required.
        ///
        /// Execution time:
        /// ---------------
        /// The system will grant enough time to the extension to download the file. The system will interrupt the
        /// call if it stops making progress or if download takes an unexpectedly long time. In that case, the system
        /// will call `cancel` on the progress. The extension is then expected to quickly call the completion
        /// handler.
        #[unsafe(method(fetchContentsForItemWithIdentifier:version:request:completionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn fetchContentsForItemWithIdentifier_version_request_completionHandler(
            &self,
            item_identifier: &NSFileProviderItemIdentifier,
            requested_version: Option<&NSFileProviderItemVersion>,
            request: &NSFileProviderRequest,
            completion_handler: &block2::DynBlock<
                dyn Fn(*mut NSURL, *mut NSFileProviderItem, *mut NSError),
            >,
        ) -> Retained<NSProgress>;

        #[cfg(all(
            feature = "NSFileProviderItem",
            feature = "NSFileProviderRequest",
            feature = "block2"
        ))]
        /// Create a new item.
        ///
        /// The itemTemplate object describes the expected state of the newly created item,
        /// including its location provided by parentItemIdentifier and filename. The list
        /// of fields to conside in that object is defined by the fields parameter. Fields
        /// not listed should be considered as not being defined.
        ///
        /// The url is used to transfer the content of the file from the system to the
        /// extension. It can be nil if the item has no content. This will be the case if
        /// the item is a folder or if the item is being reimported (flag
        /// NSFileProviderCreateItemMayAlreadyExist set) and the file is dataless on disk.
        /// If the item is a symbolic link, the target path is provided by the symlinkTargetPath
        /// of the itemTemplate.
        ///
        /// The system is setting the itemIdentifier of the itemTemplate to a unique value that
        /// is guaranteed to stay the same for a given item in case the creation is replayed
        /// after a crash. That itemIdentifier is not intended to be the identifier assigned
        /// to the item by the provider.
        ///
        /// In the completion block, the createdItem is expected to reflect the properties of the
        /// newly created item, which usually means matching the properties passed in by the
        /// template. An exception is the itemIdentifier which should be the identifier assigned
        /// to that item by the provider rather than the identifier passed in through the template.
        /// If the provider reuses an existing identifier, the item that used that identifier will
        /// be removed from disk, replaced by the createdItem. If the item is a directory, the two
        /// directories will be merged and the items from the existing one will be modified with
        /// the NSFileProviderModifyItemMayAlreadyExist option set.
        ///
        /// If the provider is not able to apply all the fields at once, it should return a
        /// set of stillPendingFields in its completion handler. In that case, the system will
        /// attempt to modify the item later by calling modifyItem with those fields.
        ///
        /// The filename and contents fields should be synced together.
        /// If synced independently, files may appear corrupted on other devices, due to
        /// a mismatch between the file extension and the actual file data.
        ///
        /// If a field in the returned createdItem does not match the itemTemplate, and is
        /// not in the list of stillPendingFields, the value from the createdItem will be
        /// propagated to the disk. If the content of the item as described by createdItem
        /// does not match the content from url, the provider should set shouldFetchContent
        /// in the completion handler. The content from the provider will then be fetched
        /// and propagated to disk.
        ///
        /// In case the deletion of an item from the working set could not be applied to the
        /// disk by the system because it conflicted with a local edit of the file, the system
        /// will attempt to create the edited item. In that case the creation call will receive
        /// the NSFileProviderCreateItemDeletionConflicted option and the itemIdentifier in the
        /// template will be set to the itemIdentifier of the item deleted from the working set.
        /// The itemVersion will also be set to the last itemVersion of the item that was made
        /// available on disk before the item was edited locally. If such a conflict happens
        /// on a dataless item on disk, the item will be immediately deleted from the disk instead
        /// of issuing a new creation.
        ///
        /// In case the NSFileProviderCreateItemMayAlreadyExist option
        /// is passed, the content may be nil if the item is found by the system without any
        /// associated content. In that case, you should return a nil item if you are not
        /// able to match the created item with an existing item from the provider.
        ///
        /// In case of path collision with an already existing item, the provider
        /// can either fail using -[NSError (NSFileProviderError) fileProviderErrorForCollisionWithItem:]
        /// or resolve the collision by itself (e.g. by returning an item with a different name).
        /// If the error is returned, the system will try to resolve the collision by itself by bouncing
        /// away one of the items (renaming the item).
        ///
        /// If the imported item is refused by the extension, it should return nil for the
        /// createdItem without any error. In that case, the source item will be deleted
        /// from disk. In case the item represents a directory, the content will be deleted
        /// recursively.
        ///
        /// If the extension does not wish to sync the item, while still
        /// keeping the item on disk, on macOS 13.0, iOS 16.0, and later,
        /// it should return `NSFileProviderErrorExcludedFromSync`
        /// on the completion handler. For more details, see the header comment for that
        /// error code.
        /// On earlier versions of macOS, where `NSFileProviderErrorExcludedFromSync` is
        /// unavailable, the extension could choose to respond to FileProvider API calls as
        /// if the item is synced to it's server, but the extension only tracks the item
        /// in it's own local database on the device. The extension must be careful to respond to
        /// all FileProvider API calls as if the file is really synced to it's server, including
        /// enumerations of the parent directory of that item, itemForIdentifier calls, etc.
        ///
        /// The progress returned by createItemBasedOnTemplate is expected to include the
        /// upload progress of the item and will be presented in the user interface until
        /// the completion handler is called.
        ///
        /// Creation is gated by the NSFileProviderItemCapabilitiesAllowsAddingSubItems
        /// capability on the parent folder on a UI level, but direct file system changes
        /// (e.g. from Terminal) can still result in changes that must be handled.
        ///
        /// Structural consistency:
        /// -----------------------
        /// The system guarantees that the creation is called after the creation of the
        /// parent completed.
        ///
        /// File ownership:
        /// ---------------
        /// The file at `url` is owned by the system and is unlinked after the completion
        /// handler is called. If the extension wishes to keep access to the content of
        /// file after calling the completion handler, it should clone the file in its
        /// container.
        ///
        /// Atomicity:
        /// ----------
        /// By default, the system assumes all the changes are applied non-atomically, which
        /// means that the change or an intermediary state from the change can be observed
        /// (for instance while enumerating the working set) while the call is in progress
        /// (before the completion handler is called). The provider can indicate to the system
        /// that it applies changes atomically (that is, the change cannot be observed before
        /// the completion handler is called) by setting the key NSExtensionFileProviderAppliesChangesAtomically
        /// in the Info.plist of the extension to YES.
        ///
        /// The atomicity declaration only describes the visibility of the changes, not
        /// the ability of the provider to apply all the fields at once: a provider that applies
        /// changes atomically might still apply a subset of the changedFields communicated
        /// by the system and defer the remaining fields by setting the stillPendingFields
        /// parameter in the completion handler.
        ///
        /// Error cases:
        /// ------------
        /// If the creation fails because the target directory does not exist, the extension
        /// must fail the creation using the NSFileProviderErrorNoSuchItem error code. In
        /// that case, the system will attempt the re-create the parent directory.
        ///
        /// In case the location of the new item is already in use by another item, the extension
        /// can chose to either resolve the collision by moving one of the items
        /// away, or reject the creation with the NSFileProviderErrorFilenameCollision
        /// error code. In that error case, the system will be responsible for resolving the
        /// collision, by renaming one of the colliding items. When the collision is resolved,
        /// the system will call createItemBasedOnTemplate again.
        ///
        /// The extension can also report NSFileProviderErrorNotAuthenticated,
        /// NSFileProviderErrorCannotSynchronize, or NSFileProviderErrorExcludedFromSync,
        /// in case the modification cannot be applied because of the current state of the
        /// system / domain. In that case, the system will present an appropriate error message
        /// and back off until the next time it is signalled. The provider can signal the error
        /// resolution by calling signalErrorResolved:completionHandler:.
        ///
        /// Any other error, including crashes of the extension process, will be considered to be transient
        /// and will cause the creation to be retried.
        ///
        /// Errors must be in one of the following domains: NSCocoaErrorDomain, NSFileProviderErrorDomain.
        ///
        /// For errors which can not be represented using an existing error code in one of these domains, the extension
        /// should construct an NSError with domain NSCocoaErrorDomain and code NSXPCConnectionReplyInvalid.
        /// The extension should set the NSUnderlyingErrorKey in the NSError's userInfo to the error which could not
        /// be represented.
        ///
        /// Cancellations:
        /// ------------
        /// If the NSProgress returned by this method is cancelled, the extension should
        /// call the completion handler with (nil, [], NO, NSUserCancelledError) in the NSProgress
        /// cancellation handler.
        ///
        /// Execution time:
        /// ---------------
        /// The system will grant enough time to the extension to upload the file if content is passed to the call,
        /// otherwise the call is expected to completed within a few seconds. The system will interrupt the
        /// call if it stops making progress or if upload takes an unexpectedly long time. In that case, the system
        /// will call `cancel` on the progress. The extension is then expected to quickly call the completion
        /// handler.
        #[unsafe(method(createItemBasedOnTemplate:fields:contents:options:request:completionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn createItemBasedOnTemplate_fields_contents_options_request_completionHandler(
            &self,
            item_template: &NSFileProviderItem,
            fields: NSFileProviderItemFields,
            url: Option<&NSURL>,
            options: NSFileProviderCreateItemOptions,
            request: &NSFileProviderRequest,
            completion_handler: &block2::DynBlock<
                dyn Fn(*mut NSFileProviderItem, NSFileProviderItemFields, Bool, *mut NSError),
            >,
        ) -> Retained<NSProgress>;

        #[cfg(all(
            feature = "NSFileProviderItem",
            feature = "NSFileProviderModifyItemOptions",
            feature = "NSFileProviderRequest",
            feature = "block2"
        ))]
        /// Informs the provider that an item or its metadata have changed. More than one
        /// property may have changed, e.g.  an item may have been renamed, moved and also
        /// changed contents, in which case changedFields might contain [.contents,
        /// .filename, .parentItemIdentifier, .contentModificationDate].
        ///
        /// If the provider is not able to apply all the fields at once, it should return a
        /// set of stillPendingFields in its completion handler. In that case, the system will
        /// attempt to modify the item later by calling modifyItem with those fields.
        ///
        /// The filename and contents fields should be synced together.
        /// If synced independently, files may appear corrupted on other devices, due to
        /// a mismatch between the file extension and the actual file data.
        ///
        /// Starting in macOS 12.0, if the set of stillPendingFields returned by the provider is
        /// identical to the set of fields passed to modifyItem, then the system will consider that these fields
        /// are not supported by the provider. The system will not send these fields to the provider again,
        /// until the item is modified.
        ///
        /// If a field in the returned item does not match the itemTemplate, and is
        /// not in the list of stillPendingFields, the value from the item will be
        /// propagated to the disk. In case there is a content change and the content of
        /// the returned item as described by item does not match the content from url,
        /// the provider should set shouldFetchContent in the completion handler. The
        /// content from the provider will then be fetched and propagated to disk.
        ///
        /// If the item modification results from the parent directory being merged into another
        /// directory, the NSFileProviderModifyItemMayAlreadyExist flag will be passed
        /// to the call.
        ///
        /// The provider can chose to merge two existing items when receiving modifyItem. In that
        /// case, the item returned should carry the itemIdentifier of the item with which the
        /// item will be merged and well as the resulting state of that item. The system will then
        /// keep one of the items (the one whose itemIdentifier was returned) and remove
        /// the other one from disk. In case of directories, the content of the two directories
        /// is merged and sub-items will be modified with the
        /// NSFileProviderModifyItemMayAlreadyExist flag set.
        ///
        /// If the extension wishes the modify item to cause the deletion of the item on disk,
        /// it can call the completion handler with nil in place of the resulting item. If the
        /// item is directory, the item will be kept on disk until all its children has been deleted
        /// from the working set. The system will only apply the deletion on the disk if this
        /// does not conflict with local edits. Otherwise, the system will attempt to re-create
        /// the item with the NSFileProviderCreateItemDeletionConflicted option set.
        ///
        /// The progress returned by modifyItem is expected to include the upload progress if any,
        /// even if the provider chose to call the completion handler before the upload finishes.
        /// For example, the provider might decide to call the completion handler as soon as the
        /// metadata have been stored in a local database.
        ///
        /// Modifications are gated by the corresponding capabilities of the item on a UI level,
        /// but direct file system changes (e.g. from Terminal) can still result in changes that
        /// must be handled.
        ///
        /// Conflict resolution:
        /// -------------------
        /// The system passes a `baseVersion` parameter to the modifyItem call. This
        /// baseVersion describes the latest version of the file which was reflected on disk.
        /// This parameter can be used to detect conflicts with remote edits.
        ///
        /// For instance, if content version A of the file was downloaded to the local system, and
        /// the content was modified locally, the modifyItem call will receive baseVersion of A. If the server
        /// has in the meantime received another content edit of the same file, the server may
        /// have content version C. In this case, the extension can detect the mismatching baseVersion,
        /// and decide how to resolve the conflict. The extension informs the system of how it
        /// wishes to resolve the conflict by returning the resolved metadata on the completion handler.
        /// As an example resolution, if the extension informs that it wishes for the remote version
        /// of the item to be on disk (and to ignore the local edits), it should return the new
        /// contentVersion in the completion handler's item. The system will subsequently call
        /// fetchContents to retrieve the new contents and replace them on disk.
        ///
        /// The `baseVersion` might contain one or both component set to
        /// `+[NSFileProviderItemVersion beforeFirstSyncComponent]`, in case
        /// there has never been a version for which the item on disk and the item in the provider
        /// were known to be in sync.
        ///
        /// Structural consistency and Cycle handling:
        /// ------------------------------------------
        /// In case the parentItemIdentifier is modified, the system guarantees that the new
        /// parent has been created and the creation completed before the call to modifyItem
        /// is issued.
        ///
        /// The system guarantees that modifyItem called after local changes from the user will
        /// never create a cycle: that is all items will always be a descendent of either the
        /// root item or the trash item.
        ///
        /// However, cycles that are caused by concurrent local changes by the user and changes
        /// on the remote server can also create cycles. This is handled by the system as a
        /// conflict. This means the provider must validate that the call of modifyItem is not
        /// creating a cycle with a change it observed from the server. If such a cycle is
        /// detected, the provider must fix the conflict by breaking the cycle, and return the
        /// state of the item after resolving that conflict. If the resolution affects other
        /// items as well, updates for those other items must be published on the working set.
        ///
        /// File ownership:
        /// ---------------
        /// The file at `url` is owned by the system and is unlinked after the completion
        /// handler is called. If the extension wishes to keep access to the content of
        /// file after calling the completion handler, it should clone the file in its
        /// container.
        ///
        /// Atomicity:
        /// ----------
        /// By default, the system assumes all the changes are applied non-atomically, which
        /// means that the change or an intermediary state from the change can be observed
        /// (for instance while enumerating the working set) while the call is in progress
        /// (before the completion handler is called). The provider can indicate to the system
        /// that it applies changes atomically (that is, the change cannot be observed before
        /// the completion handler is called) by setting the key NSExtensionFileProviderAppliesChangesAtomically
        /// in the Info.plist of the extension to YES.
        ///
        /// The atomicity declaration only describes the visibility of the changes, not
        /// the ability of the provider to apply all the fields at once: a provider that applies
        /// changes atomically might still apply a subset of the changedFields communicated
        /// by the system and defer the remaining fields by setting the stillPendingFields
        /// parameter in the completion handler.
        ///
        /// Error cases:
        /// ------------
        /// The extension may fail the modification if the modified item does not exist
        /// anymore. In that case, the extension should fail the call the
        /// NSFileProviderErrorNoSuchItem error code. The system will attempt to delete
        /// the item on disk. If the item on disk actually has changes since this call
        /// to modifyItem, then it will be re-created by a call to createItemBasedOnTemplate.
        /// Likewise, if the item is reparented to a parent that no longer exists, the extension
        /// may return a NSFileProviderErrorNoSuchItem error with the parent item.
        ///
        /// In case the modification updates the location of the item and another item is
        /// already known at this location, the extension can chose to either resolve the
        /// collision by moving one of the items away, or reject the modification with
        /// the NSFileProviderErrorFilenameCollision error code. In that error case,
        /// the system will be responsible for resolving the collision, by renaming one of
        /// the colliding items. When the collision is resolved, the system will call
        /// modifyItem again.
        ///
        /// In case the NSFileProviderModifyItemFailOnConflict option is passed, the provider should
        /// fail the modification if the baseVersion does not match the version on the server. It
        /// will be up to the system to merge the conflict and call modifyItem again with an
        /// updated baseVersion.
        ///
        /// The extension can also report NSFileProviderErrorNotAuthenticated,
        /// NSFileProviderErrorCannotSynchronize, or NSFileProviderErrorExcludedFromSync,
        /// in case the modification cannot be applied because of the current state of the
        /// system / domain. In that case, the system will present an appropriate error message
        /// and back off until the next time it is signalled. The provider can signal the error
        /// resolution by calling signalErrorResolved:completionHandler:.
        ///
        /// Any other error, including crashes of the extension process, will be considered to be transient
        /// and will cause the modification to be retried.
        ///
        /// Errors must be in one of the following domains: NSCocoaErrorDomain, NSFileProviderErrorDomain.
        ///
        /// For errors which can not be represented using an existing error code in one of these domains, the extension
        /// should construct an NSError with domain NSCocoaErrorDomain and code NSXPCConnectionReplyInvalid.
        /// The extension should set the NSUnderlyingErrorKey in the NSError's userInfo to the error which could not
        /// be represented.
        ///
        /// Cancellations:
        /// ------------
        /// If the NSProgress returned by this method is cancelled, the extension should
        /// call the completion handler with (nil, [], NO, NSUserCancelledError) in the NSProgress
        /// cancellation handler.
        ///
        /// Execution time:
        /// ---------------
        /// The system will grant enough time to the extension to upload the file if content is passed to the call,
        /// otherwise the call is expected to completed within a few seconds. The system will interrupt the
        /// call if it stops making progress or if upload takes an unexpectedly long time. In that case, the system
        /// will call `cancel` on the progress. The extension is then expected to quickly call the completion
        /// handler.
        #[unsafe(method(modifyItem:baseVersion:changedFields:contents:options:request:completionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn modifyItem_baseVersion_changedFields_contents_options_request_completionHandler(
            &self,
            item: &NSFileProviderItem,
            version: &NSFileProviderItemVersion,
            changed_fields: NSFileProviderItemFields,
            new_contents: Option<&NSURL>,
            options: NSFileProviderModifyItemOptions,
            request: &NSFileProviderRequest,
            completion_handler: &block2::DynBlock<
                dyn Fn(*mut NSFileProviderItem, NSFileProviderItemFields, Bool, *mut NSError),
            >,
        ) -> Retained<NSProgress>;

        #[cfg(all(
            feature = "NSFileProviderItem",
            feature = "NSFileProviderRequest",
            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.
        ///
        /// This call receives an optional baseVersion which represent the version of the
        /// item we are trying to delete.
        ///
        /// Unless the NSFileProviderDeleteItemRecursive options is passed, the
        /// deletion of a directory should be non-recursive. If the deletion is recursive
        /// the provider should take care of reporting the deletion of all the deleted
        /// items through the working set.
        ///
        /// Delete is gated by the capabilities of the removed item with
        /// NSFileProviderItemCapabilitiesAllowsDeleting.
        ///
        /// Modifications are gated by NSFileProviderItemCapabilitiesAllowsDeleting
        /// of the item on a UI level, but direct file system changes (e.g. from Terminal)
        /// can still result in changes that must be handled.
        ///
        /// Atomicity:
        /// ----------
        /// By default, the system assumes all the changes are applied non-atomically, which
        /// means that the change or an intermediary state from the change can be observed
        /// (for instance while enumerating the working set) while the call is in progress
        /// (before the completion handler is called). The provider can indicate to the system
        /// that it applies changes atomically (that is, the change cannot be observed before
        /// the completion handler is called) by setting the key NSExtensionFileProviderAppliesChangesAtomically
        /// in the Info.plist of the extension to YES.
        ///
        /// Error cases:
        /// ------------
        /// The extension may fail the deletion in different scenarios, for instance because
        /// the baseVersion is out of date or because the user does not have permissions to
        /// delete the item. In that case the extension should fail the call with the
        /// NSFileProviderErrorDeletionRejected error code which will cause the system to
        /// re-create the deleted item on disk based on the latest metadata available from
        /// the extension.
        ///
        /// If the options don't include NSFileProviderDeleteItemRecursive and the
        /// deletion targets a non-empty directory, the extension must reject the deletion
        /// with the NSFileProviderErrorDirectoryNotEmpty error code. This error can also
        /// be reported in case some children of the directory cannot be deleted when
        /// receiving the NSFileProviderDeleteItemRecursive option. In both cases,
        /// the system will re-create the deleted item on disk based on the latest metadata
        /// available from the extension.
        ///
        /// If the deletion targets an item that is unknown from the extension because
        /// that item may have already been deleted remotely, then the extension should
        /// report a success.
        ///
        /// The extension can also report the NSFileProviderErrorNotAuthenticated,
        /// NSFileProviderErrorServerUnreachable, or NSFileProviderErrorCannotSynchronize
        /// in case the deletion cannot be applied because of the current state of the
        /// system / domain. In that case, the system will present an appropriate error
        /// message and back off until the next time it is signalled.
        ///
        /// Any other error, including crashes of the extension process, will be considered to be transient
        /// and will cause the deletion to be retried.
        ///
        /// Errors must be in one of the following domains: NSCocoaErrorDomain, NSFileProviderErrorDomain.
        ///
        /// For errors which can not be represented using an existing error code in one of these domains, the extension
        /// should construct an NSError with domain NSCocoaErrorDomain and code NSXPCConnectionReplyInvalid.
        /// The extension should set the NSUnderlyingErrorKey in the NSError's userInfo to the error which could not
        /// be represented.
        ///
        /// Cancellations:
        /// ------------
        /// If the NSProgress returned by this method is cancelled, the extension should
        /// call the completion handler with (NSUserCancelledError) in the NSProgress
        /// cancellation handler.
        ///
        /// Execution time:
        /// ---------------
        /// This call is not expected to take more than a few seconds to complete. The system will interrupt the
        /// call if it stops making progress or if the deletion takes an unexpectedly long time. In that case,the system
        /// will call `cancel` on the progress. The extension is then expected to quickly call the completion
        /// handler.
        #[unsafe(method(deleteItemWithIdentifier:baseVersion:options:request:completionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn deleteItemWithIdentifier_baseVersion_options_request_completionHandler(
            &self,
            identifier: &NSFileProviderItemIdentifier,
            version: &NSFileProviderItemVersion,
            options: NSFileProviderDeleteItemOptions,
            request: &NSFileProviderRequest,
            completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
        ) -> Retained<NSProgress>;

        #[cfg(feature = "block2")]
        /// Signal the end of import of on-disk items.
        ///
        /// This is called after a reimport of on-disk items has been triggered by either
        /// `-[NSFileProviderManager reimportItemsBelowItemWithIdentifier:completionHandler:]`
        /// or after a new domain is created using
        /// `+[NSFileProviderManager importDomain:fromDirectoryAtURL:completionHandler:]` or
        /// `+[NSFileProviderManager addDomain:completionHandler:]`.
        ///
        /// `reimport` can also be started by the system independently from any request by the
        /// provider. The provider can detect those events by monitoring
        /// `-[NSFileProviderDomain backingStoreIdentity]`.
        ///
        /// During import, found items will be created via the
        /// -[NSFileProviderExtension createItemBasedOnTemplate:fields:contents:options:completionHandler:]
        /// call with the NSFileProviderCreateItemMayAlreadyExist flag set.
        /// At the end of an import the -[NSFileProviderExtension importDidFinishWithCompletionHandler:]
        /// is called.
        ///
        /// The system will attempt to import items as they are accessed by the user or applications. Import
        /// of the other items is scheduled by the system as a background task. That task may be delayed,
        /// for instance in low-power situations, or when the system is under heavy load. The provider can
        /// force the system to process a folder and its direct children by issuing a coordination request
        /// on that folder.
        ///
        /// Execution time:
        /// ---------------
        /// This call is not expected to take more than a few seconds to complete.
        #[optional]
        #[unsafe(method(importDidFinishWithCompletionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn importDidFinishWithCompletionHandler(
            &self,
            completion_handler: &block2::DynBlock<dyn Fn()>,
        );

        #[cfg(feature = "block2")]
        /// Called by the system if the set of materialized items changes.
        ///
        /// Materialized items are items that have synced to disk and are not
        /// dataless.  They may contain a mix of dataless and materialized files and
        /// directories, but in any case, all their children are represented on disk.
        /// Traversals of dataless directories by applications trigger an enumeration
        /// against the file provider extension; traversals of materialized directories
        /// do not.  It is the responsability of the file provider extension to notify
        /// the system on remote changes of these files: there is no alternative cache
        /// invalidation mechanism.
        ///
        /// If the extension doesn't keep track of the materialized set, it will have to
        /// notify the system of all remote changes.  In that case the working set is the
        /// entire dataset.  The system may drop items whose parent isn't materialized, to
        /// avoid unnecessary disk usage.  This saves some I/O, but isn't optimal.  The
        /// filtering by parentItemIdentifier is better done in the extension;  ideally,
        /// it would even be done server-side.  A hybrid model is possible, where some
        /// filtering is done server-side, and some finer filtering is done client-side.
        ///
        /// The file provider extension should therefore keep a list of the identifiers of
        /// the materialized directories.  This method is called when a new directory is
        /// materialized or when a materialized directory is rendered dataless.
        ///
        /// To enumerate the set of materialized containers,
        /// - Call -enumeratorForMaterializedItems on the instance of
        /// NSFileProviderManager corresponding to your domain;
        /// - Implement the NSFileProviderEnumerationObserver and
        /// NSFileProviderChangeObserver on an object;
        /// - Pass that object to the enumerator;
        /// - Use the identifiers of items or changes you receive to note the
        /// materialization status in your database.
        ///
        /// When an item is created, modified or deleted remotely, the file provider
        /// extension should check whether its parentItemIdentifier is in the materialized
        /// set.  If it is, the extension needs to inform the system so the system may
        /// create, modify or delete the file or directory (initially dataless) on disk.
        /// In the case when an item is reparented, the test should be that either the new
        /// or the old parentItemIdentifier is in the materialized set.  No need to pretend
        /// that the iten was deleted if the new parentItemIdentifier is no longer in the
        /// materialized set: the system will know what to do with an unknown parent
        /// identifier.
        ///
        /// To notify the system of this created, modified or deleted item,
        /// - Call -signalEnumeratorForContainerItemIdentifier: on the working set, i.e the
        /// container identified by NSFileProviderWorkingSetContainerItemIdentifier;
        /// - Include this item in the next enumeration of the working set.
        ///
        /// Since this method is called on every change of the set of materialized items,
        /// it is advisable to use it to set a flag and perform any resulting work as a
        /// timed task rather than performing any work directly.
        ///
        /// Execution time:
        /// ---------------
        /// This call is not expected to take more than a few seconds to complete.
        #[optional]
        #[unsafe(method(materializedItemsDidChangeWithCompletionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn materializedItemsDidChangeWithCompletionHandler(
            &self,
            completion_handler: &block2::DynBlock<dyn Fn()>,
        );

        #[cfg(feature = "block2")]
        /// Called by the system when the set of pending items is refreshed.
        ///
        /// The pending enumerator lists all the items for which a change has been observed either
        /// on the disk or in the working set more than one second ago and that change hasn't been
        /// applied on the other side yet. An item can appear in the pending set for various reasons:
        /// - the system is under load and cannot process all the events in a timely fashion
        /// - a long running operation is scheduled or running for the item to be in sync (for instance,
        /// the download or the upload of a new content)
        /// - an error occurred, in which case the error will be set on the item as `downloadError` if
        /// it occurred when applying a change to the disk, or `uploadError` in the other way around.
        ///
        /// The pending set will only include items that comply to the following rules:
        /// - They have been queued for changes for more time than the refresh interval;
        /// - The items are already known by the provider.
        ///
        /// These constraints imply that initial transfer of a file from the disk to the provider will not
        /// be listed in the pending set, even though the transfer could take several minutes to complete
        ///
        /// Furthermore, the pending set can only contain a limited number of items.
        /// The pending set provides an easy way to design an "in progress" UI containing a few items
        /// and to detect whether there's any activity pending on the system.
        /// In case the pending set reached its maximum size items, newly pending items won't be included
        /// in it. Already present items in the pending set will remain until they no longer are pending.
        ///
        /// The pending set is refreshed regurlary but only if there are meaningful changes:
        /// new pending items, items that were pending but are not anymore (deletions from the set),
        /// or domain version changed and set is not empty
        ///
        /// To enumerate the set of pending items,
        /// - Call -enumeratorForPendingItems on the instance of
        /// NSFileProviderManager corresponding to your domain;
        /// - Implement the NSFileProviderEnumerationObserver and
        /// NSFileProviderChangeObserver on an object;
        /// - Pass that object to the enumerator;
        /// - It will get called upon change to the set.
        ///
        /// This method is regularly called when changes happen to the pending set.
        /// implementeers are advised that this call will not happen as soon as an item is pending.
        /// Thus, implementeers should not use the pending set to detect when a change happens.
        /// The pending set will only contain items that were pending for a least one second before the
        /// last refresh date.
        ///
        /// Execution time:
        /// ---------------
        /// This call is not expected to take more than a few seconds to complete.
        #[optional]
        #[unsafe(method(pendingItemsDidChangeWithCompletionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn pendingItemsDidChangeWithCompletionHandler(
            &self,
            completion_handler: &block2::DynBlock<dyn Fn()>,
        );
    }
);

extern_protocol!(
    /// Protocol to implement if the provider instance supports fetching incremental content changes.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderincrementalcontentfetching?language=objc)
    pub unsafe trait NSFileProviderIncrementalContentFetching: NSObjectProtocol {
        #[cfg(all(
            feature = "NSFileProviderItem",
            feature = "NSFileProviderRequest",
            feature = "block2"
        ))]
        /// Update a previously provided item to a new version.
        ///
        /// If the system already has a version of an item and learns that a new version is
        /// available, it may call this method to update the existing version to a new
        /// version.
        ///
        /// The semantics of the requestedVersion parameter are the same as for the non-delta update method above.
        #[unsafe(method(fetchContentsForItemWithIdentifier:version:usingExistingContentsAtURL:existingVersion:request:completionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn fetchContentsForItemWithIdentifier_version_usingExistingContentsAtURL_existingVersion_request_completionHandler(
            &self,
            item_identifier: &NSFileProviderItemIdentifier,
            requested_version: Option<&NSFileProviderItemVersion>,
            existing_contents: &NSURL,
            existing_version: &NSFileProviderItemVersion,
            request: &NSFileProviderRequest,
            completion_handler: &block2::DynBlock<
                dyn Fn(*mut NSURL, *mut NSFileProviderItem, *mut NSError),
            >,
        ) -> Retained<NSProgress>;
    }
);

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderservicing?language=objc)
    pub unsafe trait NSFileProviderServicing: NSObjectProtocol {
        #[cfg(all(
            feature = "NSFileProviderItem",
            feature = "NSFileProviderService",
            feature = "block2"
        ))]
        /// A file provider can implemement this method to return service sources that provide custom
        /// communication channels to client applications.
        ///
        /// The service sources must be tied to the item identified by
        /// `itemIdentifier.`Client applications can retrieve the list of supported services by calling
        /// `-[NSFileManager`getFileProviderServicesForItemAtURL:] for a specific item URL.
        ///
        /// Cancellations:
        /// ------------
        /// If the NSProgress returned by this method is cancelled, the extension should
        /// call the completion handler with (nil, NSUserCancelledError) in the NSProgress
        /// cancellation handler.
        ///
        /// Execution time:
        /// ---------------
        /// This method is not expected to take more than a few seconds to complete the retrieval of the
        /// thumbnails. The system will call `cancel` on the progress if the
        /// operation takes too much time. The extension is then expected to quickly call the completion
        /// handler.
        #[unsafe(method(supportedServiceSourcesForItemIdentifier:completionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn supportedServiceSourcesForItemIdentifier_completionHandler(
            &self,
            item_identifier: &NSFileProviderItemIdentifier,
            completion_handler: &block2::DynBlock<
                dyn Fn(*mut NSArray<ProtocolObject<dyn NSFileProviderServiceSource>>, *mut NSError),
            >,
        ) -> Retained<NSProgress>;
    }
);

extern_protocol!(
    /// Protocol to implement if the provider supports fetching thumbnails for its items.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderthumbnailing?language=objc)
    pub unsafe trait NSFileProviderThumbnailing: NSObjectProtocol {
        #[cfg(all(
            feature = "NSFileProviderItem",
            feature = "block2",
            feature = "objc2-core-foundation"
        ))]
        /// The system calls this method to fetch thumbnails.
        ///
        /// The
        /// `perThumbnailCompletionHandler`should be called for each thumbnail, and
        /// `completionHandler`only after all the per thumbnail completion blocks.
        ///
        /// In the event of a global error, the implementation is allowed to skip calling
        /// the
        /// `perThumbnailCompletionHandler`for individual thumbnails. In that case,
        /// the
        /// `completionHandler's`error parameter would apply to all item identifiers
        /// for which
        /// `perThumbnailCompletionHandler`had not been called.
        ///
        /// If there is no thumbnail for a given item, the
        /// `perThumbnailCompletionHandler`should be called with its
        /// `imageData`and
        /// `error`parameters both
        /// set to nil.
        ///
        /// If the system decides that an in-flight thumbnail request is not needed anymore,
        /// it will call the returned
        /// `NSProgress`object's
        /// `-cancel`method,
        /// at which time the implementation should clean up any held resources.
        ///
        /// The system will cache the thumbnail for the item, and the cache will be
        /// invalidated when itemVersion.contentVersion changes.
        ///
        /// Thread safety:
        /// ------------
        ///
        /// The
        /// `perThumbnailCompletionHandler`may be called from multiple threads
        /// concurrently.
        ///
        /// Cancellations:
        /// ------------
        /// If the NSProgress returned by this method is cancelled, the extension should
        /// call the completion handler with (NSUserCancelledError) in the NSProgress
        /// cancellation handler.
        ///
        /// Execution time:
        /// ---------------
        /// This method is not expected to take more than a few tens seconds to complete the retrieval of the
        /// services exposed on the item. The system will call `cancel` on the progress if the
        /// operation takes too much time. The extension is then expected to quickly call the completion
        /// handler.
        #[unsafe(method(fetchThumbnailsForItemIdentifiers:requestedSize:perThumbnailCompletionHandler:completionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn fetchThumbnailsForItemIdentifiers_requestedSize_perThumbnailCompletionHandler_completionHandler(
            &self,
            item_identifiers: &NSArray<NSFileProviderItemIdentifier>,
            size: CGSize,
            per_thumbnail_completion_handler: &block2::DynBlock<
                dyn Fn(NonNull<NSFileProviderItemIdentifier>, *mut NSData, *mut NSError),
            >,
            completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
        ) -> Retained<NSProgress>;
    }
);

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileprovidercustomaction?language=objc)
    pub unsafe trait NSFileProviderCustomAction: NSObjectProtocol {
        #[cfg(all(
            feature = "NSFileProviderActions",
            feature = "NSFileProviderItem",
            feature = "block2"
        ))]
        /// Perform a custom action identified by `actionIdentifier`, on items identified by
        /// `itemIdentifiers`.
        ///
        /// Custom actions are defined in the File Provider Extension's Info.plist, under the
        /// `NSExtensionFileProviderActions` key. The format of this key is identical to actions
        /// defined in a FileProviderUI extension.
        ///
        /// Cancellations:
        /// ------------
        /// If the NSProgress returned by this method is cancelled, the extension should
        /// call the completion handler with (NSUserCancelledError) in the NSProgress
        /// cancellation handler.
        #[unsafe(method(performActionWithIdentifier:onItemsWithIdentifiers:completionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn performActionWithIdentifier_onItemsWithIdentifiers_completionHandler(
            &self,
            action_identifier: &NSFileProviderExtensionActionIdentifier,
            item_identifiers: &NSArray<NSFileProviderItemIdentifier>,
            completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
        ) -> Retained<NSProgress>;
    }
);

extern_protocol!(
    /// Protocol to implement for managing UserInteraction alerts.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileprovideruserinteractionsuppressing?language=objc)
    pub unsafe trait NSFileProviderUserInteractionSuppressing: NSObjectProtocol {
        /// Suppression management:
        ///
        /// The extension may choose to give the user the option to suppress certain UserInteraction alerts.
        /// In order to do so, the extension must both implement NSFileProviderUserInteractionSuppressing, as well as
        /// configure the desired UserInteractions in the Info.plist with the `SuppressionIdentifier` field.
        ///
        /// When FileProvider needs to evaluate whether to display a UserInteraction alert, it will call
        /// -[NSFileProviderUserInteractionSuppressing isInteractionSuppressedForIdentifier:]. When the user indicates that they do not
        /// wish to see a given SuppressionIdentifiers's alert again, FileProvider will call
        /// -[NSFileProviderUserInteractionSuppressing setInteractionSuppressed:forIdentifier:].
        ///
        /// The extension can choose whether the suppression should apply only to the domain upon which
        /// -[NSFileProviderUserInteractionSuppressing setInteractionSuppressed:forIdentifier:] was called, or if it should apply to all
        /// domains for their provider. For instance, the extension could choose to suppress future alerts related
        /// to adding an item to a shared folder across all domains, after the user chooses to suppress the alerts
        /// in a specific domain's context. Or, the extension could choose to only suppress that alert for the
        /// specific domain it was displayed within, and in the future, the user would see the same alert in the same
        /// context, if they take the same action in another domain.
        ///
        /// Execution time:
        /// ---------------
        /// This method is expected to complete immediately.
        #[unsafe(method(setInteractionSuppressed:forIdentifier:))]
        #[unsafe(method_family = none)]
        unsafe fn setInteractionSuppressed_forIdentifier(
            &self,
            suppression: bool,
            suppression_identifier: &NSString,
        );

        #[unsafe(method(isInteractionSuppressedForIdentifier:))]
        #[unsafe(method_family = none)]
        unsafe fn isInteractionSuppressedForIdentifier(
            &self,
            suppression_identifier: &NSString,
        ) -> bool;
    }
);

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderdomainstate?language=objc)
    pub unsafe trait NSFileProviderDomainState: NSObjectProtocol {
        #[cfg(feature = "NSFileProviderDomain")]
        /// Version of the domain.
        ///
        /// The domain version is an opaque value assigned by the provider. It is read by the system in the
        /// completion handler for createItemBasedOnTemplate, modifyItem, deleteItem and itemForIdentifier, as
        /// well as in the finish calls when enumerating the working set. The read is guaranteed to happen
        /// on the same dispatch queue the completion handler was called on.
        ///
        /// When the system discovers a change on disk, it associates that change to the currently known
        /// domain version. When that change get communicated to the extension, that version is included in
        /// the NSFileProviderRequest object passed by the system to the extension. As a consequence, the
        /// provider can use the domain version to identify the state of the system when a change was made on disk.
        ///
        /// The provider is responsible for defining when the domain version changes. When that value is
        /// updated, the provider must notify the system by signaling the working set.
        ///
        /// The system ignore any domain version that is smaller than the previously known version.
        #[unsafe(method(domainVersion))]
        #[unsafe(method_family = none)]
        unsafe fn domainVersion(&self) -> Retained<NSFileProviderDomainVersion>;

        /// Global state of the domain.
        ///
        /// Use this dictionary to add state information to the domain. It is accessible to predicates for
        /// User Interactions, FileProvider Actions, and FileProviderUI Actions, via the top-level `domainUserInfo` context
        /// key.
        ///
        /// This dictionary must only contain key and value classes in the following list:
        /// NSString, NSNumber, NSDate, and NSPersonNameComponents.
        ///
        /// The system expects the domainVersion to be updated when the value of the userInfo property
        /// changes.
        #[unsafe(method(userInfo))]
        #[unsafe(method_family = none)]
        unsafe fn userInfo(&self) -> Retained<NSDictionary>;
    }
);

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderpartialcontentfetching?language=objc)
    pub unsafe trait NSFileProviderPartialContentFetching: NSObjectProtocol {
        #[cfg(all(
            feature = "NSFileProviderItem",
            feature = "NSFileProviderRequest",
            feature = "block2"
        ))]
        /// Download the requested extent of an item for the given identifier and return it via the completion
        /// handler.  If this protocol is not implemented the system defaults to fetchContentsForItemWithIdentifier.
        ///
        /// The requestedVersion parameter specifies which version should be returned. This version will always be
        /// specified by the system so as to prevent extents from different versions from being written into the same
        /// file. The system tolerates a version mismatch for the first materialization of a fully dataless file (strictVersion=NO).
        ///
        /// The requested range is
        /// <location
        /// , length>.  The implementation can provide any properly aligned range that
        /// covers the requested range (including the entire item).  The system provides the minimal alignment value.
        /// The location (or start offset) of the fetched range should be a multiple of this value for it to be considered
        /// properly aligned. The length of the fetched range should be a multiple of this value, with an exception for
        /// the end of the file, checked against the documentSize attribute the implementation supplied for this item.
        /// The alignment value should not be expected to be stable across reboots. It is guaranteed by the system to be
        /// a power of two.
        /// In addition to the content the extension needs to fill in fetchedRange with either the requestest range,
        /// <location
        /// , length>, or indicate full materialization with,
        /// <
        /// 0, file size>.
        ///
        /// On-disk layout:
        /// ---------------
        /// The retrieved content at `fileContents` URL must be a regular file on the same volume as the user-visible URL.
        /// A suitable location can be retrieved using -[NSFileProviderManager temporaryDirectoryURLWithError:].
        /// The file contents outside of the fetched range are ignored by the system. The system only requires the file
        /// to be at least as large as the end of the fetched range. For instance, if the fetchedRange is {offset:0x100000, length:0x1000},
        /// the file size must be at least 0x101000 bytes. Any data (or lack thereof) beyond the fetched range is ignored.
        ///
        /// The fetched range must be stored in this file at the same offset as the range indicates.
        /// For instance if the retrievedRange  is {offset:0x100000, length:0x1000} then it should actually be at offset 0x100000 in the
        /// `fileContents` file. The ranges {0, 0x100000}, and {0x101000, EOF} can be anything including sparse ranges.
        ///
        /// Concurrent Downloads:
        /// ---------------
        /// The system will call fetchContents concurrently if there are multiple outstanding file download requests.
        /// The provider can control the concurrency by setting the key NSExtensionFileProviderDownloadPipelineDepth
        /// in the Info.plist of the extension to the number of concurrent downloads that the system should create
        /// per domain. This number must be between 1 and 128, inclusive.
        ///
        /// File ownership:
        /// ---------------
        /// The system clones and unlinks the received fileContents. The extension should not mutate the corresponding
        /// file after calling the completion handler. If the extension wishes to keep a copy of the content, it must
        /// provide a clone of the that content as the URL passed to the completion handler.
        ///
        /// In case the extension or the system crashes between the moment the completion handler is called and the
        /// moment the system unlinks the file, the file may unexpectedly still be on disk the next time an instance
        /// of the extension is created. The extension is then responsible for deleting that file.
        ///
        /// Disallowing processes from fetching items:
        /// ---------------
        ///
        /// The system automatically downloads files on POSIX accesses. The extension may wish to disallow this class of
        /// downloads for specific applications.
        ///
        /// The extension can set an array of strings into the UserDefault key
        /// "NSFileProviderExtensionNonMaterializingProcessNames". A process whose executable's filename on disk is an
        /// exact match for an entry in this array will not be allowed to fetch items in the extension's domains. The comparison
        /// is case sensitive.
        ///
        /// In macOS 11.0 and later, this list will be checked when a download is initiated through a POSIX filesystem call.
        /// In macOS 11.4 and later, this list will also be checked for downloads initiated through file coordination.
        ///
        /// Error cases:
        /// ------------
        /// If the download fails because the item is unknown, the call should
        /// fail with the NSFileProviderErrorNoSuchItem error. In that case, the system
        /// will consider the item has been removed from the domain and will attempt to
        /// delete it from disk. In case that deletion fails because there are local
        /// changes on this item, the system will re-create the item using createItemBasedOnTemplate.
        ///
        /// If the user does not have access to the content of the file, the provider
        /// can fail the call with NSCocoaErrorDomain and code NSFileReadNoPermissionError.
        /// That error will then be presented to the user. The extension can also report
        /// the NSFileProviderErrorNotAuthenticated, NSFileProviderErrorServerUnreachable
        /// in case the item cannot be fetched because of the current state of the system / domain.
        /// In those cases, the system will present an appropriate error message and back off
        /// until the next time it is signalled.
        ///
        /// If the requested version cannot be retrieved, the provider can choose to provide a different
        /// version of the file, unless NSFileProviderFetchContentsOptionsStrictVersioning  is set. In this case,
        /// the provider should fail with NSFileProviderErrorVersionNoLongerAvailable.
        /// If some content is returned, the item must have the corresponding version. The system will detect
        /// any mismatch and handle it as a remote update.
        /// For the reading application, the materialization will fail with the same error as reading from
        /// a dataless file that got remotely updated (-1/errno=ESTALE). Upon retry the new version will be
        /// requested by the system.
        ///
        /// Any other error will be considered to be transient and will cause the
        /// download to be retried.
        ///
        /// Cancellations:
        /// ------------
        /// If the NSProgress returned by this method is cancelled, the extension should
        /// call the completion handler with (nil, nil, someRange, 0, NSUserCancelledError) in the NSProgress
        /// cancellation handler.
        ///
        /// The returned NSProgress is used to show progress to the user. If the user cancels the
        /// fetch, the extension should stop fetching the item, as it is no longer required.
        ///
        /// Execution time:
        /// ---------------
        /// The system will grant enough time to the extension to download the file. The system will interrupt the
        /// call if it stops making progress or if download takes an unexpectedly long time. In that case, the system
        /// will call `cancel` on the progress. The extension is then expected to quickly call the completion
        /// handler.
        #[unsafe(method(fetchPartialContentsForItemWithIdentifier:version:request:minimalRange:aligningTo:options:completionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn fetchPartialContentsForItemWithIdentifier_version_request_minimalRange_aligningTo_options_completionHandler(
            &self,
            item_identifier: &NSFileProviderItemIdentifier,
            requested_version: &NSFileProviderItemVersion,
            request: &NSFileProviderRequest,
            requested_range: NSRange,
            alignment: NSUInteger,
            options: NSFileProviderFetchContentsOptions,
            completion_handler: &block2::DynBlock<
                dyn Fn(
                    *mut NSURL,
                    *mut NSFileProviderItem,
                    NSRange,
                    NSFileProviderMaterializationFlags,
                    *mut NSError,
                ),
            >,
        ) -> Retained<NSProgress>;
    }
);

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/fileprovider/nsfileproviderexternalvolumehandling?language=objc)
    pub unsafe trait NSFileProviderExternalVolumeHandling: NSObjectProtocol {
        #[cfg(feature = "block2")]
        /// Implement this protocol on your extension's Principal Class in order for the system
        /// to ask your extension whether a domain located on an external volume should be connected.
        ///
        /// Your extension may use this method as an opportunity to check for, and setup if necessary,
        /// state to operate the extension. Such as prompting the user to login in your application.
        /// When creating domains on external drive, store state related to the domain in the `userInfo` parameter to
        /// `-[NSFileProviderDomain initWithDisplayName:userInfo:volumeURL:]`,
        /// such as the user's ID, to help your extension identify the domain when connected on other devices. This userInfo will be
        /// persisted on the external volume, and provided in the ReplicatedExtension initializer when the drive is connected to a new device.
        ///
        /// If your extension responds with an NSError, the domain will be in a disconnected state. Non-downloaded files
        /// in the domain will not be downloadable, and file edits will not be synced up. The system will display
        /// UI to inform the user. Your extension will be able to enumerate this domain in
        /// `+[NSFileProviderManager getDomainsWithCompletionHandler:]`, with the
        /// `-[NSFileProviderDomain disconnected]` property set as YES.
        ///
        /// If at a later point, the user has setup the necessary state to service requests for the disconnected external
        /// domain, your extension may call `-[NSFileProviderManager reconnectWithCompletionHandler:]`.
        ///
        /// If your extension does not implement this protocol, domains on external volumes will automatically be
        /// connected and instantiated in your extension.
        #[unsafe(method(shouldConnectExternalDomainWithCompletionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn shouldConnectExternalDomainWithCompletionHandler(
            &self,
            completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
        );
    }
);