General:
DevForums tags: Files and Storage, Finder Sync, File Provider, Disk Arbitration, APFS
File System Programming Guide
On File System Permissions DevForums post
File Provider framework
Finder Sync framework
App Extension Programming Guide > App Extension Types > Finder Sync
Disk Arbitration Programming Guide
Mass Storage Device Driver Programming Guide
Device File Access Guide for Storage Devices
Apple File System Guide
TN1150 HFS Plus Volume Format
Extended Attributes and Zip Archives
File system changes introduced in iOS 17 DevForums post
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
File Provider
RSS for tagAllow other apps to access the documents and directories stored and managed by your containing app using File Provider.
Posts under File Provider tag
84 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
I have created working fileprovider, that works perfectly on my local machine. Codesigned in xcode, with our company sign certificate as Developer ID Application. No provisioning profile. Also notarized result dmg.
Works as expected on my local machine. But won't load on any other machine.
Calling [NSFileProviderManager addDomain: ...], ends up with error:
Error Domain=NSFileProviderErrorDomain Code=-2001 "The application cannot be used right now." UserInfo={NSLocalizedDescription=The application cannot be used right now.}
Code=-2001 should mean, that no file provider manager extension was found in an app bundle.
I have made a TestFileProvider application that is totally simplified File Provider example.
This too does work only on my own machine.
Relevant code from app:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSFileProviderDomain* fileProviderDomain = [[NSFileProviderDomain alloc] initWithIdentifier:@"com.xxxxx.dwc.FileProvider" displayName:@"TestDomain"];
[NSFileProviderManager addDomain:fileProviderDomain completionHandler:^(NSError * _Nullable error) {
if (error)
NSLog(@"add domain: %@", error);
else
NSLog(@"add domain SUCCESS");
}];
}
There are also these errors, that are related, but I do not understand what are they implying neither how to fix:
kernel Sandbox: fileproviderd(448) deny(1) file-read-data /Applications/TestFileProvider.app
fileproviderd [ERROR] PluginRecord doesn't have container url for
fileproviderd [WARNING] No provider found with identifier (null) for calling bundle (null) on second attempt.
I'm clueless on how to fix this. Is this related to codesign ? Or is it necessary to start fileprovider with different method call ?
Hey, I'm not sure I'm even in the correct ballpark - trying to allow my app to download largish videos from user's OneDrive and G-Drive to app
Is it correct to use NSFileCoordinator in this way?
How do I report progress as it downloads the video (is it possible?)
Is it correct to dismiss the picker like this?
anything else wrong (or, like is....any of it correct? :)
it's sort of working with my contrived examples (I created new personal G-drive / Onedrive accounts, and copied vids up there), but...when I use a file from our corporate OneDrive, from shared folder, I get:
"NSCocoaErrorDomain Code=3328 "The requested operation couldn’t be completed because the feature is not supported."
Is this the NSFileProvider extension (Microsoft's) complaining?
public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard let url = urls.first else {
return
}
let isSecurityScoped = url.startAccessingSecurityScopedResource()
print("(#function) - iSecurityScoped = (isSecurityScoped)")
print("(#function) - document at (url)")
let filename = String(UUID().uuidString.suffix(6)) + "_" + url.lastPathComponent
let newURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent(filename)
let readingIntent = NSFileAccessIntent.readingIntent(with: url, options: .withoutChanges)
fileCoordinator.coordinate(with: [readingIntent], queue: queue) { error in
defer {
if isSecurityScoped {
url.stopAccessingSecurityScopedResource()
}
}
if let error = error {
print("(#function) - (error)")
return
}
let safeURL = readingIntent.url
do {
let fileData = try Data(contentsOf: safeURL)
try fileData.write(to: newURL, options: .atomic)
print("(#function) - SUCCESS - newURL = (newURL)")
} catch {
print("(#function) - NOOOOO - (error)")
}
}
controller.dismiss(animated: true)
}
Trying to use file importer in a swift app to upload documents into firebase Storage and getting error when running on live device but works perfectly fine on emulator.
error:
BackgroundSession <***...> Failed to issue sandbox extension for file
file:///private/var/mobile/Library/Mobile%20Documents/comappleCloudDocs/Sample.pdf, errno = [1: Operation not permitted]
UNKNOWN ERROR Error Domain=FIRStorageErrorDomain Code=-13000 "An unknown error occurred, please check the server response." UserInfo={object=Repository/Sample.pdf, ResponseBody=Can not finalize upload. Current size is 0. Expected final size is 2665098., bucket=bucket, data={length = 77, bytes = 0x43616e20 6e6f7420 66696e61 6c697a65 ... 32363635 3039382e }, data_content_type=text/plain; charset=utf-8, NSLocalizedDescription=An unknown error occurred, please check the server response., ResponseErrorDomain=com.google.HTTPStatus, ResponseErrorCode=400}
I tried separating all the logic from selectedFile.startAccessingSecurityScopedResource() all the way through the end into a function of its own using @MainActor based on another post I found around here and issue persisted..
Below is the implementation:
.fileImporter(
isPresented: $fileImporterIsPresented,
allowedContentTypes: [.pdf],
allowsMultipleSelection: false
) {
result in
switch result
{
case .success(let url):
print(url)
guard let selectedFile:URL = url.first else { return }
guard selectedFile.startAccessingSecurityScopedResource() else
{
return
}
let firebaseRepository = Storage.storage().reference().child("Repository/Sample.pdf")
let uploadTask = firebaseRepository.putFile(from: selectedFile)
uploadTask.observe(.progress)
{
snapshot in
// Upload reported progress
percentComplete = 100.0 * Double(snapshot.progress!.completedUnitCount)
/ Double(snapshot.progress!.totalUnitCount)
}
uploadTask.observe(.success)
{
snapshot in
selectedFile.stopAccessingSecurityScopedResource()
uploadTask.removeAllObservers()
print("SUCCESS")
// Upload completed successfully
}
uploadTask.observe(.failure)
{
snapshot in
if let error = snapshot.error as? NSError
{
switch (StorageErrorCode(rawValue: error.code)!)
{
case .objectNotFound:
print("NOT FOUND")
// File doesn't exist
break
case .unauthorized:
print("UNAUTHORIZED")
// User doesn't have permission to access file
break
case .cancelled:
print("CANCELLED")
// User canceled the upload
break
/* ... */
case .unknown:
print("UNKNOWN ERROR \(error.description)")
print("UNKNOWN ERROR \(error.localizedDescription)")
print("UNKNOWN ERROR \(error.underlyingErrors)")
// Unknown error occurred, inspect the server response
break
default:
print("UNSPECIFIED ERROR")
// A separate error occurred. This is a good place to retry the upload.
break
}
}
}
case .failure(let error):
print(error)
}
}
The existing project of Finder Extension is doing an amazing job in other paths but when I point it to the CloudStorage path the context menu doesn't show up. And no trace of what is going wrong any where (Xcode Logs, Console log, crash log, etc.)
Path Used:
/Users/<User>/Library/CloudStorage/FP-SomeDomains
Yes, even my first though was, it must be because of dataless file and folders. But unfortunately it not. There was no context menu presented from my Finder Extension even on real physical files and folders.
My project has a base app which is manually signed, inside I have a FileProvider parent app and extension.
When things works elegantly in Xcode debug build when I run FP App. But, when I package it, the FileProvider can't mount, fails with a generic error on parent app
(Error Domain=NSFileProviderErrorDomain Code=-2001 "The application cannot be used right now." UserInfo={NSLocalizedDescription=The application cannot be used right now.}
Another generic error in FileProvider demon
fileproviderd(488) deny(1) file-read-data /Applications/XYZ.app/Contents/Resources/FileFP.app
How to solve this?
I have a Login Item that is bundled with my .app and can run in the background. The Login Item has a File Provider extension. When a user downloads and installs a new version of the main .app, what's the correct way to handle stopping and restarting the login item and File Provider related processes to make sure they are running the latest code also?
I'm working with NSFileProviderReplicatedExtension for macOS app. I want to apply default badge on files(For example, com.apple.icon-decoration.badge.warning, com.apple.icon-decoration.badge.pinned, .. etc).
I am unable to see any badge when I open the folder mounted by the Extension.
I've defined NSFileProviderDecorations in NSExtension as follows :
<dict>
<key>NSFileProviderDecorations</key>
<array>
<dict>
<key>BadgeImageType</key>
<string>com.apple.icon-decoration.pinned</string>
<key>Category</key>
<string>Badge</string>
<key>Identifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER).cyfile</string>
<key>Label</key>
<string>CydriveFile</string>
</dict>
</array>
<key>NSExtensionFileProviderDocumentGroup</key>
<string>$(TeamIdentifierPrefix)com.example.app-group</string>
<key>NSExtensionFileProviderSupportsEnumeration</key>
<true/>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.fileprovider-nonui</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).FileProviderExtension</string>
</dict>
I have implemented the class Item that's implementing the following Protocols :
NSObject, NSFileProviderItemProtocol, NSFileProviderItemDecorating
and when returning decorations for that item I'm just doing this :
class Item : ... {
...
static let decorationPrefix = Bundle.main.bundleIdentifier!
static let heartItem = NSFileProviderItemDecorationIdentifier(rawValue: "\(decorationPrefix).cyfile")
var decorations: [NSFileProviderItemDecorationIdentifier]? {
var decos = [NSFileProviderItemDecorationIdentifier]()
decos.append(CyItem.heartItem)
return decos
}
}
As far as i can tell I've completed all the requirements for getting the badge to show up.
I'm trying to put a sub menu inside the context menu using the NSExtensionFileProviderActions in info.plist. Which should look like this image below
I have been trying to use FPUIActionExtensionViewController for doing this task but I havent got any context menu like above. But still doing that does seem to complicate the task more.
Is there a simpler way to do this task, like doing it within the info.plist so I dont have to complicate the task by creating a view controller. ?
I discovered a multithreading mistake in my use of NSManagedObjects recently and was surprised that I wasn't alerted to this during development, since I had -com.apple.CoreData.ConcurrencyDebug 1 set under "arguments passed on launch" for my macOS and iOS FileProvider extensions. I confirmed that the expected log stating CoreData: annotation: Core Data multi-threading assertions enabled. is NOT present when running these targets (but does appear as expected on my main macOS and iOS applications).
Can anyone advise me on how to get this concurrency debugging functionality to work on my FileProvider extension(s)?
Thanks
I'm asking this because the documentation is totally contradicting to itself on multiple occasions:
Extensions overview page (https://developer.apple.com/app-extensions/) claims it's not supported.
At the same time, on FileProviderUI docs page (https://developer.apple.com/documentation/fileproviderui) macOS is listed among another platforms and docs kinda generally suggest it is supported.
At the same time, "add new target" dialog in xcode is missing "File Provider UI Extension" template under macOS.
At the same time, it's can be easily be done by creating an iOS extension, then swapping SDK to macOS and UIKit APIs to their AppKit counterparts. This way, FileProviderUI actions DO appear in Finder.
Problem is, after clicking the action, UI never appears and here's what i see in Console:
default pkd Waiting on thread <private> until Launch Services database seeding is complete.
default Finder [d <private>] <PKHost:0x600000c38cc0> Beginning discovery for flags: 1024, point: (null)
default Finder [d <private>] <PKHost:0x600000c38cc0> Completed discovery. Final # of matches: 0
error Finder nil extension for provider ID (<private>), error: (null)
error Finder Action with identifier (<private>) did finish with error (Error Domain=FPUIActionViewControllerErrorDomain Code=1000).
error Finder FP Custom action sheet finished with error Error Domain=FPUIActionViewControllerErrorDomain Code=1000 "(null)"
default pkd [d <private>] Final plugin count: 0
This is totally confusing, please elaborate.
Is it possible to indirectly delete data stored in the stock iOS "File" app from any external app (without opening the File app)?
As reference information, we have confirmed that when data is deleted from a third-party file app (e.g. Readdle's documents(https://readdle.com/ja/documents) the data is also deleted from the genuine iOS file app.
We are implementing a file system extension using the file provider replicated extension for an application on Mac OS. On part of it, we need to show context menus for items(files/folders) inside the file provider's mounted folder.
But we don't want to show the context menu based on the 'activation rule' key's value declared on each NSExtensionFileProviderActions item in the info.plist file but with the main app's code logic. Because if we use the info.plist activation rule, we need to use each item's instance variables as part of predicate query(which decides on showing the context menu item), and after performing the action, we need to change the value of that instance variable so that we can show opposite context menu of the previous one (for example if previously 'set offline' is clicked, now 'set online' have to be shown) but doing this is tedious process.
Also, we already implemented the code logic in our main app(that is not written in swift) to choose what are the context menu items to be shown and so we want to use it.
So, Instead, we are hoping to do it either:
By handling the get-menu function call or
By handling the predicate checking function call.
Kindly let us know if is there any function we can override or inform the system to do at least any one of the above things.
Thanks in advance.
Currently, we are doing it by:
Calling the function 'signalEnumerator' with the identifier as workingset
Returning the metas of the new changes to the function enumerateChanges called by the file provider
Sometimes, it would take more time to get the enumerateChanges function call from the file provider after invoking the signalEnumerator function. So, Kindly let us know if is there any other alternative to pass the new updated items information to the file provider properly and quickly.
Previously, we are using the Finder Sync extension for showing the context menu on the finder items. But now we are planning to use the File Provider extension on Mac OS.
So, as of our learning, we found that the context menu items to be shown on the finder items have to be informed using the 'NSExtensionFileProviderActions' key in the info.plist file and the activation rule also have to be informed there under key 'NSExtensionFileProviderActionActivationRule'.
But in the Finder Sync, we can get both the right-click(to list menu) and menu item clicked(on the context menu shown) calls from the Finder Sync extension.
Like Finder Sync Extension, can we able to get both the calls from the file provider extension?
Hello,
I am interested in developing an iOS app that can monitor the names of third-party applications running in parallel without collecting any user-specific data. I would like to inquire about the feasibility of implementing such functionality within the iOS ecosystem and if there are any privacy terms or restrictions that I need to be aware of to ensure compliance with Apple's policies.
Additionally, I want to emphasize that the app will not collect any user-specific data but only the names of third-party apps for operational purposes.
Thank you for your guidance.
Hello Everyone,
I'm trying to add badges to files in my File Provider Extension for macOS. I'm not trying to create my own Item decorations here, but use the default Icons provided by apple (such as com.apple.icon-decoration.badge.heart , com.apple.icon-decoration.badge.pinned). I've gone through the Sample code provided by Apple for Fruit Basket.
I've tried to replicate the same thing in my Extension as well but It seems I'm unable to display Icons. I'm not even getting any Error when the Icons are not being displayed, So I've been stuck for a month on this.
These are the Things that I've done below:
Folder Structure :
FileExplorer
|- FileProviderApp
| |- UI.swift
| |- ContentView.swift
|- Extension
|- extension.swift
|- item.swift
|- enumerator.swift
|- info.plist
According to the instructions given in the Documentation for Decorations here : https://developer.apple.com/documentation/fileprovider/nsfileprovideritemdecorating.
The implementation was done as follows:
content inside info.plist of the File provider Extension
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionFileProviderSupportsEnumeration</key>
<true/>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.fileprovider-nonui</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).FileProviderExtension</string>
<key>NSFileProviderDecorations</key>
<array>
<dict>
<key>BadgeImageType</key>
<string>com.apple.icon-decoration.badge.heart</string>
<key>Category</key>
<string>Badge</string>
<key>Identifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER).heart</string>
<key>Label</key>
<string>Heart Item</string>
</dict>
</array>
</dict>
</dict>
</plist>
In my extension's NSFileProviderItem I've also Implemented the protocol NSFileProviderItemDecorating. and the decoration's method as
static let decorationPrefix = Bundle.main.bundleIdentifier!
static let heartDecoration = NSFileProviderItemDecorationIdentifier(rawValue: "\(decorationPrefix).heart")
var decorations: [NSFileProviderItemDecorationIdentifier]?
{
var decos = [NSFileProviderItemDecorationIdentifier]()
decos.append(Item.heartDecoration)
return decos
}
I was expecting to see badges on the File items in Finder, but i got nothing. When I modified the FruitBasket Project to do the same i was able to see badges, but not when I try to implement it in my Extension.
Was I missing a step or is the issue something else ?
We are developing File Provider for macOS. We followed apple sample app, and are able to create a File Provider with Container app and an extension. We are able to get this working while building from Xcode. But the distributable build does not load the extension and fails with error "Application can not be loaded".
We need help with understanding root cause of the issue, and exact entitlement that we can use for creating distributable builds.
Crash in fileproviderctl
Invoking fileproviderctl from the Terminal.app results in crash.
ot@wpg-img-mbp bin % fileproviderctl --help
zsh: killed fileproviderctl --help
Checked the Device log for more details, and found this,
default 10:35:47.810676+0530 kernel mac_vnode_check_signature: /usr/bin/fileproviderctl: code signature validation failed fatally: When validating /usr/bin/fileproviderctl:
dynamic: com.apple.fileproviderctl disallowed without com.apple.private.amfi.version-restriction entitlement
default 10:35:47.810733+0530 kernel proc 58397: load code signature error 4 for file "fileproviderctl"
default 10:35:47.811297+0530 kernel ASP: Security policy would not allow process: 58397, /usr/bin/fileproviderctl
default 10:35:47.811420+0530 kernel fileproviderctl[58397] Corpse allowed 1 of 5
default 10:35:47.828366+0530 ReportCrash Formulating fatal 309 report for corpse[58397] fileproviderctl
default 10:35:47.838691+0530 osanalyticshelper creating type 309 as /Users/ot/Library/Logs/DiagnosticReports/.fileproviderctl-2023-09-14-103547.ips
default 10:35:47.852670+0530 osanalyticshelper Saved type '309(<private>)' report (25 of max 25) at /Users/ot/Library/Logs/DiagnosticReports/fileproviderctl-2023-09-14-103547.ips
default 10:35:47.853184+0530 ReportCrash client log create type 309 result success: /Users/ot/Library/Logs/DiagnosticReports/fileproviderctl-2023-09-14-103547.ips
default 10:35:47.853323+0530 ReportCrash no MetricKit for process fileproviderctl type 309 bundleId (null)
default 10:35:47.852983+0530 osanalyticshelper xpc log creation type 309 result success: /Users/ot/Library/Logs/DiagnosticReports/fileproviderctl-2023-09-14-103547.ips
And also found the fileproviderctl in the Crash DiagosticsReports, looks like a codesigning issue. I'm not sure how I got into this issue, but I need this to be fixed. Any help is appreciated!
Added the Crash Report and Device Information below,
Crash Report of fileproviderctl
Crash Report
Device Information
I am developing a FileProvider extension which will be launched for one or more domains. In the case where I have two domains, say with displayNames "Foo" and "Bar", the finder will then show "MyExtension - Foo" and "MyExtension - Bar" respectively after registering them with addDomain.
However, if I only have a single domain, let's say "Foo" – then I just see "MyExtension" rather than "MyExtension - Foo". Now ideally I'd like to be able to control the entire name, but barring that at least be able to show the displayName even with a single domain. How can I achieve that?