Reputation: 9061
I have this code in a UIViewController
that confirms to UIDocumentPickerDelegate
:
- (void)openTextFilePicker {
NSArray *UTIs = [NSArray arrayWithObjects:@"public.text", nil];
[self openFilePicker:UTIs];
}
- (void)openFilePicker:(NSArray *)UTIs {
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:UTIs inMode:UIDocumentPickerModeImport];
documentPicker.delegate = self;
documentPicker.popoverPresentationController.barButtonItem = self.importButton;
[self presentViewController:documentPicker animated:TRUE completion:nil];
}
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURLs:(NSArray<NSURL *> *)urls {
[self documentPicker:controller didPickDocumentAtURL:[urls firstObject]];
}
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url {
NSLog(@"picked document %@", url);
}
- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller {
NSLog(@"cancelled");
}
This allows users to select a file anywhere on their system and import its contents into the app. It works if I have the App Sandbox > User Selected File capability set to Read/Write. But I'm only reading data in from the file, I don't need to update the file or save anything outside of the sandbox. So I changed the capability to Read Only, but then I get this error in the console, and didPickDocumentsAtURLs
isn't called:
Failed to create an FPSandboxingURLWrapper for [path]. Error: Error Domain=NSPOSIXErrorDomain Code=1 "couldn't issue sandbox extension com.apple.app-sandbox.read-write for '[path]': Operation not permitted"
Does that seem right, or should I be able to read files with just the Read Only entitlement? It's easy enough to switch it to Read/Write if needed, but my first submission was rejected for using unnecessary entitlements, and I want to be prepared to justify this to the review team if it is in fact needed.
Upvotes: 4
Views: 928
Reputation: 469
For anyone searching for this, I did not get granted app approval by stating my case - instead I was forced to find the following solution - which uses a UIDocumentBrowserViewController (Read only!) vs a UIDocumentPickerViewController (which requires read-write)
import Foundation
import UIKit
extension ViewController: UIDocumentBrowserViewControllerDelegate, UIDocumentPickerDelegate {
@objc func presentDocumentPicker() {
if operatingSystem == .macintosh {
let documentPicker = UIDocumentBrowserViewController(forOpening: [.pdf])
documentPicker.delegate = self
documentPicker.allowsDocumentCreation = false
documentPicker.allowsPickingMultipleItems = false
// Present the document picker.
present(documentPicker, animated: true, completion: nil)
} else {
let documentsPicker = UIDocumentPickerViewController(forOpeningContentTypes: [.pdf])
documentsPicker.delegate = self
documentsPicker.allowsMultipleSelection = false
documentsPicker.modalPresentationStyle = .fullScreen
self.present(documentsPicker, animated: true, completion: nil)
}
}
func documentBrowser(_ controller: UIDocumentBrowserViewController, didPickDocumentsAt documentURLs: [URL]) {
guard let url = documentURLs.first, url.startAccessingSecurityScopedResource() else { return }
defer {
DispatchQueue.main.async {
url.stopAccessingSecurityScopedResource()
}
}
debugPrint("[DocumentPicker] Selected Item with URL : ", url)
controller.dismiss(animated: true)
}
public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard let url = urls.first, url.startAccessingSecurityScopedResource() else { return }
defer {
DispatchQueue.main.async {
url.stopAccessingSecurityScopedResource()
}
}
debugPrint("[DocumentPicker] Selected Item with URL : ", url)
controller.dismiss(animated: true)
}
public func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
controller.dismiss(animated: true)
}
}
Upvotes: 5
Reputation: 9061
I went ahead and changed the entitlement to Read/Write, and submitted it with a note in the App Sandbox Information field explaining how the file access is used. The app was approved.
Upvotes: 2