Motivation: The new document based app in SwiftUI 2.0 still lacking many features, for example,
DocumentGroup: almost not customizable, i.e. template selection, tint color, nav bar items.
FileDocument/ReferenceFileDocument: No conflict resolution whatsoever. And as far as my trails, the ReferenceFileDocument cannot trigger any write operation :(*.
the SwiftUI 1.0 solution is using the traditional AppDelegate, SceneDelegate, etc, then hosting the DocumentEditorView which assuming it is the SwiftUI view.
However, it makes develop cross iOS/macOS app harder.
Also harder to use the new SwiftUI stuff like AppStorage, ScenceStorage, WindowGroup, Widgets etcs. (OR there are workarounds maybe?)
the SwiftUI 2.0 solution, I have actually tried two paths.
A not very successful one, using #if os check to use @UIApplicationDelegateAdaptor and @NSApplicationDelegateAdaptor. (let me know if you use this path).
So far partially worked, creating a SwiftUI view to wrap the DocumentBrowserViewController. see the demo code below.
I) Has anyone successed in using like UIDocument directly in a DocumentGroup?
II) Is DocumentGroup with "proper workaround" actually sufficient enough to replace the old framework?
III)Do you know any drawbacks to wrap a UIDocumentBrowserViewController in a SwiftUI's Representable? And if the drawback is serious enough that we should give up the SwiftUI 2.0's new App structure, and use the AppDelegate approach.
IV) Any related discussion is welcomed.
Code Block swift struct DocumentBrowserView: View { /// The presentation of the view itself. @Binding var isPresented: Bool @StateObject var model = ViewModel() var body: some View { Group { #if os(iOS) RepresentedUIDocumentBrowser() .fullScreenCover(isPresented: .init(get: { model.state == .loadedAndPresentingDocument }, set: { _ in // handle state in onDismiss. }), onDismiss: { model.clearDocument() }, content: { if model.document != nil { EmptyView() .environmentObject(model.document!) } else { EmptyView() } }) #elseif os(macOS) Text("macOS NSDocumentController? Stub here.") #else fatalError("OS not supported.") #endif } .edgesIgnoringSafeArea(.all) } }
Code Block swift // MARK: - SwiftUI Interface struct RepresentedUIDocumentBrowser { @Binding var isPresented: Bool @Binding var configuration: Configuration let supportedContentTypes: [UTType]? = nil func dismissView() { isPresented = false } } extension RepresentedUIDocumentBrowser { public struct Configuration { var allowsDocumentCreation = true var allowsPickingMultipleItems = false var shouldShowFileExtensions = false var viewTintColor: UIColor = .systemOrange } } // MARK: - UIViewControllerRepresentable extension RepresentedUIDocumentBrowser: UIViewControllerRepresentable { typealias UIViewControllerType = CustomUIDocumentBrowserViewController func makeCoordinator() -> Coordinator { Coordinator(parent: self) } func makeUIViewController(context: Context) -> CustomUIDocumentBrowserViewController { let vc = CustomUIDocumentBrowserViewController(forOpening: supportedContentTypes) vc.delegate = context.coordinator updateUIViewController(vc, context: context) return vc } func updateUIViewController(_ uiViewController: CustomUIDocumentBrowserViewController, context: Context) { let vc = uiViewController vc.allowsDocumentCreation = configuration.allowsDocumentCreation vc.allowsPickingMultipleItems = configuration.allowsPickingMultipleItems vc.shouldShowFileExtensions = configuration.shouldShowFileExtensions vc.view.tintColor = configuration.viewTintColor } } // MARK: - UIDocumentBrowserViewController Subclass extension RepresentedUIDocumentBrowser { class CustomUIDocumentBrowserViewController: UIDocumentBrowserViewController { // Customizations } } // MARK: - UIDocumentBrowserViewControllerDelegate extension RepresentedUIDocumentBrowser { class Coordinator: NSObject, UIDocumentBrowserViewControllerDelegate { var parent: RepresentedUIDocumentBrowser init(parent: RepresentedUIDocumentBrowser) { self.parent = parent } // MARK: Create New func documentBrowser(_ controller: UIDocumentBrowserViewController, didRequestDocumentCreationWithHandler importHandler: @escaping (URL?, UIDocumentBrowserViewController.ImportMode) -> Void) { } func documentBrowser(_ controller: UIDocumentBrowserViewController, didImportDocumentAt sourceURL: URL, toDestinationURL destinationURL: URL) { } func documentBrowser(_ controller: UIDocumentBrowserViewController, failedToImportDocumentAt documentURL: URL, error: Error?) { } // MARK: Select func documentBrowser(_ controller: UIDocumentBrowserViewController, didPickDocumentsAt documentURLs: [URL]) { } // MARK: UIActivity } }