Download, Store, and View PDF in Swift

I’ve been working on an App that requires me to download PDF files, store it, and to view it. To accomplish the task, there are three main topics:

  • DownloadTask
  • File Management
  • PDFView

To download the file from an URL, we need to use downloadTask . Since we also need to tack where the location had the task have placed our files, the observer, which is ViewController in my example, needs to conform to URLSessionDownloadDelegate .

To see where the downloaded file is located, simply inspect the location printed in the Xcode console.

After I pressed download, the file downloaded persisted less than a second, and then it was killed by the system. This behavior behaves the same on both simulator and physical machine.

Image for post
Image for post

Each App created in iOS has its own sandbox. Inside the sandbox, there are three main portions that iOS developers should know: Bundle Container, Data Container, and iCloud Container. Here I am going to only specify on Data Container to stay focus on our task — download PDF.

Image for post
Image for post
reference: https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW4

Data container is the space where the your code can manipulate the files downloaded from the Internet after the is compiled. Below am I listing the important features:

  • Files inside Library and tmp will be cleaned up by iOS automatically.
  • iTunes will backup all the files in Data Container except Caches, tmp and files specifying .isExcludedFromBackup = true . During App review, if Apple finds out that unneeded files being backed up in iTines, it’s likely the App will be rejected.
  • Caches (not Documents) is the location to store downloaded files.

[Update] Thanks to the response from Remmelt Koenes. It’s better to store the pdf files in Caches rather than Documents.

  • Data which is explicitly accepted by the user as personal, and potentially backuped in his/her iCloud space, should be written in user’s “Documents” directory
  • Data that belongs and extends your application (an extension user can download for instance,…), but which is NOT in the bundle, should be written in a subfolder of “Application Support/” directory, having the title of your appID. It can also be the “Cache” directory.
  • Data with short-life time can be stored in the tmp directory of your application. In this case, use of NSTemporaryDirectory() is possible to get the “tmp” directory. Check this link for additional help.

Hence, the next step is to copy the file from tmp to Cache. I’ve done this by:

  1. extracting the original pdf name,
  2. creating a url in Cache,
  3. deleting file with the same name to avoid Copy Error: “CFNetworkDownload_mdrFNb.tmp” couldn’t be copied to “Documents” because an item with the same name already exists. , and
  4. copying it to Cache.
Image for post
Image for post

Now we’ve successfully placed the downloaded PDF into the proper place for users to access. It’s time to view it with PDFView from PDFKit, which is a convenient framework provided by Apple since the release of iOS 11.

Even though many tutorials of PDFKit uses storyboard to create PDFView by assigning the property to a UIView, it does not support in Xibs. Thus here I’m going to instantiate it programmatically.

Image for post
Image for post

Wa-Lah!!! Now we’ve fetched the opened the PDF successfully 😀. I know the size doesn’t fit, and I’ll be focusing on PDFKit in the next article. Enjoy!

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store