Skip to content

Instantly share code, notes, and snippets.

Created February 19, 2023 20:40
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
Creating PDFs From WKWebView
// ViewController.swift
// WebKitPDFAndImageDemo
// Created by Aryaman Sharda on 2/18/23.
import UIKit
import WebKit
class ViewController: UIViewController {
private lazy var webView: WKWebView = {
// We'll go ahead and use the default configuration here. Some cool options here, but not in scope.
let webView = WKWebView(frame: .zero, configuration: WKWebViewConfiguration())
// This will be used to determine when the web page has fully loaded.
webView.navigationDelegate = self
return webView
override func viewDidLoad() {
loadURL(from: "")
private func loadURL(from string: String) {
guard let url = URL(string: string) else {
webView.load(URLRequest(url: url))
private func saveAsPDF(title: String?) {
let pdfConfiguration = WKPDFConfiguration()
/// Using `webView.scrollView.frame` allows us to capture the entire page, not just the visible portion
pdfConfiguration.rect = CGRect(x: 0, y: 0, width: webView.scrollView.contentSize.width, height: webView.scrollView.contentSize.height)
webView.createPDF(configuration: pdfConfiguration) { result in
switch result {
case .success(let data):
guard let downloadsDirectory = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first else {
do {
let savePath = downloadsDirectory.appendingPathComponent(title ?? "PDF").appendingPathExtension("pdf")
try data.write(to: savePath)
print("Successfully created and saved PDF at \(savePath)")
} catch let error {
print("Could not save pdf due to \(error.localizedDescription)")
case .failure(let failure):
extension ViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
// The web view has finished loading the resource, we can now create a PDF
saveAsPDF(title: webView.title)
extension UIView {
func pinToSuperview() {
guard let superview else { return }
translatesAutoresizingMaskIntoConstraints = false
topAnchor.constraint(equalTo: superview.topAnchor),
bottomAnchor.constraint(equalTo: superview.bottomAnchor),
leadingAnchor.constraint(equalTo: superview.leadingAnchor),
trailingAnchor.constraint(equalTo: superview.trailingAnchor)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment