Last active
November 11, 2024 07:46
-
-
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).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 } | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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