szakes1
szakes1

Reputation: 904

How to implement PDF Viewer to SwiftUI application?

I'm building an app, which displays PDFs, but I don't know how to display a PDF file using SwiftUI. I found tutorials on how to display a PDF file using UIKit, but there are no tutorials about SwiftUI. Can anyone help me?

I'm also trying to do that using MVVM design pattern. If there's someone, who can help me, I will be extremely grateful!

File structure

App

Code:

HomeView.swift

import SwiftUI

struct HomeView: View {
    
    var deeds: [Deed] = deedsData
    
    var body: some View {
        NavigationView {
                List(deeds) { item in
                    Button(action: {
                        
                    }) {
                        HStack {
                            Image(systemName: "doc.fill")
                            Text(item.title)
                        }
                    }
                }
                .navigationTitle("title")
        }
    }
}

struct HomeView_Previews: PreviewProvider {
    static var previews: some View {
        HomeView(deeds: deedsData)
    }
}

DeedModel.swift

import SwiftUI

struct Deed: Identifiable {
    var id = UUID()
    var title: String
    var URL: String
}

let deedsData: [Deed] = [
    Deed(title: NSLocalizedString("civilCode", comment: "Civil code"), URL: "https://isap.sejm.gov.pl/isap.nsf/download.xsp/WDU19640160093/U/D19640093Lj.pdf"),
    Deed(title: NSLocalizedString("penalCode", comment: "Penal code"), URL: "https://isap.sejm.gov.pl/isap.nsf/download.xsp/WDU19970880553/U/D19970553Lj.pdf"),
    Deed(title: NSLocalizedString("civilProcedureCode", comment: "Code of civil procedure"), URL: "https://isap.sejm.gov.pl/isap.nsf/download.xsp/WDU19640430296/U/D19640296Lj.pdf"),
    Deed(title: NSLocalizedString("familyAndGuardianshipCode", comment: "Family and guardianship code"), URL: "http://isap.sejm.gov.pl/isap.nsf/download.xsp/WDU19640090059/U/D19640059Lj.pdf"),
    Deed(title: NSLocalizedString("laborCode", comment: "Labor code"), URL: "https://isap.sejm.gov.pl/isap.nsf/download.xsp/WDU19740240141/U/D19740141Lj.pdf"),
]

Anyone knows how can I do that in MVVM pattern?

Upvotes: 8

Views: 14607

Answers (2)

Quambadeur
Quambadeur

Reputation: 230

There is some nice View Modifier available since iOS 14: .quickLookPreview($url)

@State var url: URL?
Button("PDF preview") {
  url = Bundle.main.url(forResource: "mypdfdocument", withExtension: "pdf")
}
 .quickLookPreview($url)

Upvotes: 3

jnpdx
jnpdx

Reputation: 52535

To display a PDF with Apple-only frameworks, you'll need to use UIKit, via a UIViewRepresentable:

import PDFKit
import SwiftUI

struct PDFKitRepresentedView: UIViewRepresentable {
    typealias UIViewType = PDFView

    let data: Data
    let singlePage: Bool

    init(_ data: Data, singlePage: Bool = false) {
        self.data = data
        self.singlePage = singlePage
    }

    func makeUIView(context _: UIViewRepresentableContext<PDFKitRepresentedView>) -> UIViewType {
        // Create a `PDFView` and set its `PDFDocument`.
        let pdfView = PDFView()
        pdfView.document = PDFDocument(data: data)
        pdfView.autoScales = true
        if singlePage {
            pdfView.displayMode = .singlePage
        }
        return pdfView
    }

    func updateUIView(_ pdfView: UIViewType, context _: UIViewRepresentableContext<PDFKitRepresentedView>) {
        pdfView.document = PDFDocument(data: data)
    }
}

then PDFKitRepresentedView can be used in your view hierarchy.

This takes a Data object as input, so you'll need to convert those URL objects you have to Data via a network call first. So, you might do something like:

@State var data : Data? 

...

.onAppear {
  self.data = try? Data(contentsOf: url)
}

Keep in mind this is vastly simplified -- you'll want to do some error handling, etc. Might want to do some searching on SwiftUI network calls.

Upvotes: 24

Related Questions