Building an incredibly simple PDF Signing App

A few days ago I tweeted about my frustrations with document signings apps.

My frustrations boiled down to 3 main points:.

  1. Lengthy unskippable onboarding
  2. Forced signup
  3. Questionable privacy policies

So I wanted to build a completely free, zero-bloat, no catch document signer. And after sitting down for 10 minutes, it was done. So instead of going through the hassle of trying to publish it, I’m gonna write this tutorial so if you want it, you can make it.

Step One

Open Xcode, make a new project, and this is important, pick a ‘Document app’

Give it a nice name, I chose PleasantPDF. Make sure the Interface is Storyboard, the Life Cycle is UIKit App Delegate, and the Language is Swift.

Support PDFs

Now we need to tell iPadOS/iOS that our app can handle PDFs. So go to

Info > Document Types and we’ll replace the existing entry. Give it the name ‘PDF’, and the Types

com.adobe.pdf

Add CFBundleTypeRole to ‘Additional document type properties and give it the value Editor.

Open PDFs in app

So the key to make this app so quickly and so simply is to not try and write a PDF Viewer, hook it into PencilKit or touches or anything, we’re going to use QuickLook.

Open DocumentBrowserViewController.swift

Jump down to the function func presentDocument(at documentURL: URL) and delete the contents of the function, we’re going to replace this implementation.

But first, create a new class level variable called documentUrl: URL?.

Now in the presentDocument(at:) function, fill it with this:

func presentDocument(at documentURL: URL) {
	self.documentUrl = documentURL
	self.documentUrl?.startAccessingSecurityScopedResource()
	let qlController = QLPreviewController()
	qlController.dataSource = self
	self.present(qlController, animated: true, completion: nil)
}

You’ll get an error saying that

Cannot assign value of type 'DocumentBrowserViewController' to type 'QLPreviewControllerDataSource?'

So go ahead and click Fix on that issue, or if it doesn’t appear, just add QLPreviewControllerDataSource to inheritance of the class.

class DocumentBrowserViewController: UIDocumentBrowserViewController, UIDocumentBrowserViewControllerDelegate, QLPreviewControllerDataSource {

Implement the function numberOfPreviewItems like this:

func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
	1
}

And now the magic bit, this function

func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
	return self.documentUrl! as QLPreviewItem
}

Build & Run!

Wrapping Up

That’s literally it. The Document app template type handles adding to the Share Sheet, and you can build upon this however you like. But this will get you a very quick and no-frills document signer.

Warning: Don’t try and use this app to redact documents, this is not secure.