29

I want to know if there is any way for a offline build for xcode iOS such that we can display pdf file from local file.

The method I'm using now is via UIWebView to display a custom HTML which contain the PDF URL (online) , but I want to make an offline version if possible.

But from online research, it seems to me the only way to display PDF is via UIWebView, if that is really the case, is it possible to pull the file from local resource (e.g. add files to my xcode resource folder) rather than using the PDF URL.

OFF-TOPIC: Which would be a better choice? To pull local file or to use the online URL for PDF file?

As UIWebView require connection, it would seem to be a better choice to just pull the online URL as it will be the most current and updated.

Feedback is much appreciated.

EDIT: quick question, if I use the UIDocumentInteractionController method or the QuickLook framework to make it offline, this would mean I have to release update patch each time there is new PDF article added in (correct me if I'm wrong)

Taking this point into consideration, I've come up with a counter-argument to my own question on the spot (Sorry if any of you feel you are wasting time on me >.<, I am a person who like to question possibilities and the different approach one could take to solve a problem) In the event to save time from the constant updating and providing a real time base solution, which is to use UIWebView (I know this is contradicting my purpose of this SO thread), as this proj is base on a online website (getting my content and sources from there), if I were to load their website for the article section, would it be bold of me to say that by adding a NSString variable, I can add in the NSRange function to the viewDidLoad together with the UIWebView such that the URL will never leave the news section and PDF URL. e.g. using combination of if and NSRange function to counter check that the URL only contain the news section and PDF URL)

I did once before a NSRange function for point on calculator so I thought it would be a good time to put it in use for this framework app.

P.S - This app is a organization base project and I'm a intern providing them with the base skeleton framework.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Yang Jie Domodomo
  • 685
  • 1
  • 8
  • 25

12 Answers12

38

Many options, here are 3:

1) The easiest way to load and display a local pdf file is to use a UIWebview like that:

NSString *path = [[NSBundle mainBundle] pathForResource:@"document" ofType:@"pdf"];
NSURL *targetURL = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:targetURL];
[webView loadRequest:request];

2) You can also use a UIDocumentInteractionController/QLPreviewController to display PDF Files natively.

3) Another way would be to build a custom PDF Viewer, as in apples ZoomingPDFViewer example code. (using UIPageViewController + CATiledLayer + UIScrollView)

Cœur
  • 37,241
  • 25
  • 195
  • 267
calimarkus
  • 9,955
  • 2
  • 28
  • 48
34

You can use a UIWebView to get the PDF from your bundle directly, no need to call an online web service.

Local File:

NSString *html = [NSString stringWithContentsOfFile:path1 encoding:NSUTF8StringEncoding error:nil];
[self.webView loadHTMLString:html baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle]bundlePath]]];

Remote File:

- (void) loadRemotePdf
    {
       CGRect rect = [[UIScreen mainScreen] bounds];
       CGSize screenSize = rect.size;
        
       UIWebView *myWebView = [[UIWebView alloc] initWithFrame:CGRectMake(0,0,screenSize.width,screenSize.height)];
        webView.autoresizesSubviews = YES;
            webView.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);

       NSURL *myUrl = [NSURL URLWithString:@"http://www.mysite.com/test.pdf"];
       NSURLRequest *myRequest = [NSURLRequest requestWithURL:myUrl];
            
       [webView loadRequest:myRequest];

       [window addSubview: myWebView];
       [myWebView release];
            
}
self
  • 1,205
  • 1
  • 14
  • 17
  • Correct me if I'm wrong, but I will still require internet access to view the UIWebView right? And the logic behind your code is something like basic HTML code to pull local variable file. Thanks very much for your help. If left with no choice, I think yours is very simple and straight to the point solving method. – Yang Jie Domodomo Jun 04 '12 at 09:54
  • 4
    No!, you can access local html files with UIWebView, non need to connect to remote servers, with UIWebView, you can do both, remote and local files(it's the path that changes :) ) – self Jun 04 '12 at 10:02
  • 2
    to load a local pdf (*without internet connection*), you can use this code: http://stackoverflow.com/questions/2832245/iphone-can-we-open-pdf-file-using-uiwebview – calimarkus Jun 04 '12 at 12:15
  • AlbrahimZ, why did you remove the pdf loading code again? That is what he was searching for. Not to load a local html file. – calimarkus Jun 05 '12 at 08:45
  • No not completly, my code was about loading a *local PDF file* in a webview. That is what he asked ;) – calimarkus Jun 05 '12 at 08:57
  • in iOS9, using the method just show an blank webview. I have to use the way describe in the post http://stackoverflow.com/questions/24130547/uiwebview-showing-blank-screen-in-ios-8 – xi.lin Jun 12 '16 at 06:29
  • As of iOS 11 this is no longer the recommended solution check out the new PDFKit framework, or the QuickLook framework (iOS9). – cleverbit Dec 25 '17 at 19:09
11

I advise you using the QuickLook framework while handling PDF files.

Rui Peres
  • 25,741
  • 9
  • 87
  • 137
6

Apple’s PDFKit framework provides a huge range of code to help us work with PDFs, and one of the most useful is PDFView – it renders PDFs to the screen and lets users interact with them.

