Skip to content

Instantly share code, notes, and snippets.

@Enriquecm
Last active November 11, 2024 07:46
Show Gist options
  • Save Enriquecm/43ad7ed40dafdcaa51001a7a07f1def4 to your computer and use it in GitHub Desktop.
Save Enriquecm/43ad7ed40dafdcaa51001a7a07f1def4 to your computer and use it in GitHub Desktop.
Using QLPreviewController and SwiftUI to preview many common file types (PDF, iWork, Microsoft Office documents, images, texts, etc).
import SwiftUI
struct DocView: View {
@State private var buttonPressed: Bool = false
var body: some View {
Button {
buttonPressed = true
} label: {
Text("Show PDF file")
}
.sheet(isPresented: $buttonPressed) {
let localURL = Bundle.main.url(forResource: "Sample", withExtension: "pdf")!
PreviewController(url: localURL)
}
}
}
import SwiftUI
struct DocView: View {
private let urlSession = URLSession.shared
@State private var isLoading: Bool = false
@State private var localDocURL: URL?
var body: some View {
ZStack {
if isLoading {
ProgressView()
} else {
Button {
if let url = URL(string: "https://www.africau.edu/images/default/sample.pdf") {
loadDocument(with: url)
}
} label: {
Text("Load and Show PDF file")
}
}
}
.sheet(item: $localDocURL) { url in
if let url = url {
PreviewController(url: url)
}
}
}
// MARK: -
func loadDocument(with url: URL) {
isLoading = true
urlSession.downloadTask(with: url) { location, response, error in
if let location = location {
self.localDocURL = copyDocumentToCache(location, url: url)
} else if let error = error {
print("Error to download file: \(error)")
} else {
print("Unknown error")
}
self.isLoading = false
}
.resume()
}
private func copyDocumentToCache(_ locationURL: URL, url: URL) -> URL? {
let documentsPath = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
let destinationURL = documentsPath.appendingPathComponent(url.lastPathComponent)
try? FileManager.default.removeItem(at: destinationURL)
do {
try FileManager.default.copyItem(at: locationURL, to: destinationURL)
return destinationURL
} catch let error {
print("Error to copy file to cache: \(error)")
return nil
}
}
}
private extension URL: Identifiable {
public var id: URL { self }
}
import QuickLook
import SwiftUI
struct PreviewController: UIViewControllerRepresentable {
@Environment(\.dismiss) private var dismiss
let url: URL
func makeUIViewController(context: Context) -> UINavigationController {
let controller = QLPreviewController()
controller.dataSource = context.coordinator
controller.navigationItem.leftBarButtonItem = UIBarButtonItem(
barButtonSystemItem: .done, target: context.coordinator,
action: #selector(context.coordinator.dismiss)
)
let navigationController = UINavigationController(rootViewController: controller)
return navigationController
}
func updateUIViewController(_ uiViewController: UINavigationController, context: Context) {}
func makeCoordinator() -> Coordinator {
return Coordinator(parent: self)
}
class Coordinator: QLPreviewControllerDataSource {
let parent: PreviewController
init(parent: PreviewController) {
self.parent = parent
}
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
return 1
}
func previewController(
_ controller: QLPreviewController,
previewItemAt index: Int
) -> QLPreviewItem {
return parent.url as NSURL
}
@objc func dismiss() {
parent.dismiss()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment