I have what I thought was a simple View Controller to displayed a preloaded PDF file. The path to the PDF is passed into var pdfPath by the pervious controller.
I have an action/share button I'm trying to use for sharing and printing the PDF using PDFDocument.dataRepresentation(). According to multiple sources online, it should work, but I'm getting a strange error:
[Unknown process name] Failed to load
/System/Library/PrivateFrameworks/CorePDF.framework/Versions/A/CorePDF
Code:
import UIKit
import PDFKit
class PDFViewController: UIViewController {
#IBOutlet weak var ActionBarButton: UIBarButtonItem!
var pdfPath: String? = nil
override func viewDidLoad() {
super.viewDidLoad()
let pdfView = PDFView(frame: self.view.bounds)
self.view.addSubview(pdfView)
pdfView.autoScales = true
if let path = pdfPath {
let fileURL = Bundle.main.url(forResource: path, withExtension: "pdf")
pdfView.document = PDFDocument(url: fileURL!)!
}
}
#IBAction func ActionButtonPressed(_ sender: UIBarButtonItem) {
print("ActionButtonPressed():")
if let path = pdfPath {
let fileURL = Bundle.main.url(forResource: path, withExtension: "pdf")
let pdfDocument = PDFDocument(url: fileURL!)
guard let data = pdfDocument?.dataRepresentation() else {return}
let activityController = UIActivityViewController(activityItems: [data], applicationActivities: nil)
self.present(activityController, animated: true, completion: nil)
}
}
If anyone knows the answer to why this isn't working I'd be very grateful.
Rather than passing the data, you can pass the URL of the file, which UIActivityViewController will recognise and display share options accordingly.
let activityController = UIActivityViewController(activityItems: [fileURL], applicationActivities: nil)
Related
I am creating QR code in swift and assigning it to an imageView
when I try to share that image with generated code, it does not shares that image,
func createCode()
{
let text = email
let data = text.data(using: .ascii, allowLossyConversion: false)
fillter = CIFilter(name: "CIQRCodeGenerator")
fillter.setValue(data, forKey: "inputMessage")
let transform = CGAffineTransform(scaleX: 5.0, y: 5.0)
CreatedImage = UIImage(ciImage: (fillter.outputImage?.transformed(by: transform))!)
imageCode.image = CreatedImage as UIImage
}
and this is share button
#IBAction func shareButtonPressed(_ sender: Any)
{
let activityItem: [UIImage] = [imageCode.image!]
let activity = UIActivityViewController(activityItems: activityItem as [UIImage], applicationActivities: [])
activity.popoverPresentationController?.sourceView = self.view
self.present(activity, animated: true, completion: nil)
}
it shows like it has nothing to share, it does not pick any bit of image
Have you created a variable to store the image somewhere e.g.
var generatedImage: UIImage?
Assuming then, that I have read your question correctly, in your creation function you can cast the image at the end of the function e.g:
generatedImage = imageCode.image
Then in your share function you could say:
guard let validQR = generatedImage else { return }
let activityItem: [UIImage] = [validQR]
let activity = UIActivityViewController(activityItems: activityItem as [UIImage], applicationActivities: [])
activity.popoverPresentationController?.sourceView = self.view
self.present(activity, animated: true, completion: nil)
I tested with an image from my Bundle e.g:
generatedImage = UIImage(named: "SCNPyramid")
And I was able to share the image :)
after searching all..
I cam I to know that make a programmatically screen shot of desired view, that is sent..
I have been having the same problem and solved it by first saving the generated qr code image to a file and then sharing the file url.
private func shareQRCode() {
guard let qrcode = self.qrCodeImage,
let data = qrcode.pngData(),
let url = self.saveInCache(data: data, fileName: "QRCode.png") else { return }
// set up activity view controller
let imageToShare = [url]
let activityViewController = UIActivityViewController(activityItems: imageToShare, applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view // so that iPads won't crash
// work around to prevent dismissing current view after saving image
let tempController = TransparentViewController()
tempController.modalPresentationStyle = .overFullScreen
activityViewController.completionWithItemsHandler = { [weak tempController] _, _, _, _ in
if let presentingViewController = tempController?.presentingViewController {
presentingViewController.dismiss(animated: false, completion: nil)
} else {
tempController?.dismiss(animated: false, completion: nil)
}
}
present(tempController, animated: true) { [weak tempController] in
tempController?.present(activityViewController, animated: true, completion: nil)
}
}
Here is the code for saveInCache function:
private func saveInCache(data: Data, fileName: String) -> URL? {
let paths = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)
let path = paths[0]
let fileUrl = path.appendingPathComponent(fileName)
let fileManager = FileManager.default
if self.pathExists(fileUrl) {
do {
try fileManager.removeItem(at: fileUrl)
} catch { return fileUrl }
}
guard fileManager.createFile(atPath: fileUrl.path, contents: data, attributes: nil) else {
return nil
}
return fileUrl
}
private func pathExists(_ path: URL) -> Bool {
let fileManager = FileManager.default
var isDir: ObjCBool = false
if fileManager.fileExists(atPath: path.path, isDirectory: &isDir) {
if isDir.boolValue {
// file exists and is a directory
return true
} else {
// file exists and is not a directory
return true
}
} else {
// file does not exist
return false
}
}
And here a simple Transparent View Controller for ActivityViewController work around:
final class TransparentViewController: UIViewController {
override func viewDidLoad() {
self.view.backgroundColor = .clear
}
}
I want to share images to Instagram from my own iOS app and I am using Kingfisher throughout the project to download and cache images and show them in UIImageViews but this time I want to do something a little bit different.
Basically, I am getting a response from an API with the url of an image and I want to
Download the image to the library using the URL
There is a bunch of questions on this for objective-C using
UIImageWriteToSavedPhotosAlbum
but I am using Swift.
Rename it with .igo extension (instagram exclusive)
Not sure how to go about this, would depend on number 1.
Then I could share it doing something like
let image = UIImage(named: "downloadedImage")
let objectsToShare: [AnyObject] = [ image! ]
let activityViewController = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view
activityViewController.excludedActivityTypes = [ UIActivityTypeAirDrop, UIActivityTypePostToFacebook ]
self.presentViewController(activityViewController, animated: true, completion: nil)
or I could do it using the instagram hooks:
instagram://library?LocalIdentifier=\(localID)
Documentation on this is scarce specially for Swift. How can I go about this? a push in the right direction is all I need.
It sounds like you already know how to use Kingfisher and retrieving the UIImage from the URL. So what i'm about to provide is information for saving the image to the documents directory and retrieving it to share.
Retrieve the correct directory URL
func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentsDirectory = paths[0]
return documentsDirectory
}
Saving an image to that directory
func saveImage (image: UIImage, filename: String ){
print("Saving image with name \(filename)")
if let data = UIImagePNGRepresentation(image) {
let fullURL = getDocumentsDirectory().appendingPathComponent(filename)
try? data.write(to: fullURL)
}
}
Retrieving an image from the directory
func loadImageFromName(name: String) -> UIImage? {
print("Loading image with name \(name)")
let path = getDocumentsDirectory().appendingPathComponent(name).path
let image = UIImage(contentsOfFile: path)
if image == nil {
print("missing image at: \(path)")
}
return image
}
Sharing an image
func share(shareText shareText:String?,shareImage:UIImage?){
var objectsToShare = [AnyObject]()
if let shareTextObj = shareText{
objectsToShare.append(shareTextObj)
}
if let shareImageObj = shareImage{
objectsToShare.append(shareImageObj)
}
if shareText != nil || shareImage != nil{
let activityViewController = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view
present(activityViewController, animated: true, completion: nil)
}else{
print("There is nothing to share")
}
}
How to Use
let img: UIImage = UIImage() // Replace this with your image from your URL
saveImage(image: img, filename: "newImage.igo") //This is where you change your extension name
let newImage: UIImage = loadImageFromName(name: "newImage.igo") //Retrieve your image with the correct extension
share(shareText: "Image going to Instagram", shareImage: newImage) //Present Activity VC.
And as DFD pointed out, you can exclude certain items from the share VC to only allow what you need.
In my navigation controller, I have a UIBarButtonItem set to System item "Action". I then created the following IBAction code:
#IBAction func shareImage(_ sender: UIBarButtonItem) {
let context = CIContext()
let final = context.createCGImage(imgFinished, from: imgFinished.extent)
let shareImage = UIImage(cgImage: final!)
let vc = UIActivityViewController(activityItems: [shareImage], applicationActivities: [])
vc.excludedActivityTypes = [
UIActivityType.airDrop,
UIActivityType.assignToContact,
UIActivityType.addToReadingList,
//UIActivityType.copyToPasteboard,
//UIActivityType.mail,
//UIActivityType.message,
//UIActivityType.openInIBooks,
//UIActivityType.postToFacebook,
//UIActivityType.postToFlickr,
UIActivityType.postToTencentWeibo,
//UIActivityType.postToTwitter,
UIActivityType.postToVimeo,
UIActivityType.postToWeibo,
UIActivityType.print,
//UIActivityType.saveToCameraRoll
]
present(vc,
animated: true,
completion: nil)
vc.popoverPresentationController?.sourceView = self.view
vc.completionWithItemsHandler = {(activity, success, items, error) in
}
}
The excludedActivityTypes list is a complete/exhaustive list of available UIActivityTypes gleaned from code-complete or command-clicking on UIActivity type and going through the resulting struct. I uncomment those I wish to exclude - but leave them in for quick reference in the future. This will give you the popup you want.
I'm trying to display a pdf file, using an iOS app, that is located on our website. Here's how I'm doing this:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
print("preparing segue")
if segue.identifier == "PdfWebView" {
print("Found segue")
let detailViewController = segue.destinationViewController as! PdfViewController
let myIndexPath = self.tableView.indexPathForSelectedRow!
let row = myIndexPath.row
//Pass selected cell title to next View
detailViewController.website = pdfLinks[row]
print("Website: ", detailViewController.website)
}
}
// This is on pdfViewController
// The webiste = http://www.example.com/some-pdf-document-to-display.pdf
if let website = website {
print("Getting pdf: ",website)
if let pdf = NSBundle.mainBundle().URLForResource(website, withExtension: "pdf", subdirectory: nil, localization: nil){
print(pdf) // <-- this is always nil
let req = NSURLRequest(URL: pdf)
webView.loadRequest(req)
self.view.addSubview(webView)
}
}
What am I doing wrong? Needless to say, this is my very first app that I'm developing.
If the file is not in your app you should not use NSBundle.
let pdfUrl = NSURL(string: website)
let req = NSURLRequest(URL: pdfUrl)
I'm also not sure why you are adding the webView subview to the view. Shouldn't that be done somewhere else? Shouldn't you push a controller with the webview instead?
File is not in your Bundle. Instead you can directly load the URL.
let website = "http://www.sanface.com/pdf/test.pdf"
let reqURL = NSURL(string: website)
let request = NSURLRequest(URL: reqURL!)
webView.loadRequest(request)
I want to share some files I have locally in my app using Share Sheet functionality on iPhone. I display the file in a UIWebView and when the user clicks the share sheet, I want to show options (email, WhatsApp, etc. ) to share the file displayed on the UIWebView. I know that we can use
func displayShareSheet(shareContent:String) {
let activityViewController = UIActivityViewController(activityItems: [shareContent as NSString], applicationActivities: nil)
presentViewController(activityViewController, animated: true, completion: {})
}
to share a string for example. How do I change this code to share documents?
Swift 4.2 and Swift 5
If you already have a file in a directory and want to share it, just add it's URL into activityItems:
let fileURL = NSURL(fileURLWithPath: "The path where the file you want to share is located")
// Create the Array which includes the files you want to share
var filesToShare = [Any]()
// Add the path of the file to the Array
filesToShare.append(fileURL)
// Make the activityViewContoller which shows the share-view
let activityViewController = UIActivityViewController(activityItems: filesToShare, applicationActivities: nil)
// Show the share-view
self.present(activityViewController, animated: true, completion: nil)
If you need to make the file:
I'm using this extension to make files from Data (read the comments in the code for explanation how it works):
As in the typedef's answer, get the current documents directory:
/// Get the current directory
///
/// - Returns: the Current directory in NSURL
func getDocumentsDirectory() -> NSString {
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentsDirectory = paths[0]
return documentsDirectory as NSString
}
Extension for Data:
extension Data {
/// Data into file
///
/// - Parameters:
/// - fileName: the Name of the file you want to write
/// - Returns: Returns the URL where the new file is located in NSURL
func dataToFile(fileName: String) -> NSURL? {
// Make a constant from the data
let data = self
// Make the file path (with the filename) where the file will be loacated after it is created
let filePath = getDocumentsDirectory().appendingPathComponent(fileName)
do {
// Write the file from data into the filepath (if there will be an error, the code jumps to the catch block below)
try data.write(to: URL(fileURLWithPath: filePath))
// Returns the URL where the new file is located in NSURL
return NSURL(fileURLWithPath: filePath)
} catch {
// Prints the localized description of the error from the do block
print("Error writing the file: \(error.localizedDescription)")
}
// Returns nil if there was an error in the do-catch -block
return nil
}
}
Examples how to use:
Share image-files:
// Your image
let yourImage = UIImage()
in png-file
// Convert the image into png image data
let pngImageData = yourImage.pngData()
// Write the png image into a filepath and return the filepath in NSURL
let pngImageURL = pngImageData?.dataToFile(fileName: "nameOfYourImageFile.png")
// Create the Array which includes the files you want to share
var filesToShare = [Any]()
// Add the path of png image to the Array
filesToShare.append(pngImageURL!)
// Make the activityViewContoller which shows the share-view
let activityViewController = UIActivityViewController(activityItems: filesToShare, applicationActivities: nil)
// Show the share-view
self.present(activityViewController, animated: true, completion: nil)
in jpg-file
// Convert the image into jpeg image data. compressionQuality is the quality-compression ratio in % (from 0.0 (0%) to 1.0 (100%)); 1 is the best quality but have bigger filesize
let jpgImageData = yourImage.jpegData(compressionQuality: 1.0)
// Write the jpg image into a filepath and return the filepath in NSURL
let jpgImageURL = jpgImageData?.dataToFile(fileName: "nameOfYourImageFile.jpg")
// Create the Array which includes the files you want to share
var filesToShare = [Any]()
// Add the path of jpg image to the Array
filesToShare.append(jpgImageURL!)
// Make the activityViewContoller which shows the share-view
let activityViewController = UIActivityViewController(activityItems: filesToShare, applicationActivities: nil)
// Show the share-view
self.present(activityViewController, animated: true, completion: nil)
Share text-files:
// Your String including the text you want share in a file
let text = "yourText"
// Convert the String into Data
let textData = text.data(using: .utf8)
// Write the text into a filepath and return the filepath in NSURL
// Specify the file type you want the file be by changing the end of the filename (.txt, .json, .pdf...)
let textURL = textData?.dataToFile(fileName: "nameOfYourFile.txt")
// Create the Array which includes the files you want to share
var filesToShare = [Any]()
// Add the path of the text file to the Array
filesToShare.append(textURL!)
// Make the activityViewContoller which shows the share-view
let activityViewController = UIActivityViewController(activityItems: filesToShare, applicationActivities: nil)
// Show the share-view
self.present(activityViewController, animated: true, completion: nil)
Other files:
You can make a file from anything which is in Data format and as far as I know, almost everything in Swift can be converted into Data like String, Int, Double, Any...:
// the Data you want to share as a file
let data = Data()
// Write the data into a filepath and return the filepath in NSURL
// Change the file-extension to specify the filetype (.txt, .json, .pdf, .png, .jpg, .tiff...)
let fileURL = data.dataToFile(fileName: "nameOfYourFile.extension")
// Create the Array which includes the files you want to share
var filesToShare = [Any]()
// Add the path of the file to the Array
filesToShare.append(fileURL!)
// Make the activityViewContoller which shows the share-view
let activityViewController = UIActivityViewController(activityItems: filesToShare, applicationActivities: nil)
// Show the share-view
self.present(activityViewController, animated: true, completion: nil)
I want to share my solution of UIActivityViewController and sharing text as a image file. This solution works for sharing via Mail and even Save to Dropbox.
#IBAction func shareCsv(sender: AnyObject) {
//Your CSV text
let str = self.descriptionText.text!
filename = getDocumentsDirectory().stringByAppendingPathComponent("file.png")
do {
try str.writeToFile(filename!, atomically: true, encoding: NSUTF8StringEncoding)
let fileURL = NSURL(fileURLWithPath: filename!)
let objectsToShare = [fileURL]
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
self.presentViewController(activityVC, animated: true, completion: nil)
} catch {
print("cannot write file")
// failed to write file – bad permissions, bad filename, missing permissions, or more likely it can't be converted to the encoding
}
}
func getDocumentsDirectory() -> NSString {
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentsDirectory = paths[0]
return documentsDirectory
}
Here's the Swift 3 version:
let dictToSave: [String: Any] = [
"someKey": "someValue"
]
let jsonData = try JSONSerialization.data(withJSONObject: dictToSave, options: .prettyPrinted)
let filename = "\(self.getDocumentsDirectory())/filename.extension"
let fileURL = URL(fileURLWithPath: filename)
try jsonData.write(to: fileURL, options: .atomic)
let vc = UIActivityViewController(activityItems: [fileURL], applicationActivities: [])
self.present(vc, animated: true)
func getDocumentsDirectory() -> String {
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentsDirectory = paths[0]
return documentsDirectory
}
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?
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.
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 .
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
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.
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
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!)
}
}
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)
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
}
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)
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
this answer if you want detail description of using QuickLook.framework
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 during viewDidLoad and sets it to use the view's frame
The URL for the PDF file is safely unwrapped from the bundle and then a PDFDocument is created, if possible
Some common settings are used. Adjust as needed
Finally, it adds the PDFView as a subview of the controller's view
//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)
}
}
if let url: URL = URL(string: "http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIWebView_Class/UIWebView_Class.pdf") {
webView.loadRequest(URLRequest(url: url)) }
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)
}