To try it out, start by importing the PDFKit framework:

import PDFKit

Next, add this code to your viewDidLoad() method to create a PDFView and make it fill all available space:

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

Finally, create a URL pointing to a PDF you have in your bundle somewhere (or one in your documents directory), then create a PDFDocument object from that and pass it to the PDF view:

guard let path = Bundle.main.url(forResource: "example", withExtension: "pdf") else { return }

if let document = PDFDocument(url: path) {
    pdfView.document = document
}

Done!

Ali A. Jalil
  • 873
  • 11
  • 25
  • Original [source](https://www.hackingwithswift.com/example-code/libraries/how-to-display-pdfs-using-pdfview) – XME Nov 26 '20 at 20:50
  • Improvement: I would say is that put creating and constrains code to overload func loadView(). – Juraj Antas Jun 24 '22 at 12:51
5

There is a new toolkit IOs has introduced. It has many dedicated features related to displaying PDFs. You can use PdfView class in it to display a PDF either from a local file or via a URL.

PDFKit > PDFView

Rizan Zaky
  • 4,230
  • 3
  • 25
  • 39
4

SWIFT 4.x

UIWebview approach in swift:

//let url = URL.init(string: "https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/pdf_open_parameters.pdf")! // for file in web
let url = Bundle.main.url(forResource: "filename", withExtension: ".pdf")! // for file in bundle
let webView = UIWebView.init(frame: view.frame)
webView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
webView.loadRequest(URLRequest.init(url: url))
view.addSubview(webView)
Olcay Ertaş
  • 5,987
  • 8
  • 76
  • 112
Argus
  • 2,241
  • 1
  • 22
  • 27
2

I found this site and is a very easy method to open pdf's with any available pdf capable app that is loaded on the iPhone. (I prefer iBooks)

simple way to present and open a pdf file

user2616647
  • 131
  • 9
2
NSString *path = [[NSBundle mainBundle] pathForResource:@"Yourpdf" ofType:@"pdf"];
NSURL *targetURL = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:targetURL];
UIWebView *webView=[[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 300, 400)];
[[webView scrollView] setContentOffset:CGPointMake(0,500) animated:YES];
[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"window.scrollTo(0.0, 50.0)"]];
[webView loadRequest:request];
[self.view addSubview:webView];
Ved Rauniyar
  • 1,539
  • 14
  • 21
2

In my case, I have a tableView that segues to a PDFView based on either a selected row or detail indicator (there are two different ViewControllers for each in different parts of my app). I have an @IBOutlet for the PDFView and use this code to open the desired PDF, which is saved in the app:

@IBOutlet weak var myPDFView: PDFView!

var mySelection = String()

override func viewDidLoad() {
    super.viewDidLoad()

    if let path = Bundle.main.path(forResource: mySelection, ofType: "pdf") {
        let url = URL(fileURLWithPath: path)

        if let myDocument = PDFDocument(url: url) {
            myPDFView.document = myDocument
            myPDFView.autoScales = true
            myPDFView.displayMode = .singlePageContinuous
            myPDFView.displayDirection = .vertical
            myPDFView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        }
    }
}

This all works great. The correct PDFs load easily and fill the screen like I want. However, the PDF is always scrolled up just a little, causing the top portion to be hidden under the navigation bar. Notice in the screen shot below that the top of the document is not visible but the bottom is, just above the tab bar at the bottom. I think this has to do with PDF coordinates starting at the bottom of the page but cannot figure out how to get it to load the very top of the document, so the background at the top is visible.

Simulator Screen Shot Link

Perhaps this has to do with autoScales?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Tracker6
  • 21
  • 3
1

It's late but there is some limitation with UIWebview on loading pdf files, It won't load editable pdf properly. so load any type of pdf files use following code

NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"pdfFileName" ofType:@"pdf"]];
PDFView *view = [[PDFView alloc] initWithFrame:self.view.frame];
view.document = [[PDFDocument alloc] initWithURL:url];
[self.view addSubview:view];
Shaik Riyaz
  • 11,204
  • 7
  • 53
  • 70
1

You can also use UIDocumentInteractionController !

let docController = UIDocumentInteractionController(url: URL(fileURLWithPath: path)) documentInteractionController.presentPreview(animated: true)

Badre
  • 710
  • 9
  • 17
0

we are iOS coders, no JS/Web programmer, so stay in swift and Apple APIs. The faster, cleaner, way is to use Quicklook.

I quote calimarkus.

Anyway code is very simple:

//  Copyright © 2019 ing.conti. All rights reserved.
//

import UIKit
import QuickLook


class ViewController: UIViewController, QLPreviewControllerDataSource {

    var previewController:QLPreviewController?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        self.previewController = QLPreviewController()
        previewController!.dataSource = self
        present(previewController!, animated: true)

    }

    //QL delegate:

    func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
        return 1
    }


    func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {

        guard let url = Bundle.main.url(forResource: "SAMPLE", withExtension: "pdf") else {
            fatalError("Could not load pdf")
        }

        return url as QLPreviewItem 
    }
}
ingconti
  • 10,876
  • 3
  • 61
  • 48