The reference file document does not trigger any save action upon objectWillChange, assuming this is what trigger the write mechanism.
I've tested both using a simple String as the Snopshot type. As well as my production document model which is an ObservableObject.
Is it a bug? Or can Apple engineer provide a working example using ReferenceFileDocument?
version: XCode 12 beta 6
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
How to use UIDocument in SwiftUI's DocumentGroup?
I was thinking to wrap the UIDocument in a ReferenceFileDocument. However, the ReferenceFileDocument doesn't have a fileURL property, and I can't figure out a way to get it.
Any ideas?
First and foremost, this question is intended to explore the feasibility, and possible workaround, of using SwiftUI 2.0 to build production ready document-based app.
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 :(*.
Solutions: Two obvious solutions,
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.
My questions are:
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.
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)
		}
}
// 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
		}
}
What's the price model for the shared database, i.e. the record user shared with others.
Does the record user shared counting towards the app's public database quota?
Or does it remain in user's private database quota for whom shared that record?
In another word, would implement the sharing feature(without using the public database) lead to additional cost on the developer side?
The document states that using private database counts towards the user's storage quota. However, I'm confused about the aspects "Data transfer" and "Requests per Second".
Let's consider a few examples,
a) Single Container
An app only operates within a single container and use the private database only, either manually using cloudkit or managed by core data.
b) Multiple Container
An app use multiple containers, within each container only use private database.
Does the "Data transfer" and "Requests Per Second" applicable to above cases?
Many thanks,