0

I am creating an app to display a PDF file selected by UIDocumentPickerViewController for iPads. Although the following code works fine with simulators of Xcode, for some reason, it won't work with my test iPad (iPad Mini, 5th gen). I can select a file, and its URL seems to be obtained appropriately; however, the PDF file is not displayed.

I would appreciate it if you could help me figure out what is happening and how to fix this.

import UIKit
import PDFKit

class ViewController: UIViewController, UIGestureRecognizerDelegate,  UIDocumentPickerDelegate {
    
    
    @IBOutlet weak var pdfView: PDFView!
    
    
    override func viewDidAppear(_ animated: Bool) {
        
        //document picker
        let documentPicker = UIDocumentPickerViewController(documentTypes: ["com.adobe.pdf"], in: .import)
        documentPicker.delegate = self
        documentPicker.allowsMultipleSelection = false
        present(documentPicker, animated: true, completion: nil)
    }
    internal func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
        print(url)
        if let pdfDocument = PDFDocument(url: url)
        {
            pdfView.autoScales = true
            pdfView.document = pdfDocument
            pdfView.displayDirection = .horizontal
            pdfView.usePageViewController(true, withViewOptions: [UIPageViewController.OptionsKey.interPageSpacing: 20])
        } else{
            print ("error, which is what I am seeing in my iPad now")
        }
    }
    
    
    
    override func viewDidLoad(){
        super.viewDidLoad()
    }

details of the environment:

  • iPad mini: 5th gen, iOS 14
  • Xcode: 14
  • Simulators: iOS 14 (I tried the majority of simulators and the app works well with them all)
user8460166
  • 73
  • 1
  • 6
  • 24

2 Answers2

2

For me, in my case, it was a security issue. Adding this simple code resolved the issue:

let shouldStopAccessing = pickedFolderURL.startAccessingSecurityScopedResource()
        defer {
          if shouldStopAccessing {
            pickedFolderURL.stopAccessingSecurityScopedResource()
          }
       }

I got this code from here: StackOverflow Post

Christian W
  • 353
  • 2
  • 12
1

You are neglecting the fact that the url is security scoped. See the documentation in the section called "Working with External Documents".

(Also note that in iOS 14 your initializer is deprecated. But that's another matter.)

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Thank you for your insight, @matt! While reading the website you posted, I changed `url` -> `fileUrl` to eliminate the potential ambiguity in code where ` if let pdfDocument = PDFDocument(url: url)`. (and other places) And now the app is actually working. Do you have any thoughts on this? Thanks! – user8460166 Sep 22 '20 at 22:54
  • That makes no sense. You must have different code from what you've shown me. – matt Sep 22 '20 at 22:57
  • You're right! I replaced back `fileUrl` with `url`, and the app is still working. Although I did not intentionally change anything else, I might have played with some other places and changed something.. Thank you for that. – user8460166 Sep 22 '20 at 23:26