Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 54 additions & 9 deletions ios/Classes/SwiftFlutterHtmlToPdfPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,80 @@ import WebKit
public class SwiftFlutterHtmlToPdfPlugin: NSObject, FlutterPlugin{
var wkWebView : WKWebView!
var urlObservation: NSKeyValueObservation?
private var didFinishOnce: Bool = false

public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "flutter_html_to_pdf", binaryMessenger: registrar.messenger())
let instance = SwiftFlutterHtmlToPdfPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}

private func topViewController() -> UIViewController? {
let window: UIWindow?
if #available(iOS 13.0, *) {
window = UIApplication.shared.connectedScenes
.compactMap { $0 as? UIWindowScene }
.first(where: { $0.activationState == .foregroundActive })?
.windows
.first(where: { $0.isKeyWindow })
} else {
window = UIApplication.shared.keyWindow ?? UIApplication.shared.delegate?.window ?? nil
}

var vc = window?.rootViewController
while let presented = vc?.presentedViewController {
vc = presented
}
return vc
}

public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "convertHtmlToPdf":
let args = call.arguments as? [String: Any]
let htmlFilePath = args!["htmlFilePath"] as? String
guard let args = call.arguments as? [String: Any],
let htmlFilePath = args["htmlFilePath"] as? String,
!htmlFilePath.isEmpty else {
result(FlutterError(code: "INVALID_ARGUMENTS",
message: "Missing htmlFilePath",
details: nil))
return
}

// !!! this is workaround for issue with rendering PDF images on iOS !!!
let viewControler = UIApplication.shared.delegate?.window?!.rootViewController
wkWebView = WKWebView.init(frame: viewControler!.view.bounds)
guard let viewControler = topViewController() else {
result(FlutterError(code: "NO_VIEW_CONTROLLER",
message: "Could not find a root view controller",
details: nil))
return
}

didFinishOnce = false
wkWebView = WKWebView.init(frame: viewControler.view.bounds)
wkWebView.isHidden = true
wkWebView.tag = 100
viewControler?.view.addSubview(wkWebView)
viewControler.view.addSubview(wkWebView)

let htmlFileContent = FileHelper.getContent(from: htmlFilePath!) // get html content from file
let htmlFileContent = FileHelper.getContent(from: htmlFilePath) // get html content from file
wkWebView.loadHTMLString(htmlFileContent, baseURL: Bundle.main.bundleURL) // load html into hidden webview

urlObservation = wkWebView.observe(\.isLoading, changeHandler: { (webView, change) in
urlObservation = wkWebView.observe(\.isLoading, changeHandler: { [weak self] (webView, change) in
guard let self = self else { return }
if webView.isLoading { return }
if self.didFinishOnce { return }
self.didFinishOnce = true

// this is workaround for issue with loading local images
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
let convertedFileURL = PDFCreator.create(printFormatter: self.wkWebView.viewPrintFormatter())
guard let wkWebView = self.wkWebView else {
result(FlutterError(code: "WEBVIEW_DISPOSED",
message: "WKWebView was disposed before PDF generation finished",
details: nil))
return
}

let convertedFileURL = PDFCreator.create(printFormatter: wkWebView.viewPrintFormatter())
let convertedFilePath = convertedFileURL.absoluteString.replacingOccurrences(of: "file://", with: "") // return generated pdf path
if let viewWithTag = viewControler?.view.viewWithTag(100) {
if let viewWithTag = viewControler.view.viewWithTag(100) {
viewWithTag.removeFromSuperview() // remove hidden webview when pdf is generated

// clear WKWebView cache
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version: 0.7.0
homepage: https://github.com/Afur/flutter_html_to_pdf

environment:
sdk: '>=2.12.0 <3.0.0'
sdk: '>=2.12.0 <4.0.0'
flutter: ">=1.12.0"

dependencies:
Expand Down