使用UIDocumentBrowserViewController创建文档
documentBrowser(_:didRequestDocumentCreationWithHandler:)
说:“创建一个新文档并将其保存到临时位置。如果使用UIDocument
子类创建文档,则必须在调用importHandler
块之前关闭它。”
所以我通过获取用户临时目录( FileManager.default.temporaryDirectory
)的URL并附加名称和扩展名(获取类似“file:/// private / var / mobile / Containers / Data / Application”的路径来创建文件URL /C1DE454D-EA1E-4166-B137-5B43185169D8/tmp/Untitled.uti“)。 但是当我调用save(to:for:completionHandler:)
传递此URL时,永远不会回调完成处理程序。 我也尝试使用url(for:in:appropriateFor:create:)
来传递用户临时目录中的子目录 – 仍然没有调用完成处理程序。
我理解文档浏览器视图控制器由一个单独的进程管理,该进程有自己的读/写权限。 除此之外,我很难理解问题所在。 临时保存新文档的位置,以便文档浏览器进程可以移动它们?
更新:截至目前的测试版,我现在看到域NSFileProviderInternalErrorDomain
并且代码1
被记录:“不允许读者访问该URL。” 至少那是对发生了什么的确认……
因此,首先,如果您使用的是自定义UTI,则必须正确设置。 我看起来像这样……
CFBundleDocumentTypes CFBundleTypeIconFiles icon-file-name // Can be excluded, but keep the array CFBundleTypeName Your Document Name CFBundleTypeRole Editor LSHandlerRank Owner LSItemContentTypes com.custom-uti
和
UTExportedTypeDeclarations UTTypeConformsTo public.data // My doc is saved as Data, not a file wrapper UTTypeDescription Your Document Name UTTypeIdentifier com.custom-uti UTTypeTagSpecification public.filename-extension doc-extension
也
UISupportsDocumentBrowser
我将UIDocument
子类UIDocument
MyDocument
并添加以下方法来创建新的临时文档…
static func create(completion: @escaping Result -> Void) throws { let targetURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("Untitled").appendingPathExtension("doc-extension") coordinationQueue.async { let document = MyDocument(fileURL: targetURL) var error: NSError? = nil NSFileCoordinator(filePresenter: nil).coordinate(writingItemAt: targetURL, error: &error) { url in document.save(to: url, for: .forCreating) { success in DispatchQueue.main.async { if success { completion(.success(document)) } else { completion(.failure(MyDocumentError.unableToSaveDocument)) } } } } if let error = error { DispatchQueue.main.async { completion(.failure(error)) } } } }
然后按如下方式初始化并显示DBVC:
@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { lazy var documentBrowser: UIDocumentBrowserViewController = { let utiDecs = Bundle.main.object(forInfoDictionaryKey: kUTExportedTypeDeclarationsKey as String) as! [[String: Any]] let uti = utiDecs.first?[kUTTypeIdentifierKey as String] as! String let dbvc = UIDocumentBrowserViewController(forOpeningFilesWithContentTypes:[uti]) dbvc.delegate = self return dbvc }() func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { window = UIWindow(frame: UIScreen.main.bounds) window?.rootViewController = documentBrowser window?.makeKeyAndVisible() return true } }
我的委托方法如下:
func documentBrowser(_ controller: UIDocumentBrowserViewController, didRequestDocumentCreationWithHandler importHandler: @escaping (URL?, UIDocumentBrowserViewController.ImportMode) -> Swift.Void) { do { try MyDocument.create() { result in switch result { case let .success(document): // .move as I'm moving a temp file, if you're using a template // this will be .copy importHandler(document.fileURL, .move) case let .failure(error): // Show error importHandler(nil, .none) } } } catch { // Show error importHandler(nil, .none) } } func documentBrowser(_ controller: UIDocumentBrowserViewController, didImportDocumentAt sourceURL: URL, toDestinationURL destinationURL: URL) { let document = MyDocument(fileURL: destinationURL) document.open { success in if success { // Modally present DocumentViewContoller for document } else { // Show error } } }
这就是它。 让我知道你是怎么办的!
我有同样的问题,但后来我意识到推荐的方法是简单地从Bundle中复制包/文件夹,如下所示:
func documentBrowser(_ controller: UIDocumentBrowserViewController, didRequestDocumentCreationWithHandler importHandler: @escaping (URL?, UIDocumentBrowserViewController.ImportMode) -> Void) { if let url = Bundle.main.url(forResource: "Your Already Created Package", withExtension: "your-package-extension") { importHandler(url, .copy) } else { importHandler(nil, .none) } }
为了澄清,这个包只是你创建的文件夹,并且已经填入Xcode。
如果您考虑这种方法,这种方法是有道理的,原因如下:
-
Apple文件系统(AFS)。 向AFS的转变意味着复制(几乎)是免费的。
-
权限。 始终允许从Bundle复制,并且用户指定要复制到的位置。
-
新文档浏览器范例。 由于我们正在使用新的
UIDocumentBrowserViewController
范例(由于iOS11和新的Files应用程序),它甚至处理命名(参见Apple的Pages)以及移动和排列文件。 我们不必担心在哪个线程上运行。
所以。 更简单,更容易,也可能更好。 我想不出手动创建所有文件(或使用临时文件夹等)的原因。
在设备上测试,而不是在模拟器中测试。 在我切换到设备测试的那一刻,一切都刚刚开始正常工作。 (注意:可能是模拟器故障仅发生在像我这样的Sierra用户身上。)
- NSFetchedResultsController不会调用controllerDidChangeContent:更新到未获取的NSManagedObject
- 我如何加载单个类的不同xibs取决于当前设备在iOS?
- 从文档目录ios获取文件名
- 在Swift中使用通道进行数据流📻
- 迦太基:iOS平台没有共享的框架计划(为我自己的框架)
- 如何为iOS构buildOpenCV 2.4.9?
- 我们可以locking应用程序,而iPhone进入睡眠模式?
- CLLocationManager kCLErrorDomain代码?
- Xamarin.Forms ZXing.Net.Mobile在iOS 10上扫描结果后丢失当前页面