Open PDF file using swift
IosIphoneSwiftIos Problem Overview
How can I add a PDF file for an app , where you click on a button to view the file & when you're done you get back to screen you were at?
Ios Solutions
Solution 1 - Ios
If you simply want to view a PDF file you can load it into a UIWebView.
let url : NSURL! = NSURL(string: "http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIWebView_Class/UIWebView_Class.pdf")
webView.loadRequest(NSURLRequest(URL: url))
Swift 4.1 :
let url: URL! = URL(string: "http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIWebView_Class/UIWebView_Class.pdf")
webView.loadRequest(URLRequest(url: url))
If you'd like to achieve more, a good framework is PSPDFKit.
Solution 2 - Ios
Apple added PDFKit framework in iOS 11
Add a UIView to your view controller and make it's class to PDFView
import UIKit
import PDFKit
class ViewController: UIViewController {
@IBOutlet var pdfView: PDFView!
override func viewDidLoad() {
super.viewDidLoad()
if let path = Bundle.main.path(forResource: "sample", ofType: "pdf") {
if let pdfDocument = PDFDocument(url: URL(fileURLWithPath: path)) {
pdfView.displayMode = .singlePageContinuous
pdfView.autoScales = true
pdfView.displayDirection = .vertical
pdfView.document = pdfDocument
}
}
}
}
There are 4 display modes : singlePage
, singlePageContinuous
, twoUp
, twoUpContinuous
.
Solution 3 - Ios
SWIFT 4+
If has to open file from local cache/Documentdiectory which has file path
Method 1: using UIDocumentInteractionController
class ViewController: UIViewController,UIDocumentInteractionControllerDelegate {
//let path = Bundle.main.path(forResource: "Guide", ofType: ".pdf")!
let dc = UIDocumentInteractionController(url: URL(fileURLWithPath: path))
dc.delegate = self
dc.presentPreview(animated: true)
}
//MARK: UIDocumentInteractionController delegates
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
return self//or use return self.navigationController for fetching app navigation bar colour
}
Method 2: using WebView
let webview = WKWebView(frame: UIScreen.main.bounds)
view.addSubview(webview)
webview.navigationDelegate = self
webview.load(URLRequest(url: URL(fileURLWithPath: path)))//URL(string: "http://") for web URL
Solution 4 - Ios
For Xcode 8.1 and Swift 3.0
Save the PDF file in any folder of your xcode. Suppose the file name is 'Filename.pdf'
if let pdf = Bundle.main.url(forResource: "Filename", withExtension: "pdf", subdirectory: nil, localization: nil) {
let req = NSURLRequest(url: pdf)
yourWebViewOutletName.loadRequest(req as URLRequest)
}
Same will apply if you want to open any html file.
Solution 5 - Ios
you can use UIDocumentInteractionController to preview file in IOS. In the view controller's file, add a property of type UIDocumentInteractionController
and implement a simple delegate method of it
self.documentInteractionController = UIDocumentInteractionController.init(URL: url)
self.documentInteractionController?.delegate = self
self.documentInteractionController?.presentPreviewAnimated(true)
func documentInteractionControllerViewControllerForPreview(controller: UIDocumentInteractionController) -> UIViewController {
return self
}
don't forget to add UIDocumentInteractionControllerDelegate
in view controller's class
Solution 6 - Ios
Check out PDFKit from IOS11
Here is an example of a view controller which implements PDFView from PDFKit.
import UIKit
import PDFKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Add PDFView to view controller.
let pdfView = PDFView(frame: self.view.bounds)
self.view.addSubview(pdfView)
// Fit content in PDFView.
pdfView.autoScales = true
// Load Sample.pdf file.
let fileURL = Bundle.main.url(forResource: "Sample", withExtension: "pdf")
pdfView.document = PDFDocument(url: fileURL!)
}
}
Solution 7 - Ios
SWIFT 5
An update to open the file from the Document directory (device) and present preview:
let urlFile = URL(string: pathToFile)
var documentInteractionController: UIDocumentInteractionController!
documentInteractionController = UIDocumentInteractionController.init(url: urlFile!)
documentInteractionController?.delegate = self
documentInteractionController?.presentPreview(animated: true)
And UIDocumentInteractionControllerDelegate:
extension ViewController: UIDocumentInteractionControllerDelegate {
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
return self
}
}
If you want to dismiss the document preview you can use:
documentInteractionController?.dismissPreview(animated: true)
Solution 8 - Ios
You can use this code in Swift 4
-
Import PDFKit
-
Copy this code
let pdfView = PDFView() pdfView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(pdfView) pdfView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true pdfView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true pdfView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true pdfView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true guard let path = Bundle.main.url(forResource: "test", withExtension: "pdf") else { return } if let document = PDFDocument(url: path) { pdfView.document = document }
Solution 9 - Ios
You can use this UIViewController
. It contains the share button
for free:
import UIKit
import PDFKit
class PDFWebViewController: UIViewController {
var pdfURL: URL!
private var pdfView: PDFView!
override func viewDidLoad() {
super.viewDidLoad()
self.edgesForExtendedLayout = []
self.setPDFView()
self.fetchPDF()
}
private func setPDFView() {
DispatchQueue.main.async {
self.pdfView = PDFView(frame: self.view.bounds)
self.pdfView.maxScaleFactor = 3;
self.pdfView.minScaleFactor = self.pdfView.scaleFactorForSizeToFit;
self.pdfView.autoScales = true;
self.pdfView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
self.view.addSubview(self.pdfView)
}
}
private func fetchPDF() {
DispatchQueue.global(qos: .userInitiated).async {
if let data = try? Data(contentsOf: self.pdfURL), let document = PDFDocument(data: data) {
DispatchQueue.main.async {
self.pdfView.document = document
self.addShareBarButton()
}
}
}
}
private func addShareBarButton() {
let barButtonItem = UIBarButtonItem(barButtonSystemItem: .action,
target: self,
action: #selector(self.presentShare))
barButtonItem.tintColor = .white
self.navigationItem.rightBarButtonItem = barButtonItem
}
@objc private func presentShare() {
guard let pdfDocument = self.pdfView.document?.dataRepresentation() else { return }
let activityViewController = UIActivityViewController(activityItems: [pdfDocument], applicationActivities: nil)
activityViewController.popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem
self.present(activityViewController, animated: true)
}
}
To use it:
let viewController = PDFWebViewController()
// the url can be a web url or a file url
viewController.pdfURL = url
self.navigationController?.pushViewController(viewController, animated: true)
Solution 10 - Ios
You can also use Quick Look Framework from Apple.
It is very flexible.
You can show your PDF file with zoom feature.
Also you have support for all other types (like png, jpg, docx, txt, rtf, xlsx, zip, mov, etc) of files and it is very easy to use.
Please refer
Solution 11 - Ios
A modernized version of Akila's answer, with the benefit that it is a drop in, ready to use UIViewController
that you can integrate into your app.
import UIKit
import PDFKit
final class PDFViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let pdfView = PDFView(frame: view.frame)
title = "Your_title_here"
if let url = Bundle.main.url(forResource: "document_name_here", withExtension: "pdf"),
let pdfDocument = PDFDocument(url: url) {
pdfView.displayMode = .singlePageContinuous
pdfView.autoScales = true
pdfView.displayDirection = .vertical
pdfView.document = pdfDocument
view.addSubview(pdfView)
}
}
}
- It creates the
PDFView
duringviewDidLoad
and sets it to use the view's frame - The
URL
for the PDF file is safely unwrapped from the bundle and then aPDFDocument
is created, if possible - Some common settings are used. Adjust as needed
- Finally, it adds the
PDFView
as a subview of the controller'sview
Solution 12 - Ios
//In Swift 5
class PDFBookViewController: UIViewController, PDFViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
addPDFView()
}
private func addPDFView() {
let pdfView = PDFView()
pdfView.translatesAutoresizingMaskIntoConstraints = false
pdfContenerView.addSubview(pdfView)
pdfView.leadingAnchor.constraint(equalTo: pdfContenerView.safeAreaLayoutGuide.leadingAnchor).isActive = true
pdfView.trailingAnchor.constraint(equalTo: pdfContenerView.safeAreaLayoutGuide.trailingAnchor).isActive = true
pdfView.topAnchor.constraint(equalTo: pdfContenerView.safeAreaLayoutGuide.topAnchor).isActive = true
pdfView.bottomAnchor.constraint(equalTo: pdfContenerView.safeAreaLayoutGuide.bottomAnchor).isActive = true
pdfView.autoScales = true
pdfView.displayMode = .singlePageContinuous
pdfView.displayDirection = .vertical
///Open pdf with help of FileManager URL
if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
let bookWithPdf = "\(bookname).pdf"
let fileURL = dir.appendingPathComponent(bookWithPdf)
let document = PDFDocument(url: fileURL)
pdfView.document = document
}
@IBAction func backButtonPressed(_ sender: Any) {
navigationController?.popViewController(animated: true)
}
}
Solution 13 - Ios
let openLink = NSURL(string : OtherContactorProfileVview.Result.CertificateList[index].CertificateFileLink)
if #available(iOS 9.0, *) {
let svc = SFSafariViewController(url: openLink! as URL)
present(svc, animated: true, completion: nil)
} else {
let port = UIStoryboard(
name: "Main",
bundle: nil
).instantiateViewController(withIdentifier: "PDFViewer") as! PDFViewer
port.strUrl = OtherContactorProfileVview.Result.CertificateList[index].CertificateFileLink
navigationController?.pushViewController(port, animated: true)
}