Document Handling in SwiftUI

Photo by Viktor Talashuk on Unsplash

This article contains complete flow of handling Documents from picking to previewing with SwiftUI. This is kind of code along. The flow is as follows:

Pick Documents from Files

Files such as text, word and csv can be picked using ‘UIDocumentPickerViewController’ of UIKit. The same can be used with SwiftUI using UIViewControllerRepresentable bridge.

UIViewControllerRepresentable is used to bridge UIKit and SwiftUI.

UIDocumentPickerViewController is created by specifying file types supported.

‘didPickDocumentsAt’ of DocumentPickerCoordinator will be called after user selects documents with list of urls of documents. We are using ProjectReportsViewModel to handle picked document URL.

Files Organisation

Whether the documents stored in local or iCloud, Organising files is really important.

In our example, We will store all the documents related to a project inside a directory with the name of Project.

Path: ./Documents/Projects/<project name>/<document name>

We use Core Data along with cloud kit to store details of document.

Name, size and url are properties of document. Location is used to differentiate document storage between iCloud and local.

Adding Documents to Local

LocalDocHandler

We will create a LocalDocHandler file which is responsible for adding and deleting files to local.

“group.com.maheshsai.walker” is an app group which can be used to hold files related to app in local

Adding Documents to iCloud

iCloudDocHandler

We will create a iCloudDocHandler file which is responsible for adding and deleting files to iCloud.

“iCloud.com.maheshsai.pedometer” is an iCloud Container which can be used to hold files related to app in iCloud

Add App Groups and iCloud Containers from Signing and Capabilities Tab. Also Don’t forget to add the same to extensions if you use files there.

Integrating Document Handlers with ViewModel

In addURLS(pickedURL: URL, storeInIcloud: Bool ), we are copying document to local or iCloud based on user preference and create a TrackerDocument object with details of document.

Whenever user selects a document to open, generateUrl(of doc: TrackerDocument) -> URL? will generate URL of selected document. If document does not belong to device and stored in iCloud then it will start download in background.

removeUrls(from index: IndexSet) remove Documents if present in local of device or iCloud and tells user operation not permitted if document is stored in Local of other device.

Preview Documents

Similar to UIDocumentPickerViewController, we will be using QLPreviewController to preview selected document.

Since we are previewing only one document selected by user, we return 1 in numberOfPreviewItems and return the url of selected document at next function.

SwiftUI Views

Finally, Let us put all view model, Document Picker and Preview Controller into action. We will first create a simple Document List View, present Document Picker over sheet and open document with Preview Controller when user selects one.

We will create a View ProjectDocumentOpener to monitor if url is generated for user selected document and download is completed if stored in iCloud. Once url is generated and document download is completed if stored in iCloud , the PreviewController is triggered with the url.

Demo

The complete code can be accessed from here. Let us see how this code in action,

Thanks for Reading..)

Using Data Science to provide better solutions to real word problems