1

I am trying to cache a PDFDocument downloaded from Firebase but it is not working. I am using PDFKit to display the pdf.

Here is the code I have:

    let cache = NSCache<NSString, PDFDocument>()

    func downloadPDF() {

    var thePdf = PDFDocument()

    if let cachedPdf = cache.object(forKey: "CachedPdf") {
         thePdf = cachedPdf
         self.pdfView.document = thePdf
         print("retrieved from cache")
     } else {

        //download
        guard let record = getRecord else {return}
        let storage = Storage.storage().reference(forURL: record.storageUrl)
        storage.downloadURL { (url, error) in
            if error == nil {

                if let getUrl = url {
                    thePdf = PDFDocument(url: getUrl) ?? PDFDocument()
                    self.cache.setObject(thePdf, forKey: "CachedPdf")
                    self.pdfView.document = thePdf
                    print("downloaded")
                }

            } else {
                guard let err = error else { return }
                self.alert(title: "Error", message: err.localizedDescription)
            }

        }

     }
}

It never stores or retrieves anything from the cache, it always downloads the pdf.
Why is cache not working for this file?

Noah-1
  • 396
  • 1
  • 5
  • 20
  • You should check if there is a cached object `cache.object(forKey: "CachedPdf")` before trying to download your pdf data – Leo Dabus Apr 12 '20 at 03:46
  • I am doing that inside `if error == nil` – Noah-1 Apr 12 '20 at 03:48
  • you need to do that before downloadURL and move the downloadURL to the else condition of the cache check – Leo Dabus Apr 12 '20 at 03:52
  • Oh yeah, that would not have worked like it was before but I updated the code like you told me and I don't see why it isn't caching it yet. It keeps downloading it. – Noah-1 Apr 12 '20 at 04:03
  • You need to move your cache declaration out of your method. It should be a property of your view controller `let cache = NSCache()` then `func downloadPDF() {` – Leo Dabus Apr 12 '20 at 04:12
  • Another dumb mistake but again fixed it and it still won't cache it. I tried doing this sometime ago and reached this same point. I don't know if maybe cache just can't store PDFDocuments ? – Noah-1 Apr 12 '20 at 04:17
  • what is being printed? – Leo Dabus Apr 12 '20 at 04:17
  • "downloaded" every time – Noah-1 Apr 12 '20 at 04:18
  • add `print("cache", self.cache.object(forKey: "CachedPdf"))` there right after print("downloaded") and check what you get – Leo Dabus Apr 12 '20 at 04:21
  • it prints: "cache Optional()" with a different id every time. – Noah-1 Apr 12 '20 at 04:24
  • 1
    So it looks like your cache object it is not the same. Are you sure you are not creating a new view controller before downloading it? Try creating a singleton (shared instance) and add the cache there. Check this https://stackoverflow.com/a/47481780/2303865 – Leo Dabus Apr 12 '20 at 04:27
  • btw change `thePdf = PDFDocument(url: getUrl) ?? PDFDocument()` to `if let thePdf = PDFDocument(url: getUrl) { self.thePdf = thePdf` – Leo Dabus Apr 12 '20 at 04:39
  • `if let url = url,` `let thePdf = PDFDocument(url: url) {` `self.thePdf = thePdf` `self.cache.setObject(thePdf, forKey: "CachedPdf")` `self.pdfView.document = thePdf` `print("downloaded")` `}` – Leo Dabus Apr 12 '20 at 04:41
  • 1
    Oh man thanks a lot. I thought that cache was a singleton by default so the issue was that I kept creating a new cache every time the view loaded. The singleton suggestion fixed it. – Noah-1 Apr 12 '20 at 04:49

0 Answers0