I have a PDF that I'm pulling from a sever that came in the form of NSData and now I need to display it. I've looked far and wide for a solution to this and I haven't found anything that bridges the gap between raw NSData and actually saving or showing the PDF.
I tried this but now I'm stuck not knowing how to save or show:
let cfData = CFDataCreate(kCFAllocatorDefault, UnsafePointer<UInt8>(data.bytes), data.length)
let cgDataProvider = CGDataProviderCreateWithCFData(cfData)
let cgPDFDocument = CGPDFDocumentCreateWithProvider(cgDataProvider)
Assign paperRect and printableRect let page = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // A4, 72 dpi render. setValue(page, forKey: "paperRect") render. setValue(page, forKey: "printableRect") // 4. Create PDF context and draw let pdfData = NSMutableData() UIGraphicsBeginPDFContextToData(pdfData, .
First of all, that NSData IS your PDF, no need to convert to another data type or use a library to manipulate it at the moment.
For now, simply save the NSData to your documents directory on iOS, which is not a managed persistent store like CoreData or Realm, nor is it UserDefaults. It's a folder with stuff in it.
Save to Documents Folder:
let data = //the stuff from your web request or other method of getting pdf
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
let filePath = "\(documentsPath)/myCoolPDF.pdf"
data.writeToFile(filePath, atomically: true)
Now verify that the file is there and open it on your mac. This is to make sure you've saved an actual PDF and not anything else. This is a two step process. First find out where on earth the file went by printing the location of the documents folder from the iOS simulator:
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentsDirectory = paths[0]
print(documentsDirectory)
Now copy that really long filepath and cd [paste location]
in terminal to go there, then open myCoolPDF.pdf
to open it in Preview! It's magical times!
Now that you have verified that you're dealing with an actual PDF it's time to display that in a WebView since it's quite simple unless you've got your own way of doing so.
Note that you still have to make it so the webview shows up, drag one onto your viewController in a storyboard and make an IBOutlet for it.
let url = NSURL(fileURLWithPath: filePath)
let webView = UIWebView()
webView.loadRequest(NSURLRequest(URL: url))
Obviously this is a quick way to make sure you get the basics going, you don't want to force unwrap unsafely using !
.
Starting with iOS 11 you don't need a web view and can use a dedicated PDFKit framework. With PDFKit loading a PDF from a URL
or Data
instance can be as simple as:
import PDFKit
// some other code here
// ...
let pdfView = PDFView()
// add pdfView to the view hierarchy and possibly add auto-layout constraints
// ...
pdfView.document = PDFDocument(data: data)
Check out PDFKit documentation for more details.
Update:
For Saving Files to Documents Directory.
let documentPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let path = "\(documentPath)/filename.pdf"
yourData.write(toFile: path, atomically: true)
For retrieving the path of Document Directory.
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentsDirectory = paths[0]
Here you can append your filename with backslash in front. And you can test whether your file exists there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With