import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate{
@IBOutlet weak var webVw: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Load a URL
if let url = URL(string: "https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_print") {
let request = URLRequest(url: url)
webVw.load(request)
}
}
}
"Print this page" button not showing anything but loading the same url in safari and clicking the same button showing the print page option.
2
Answers
Alright, let’s tackle this printing issue! So, you’ve got a
WKWebView
and you want your users to be able to print the web page, just like they can in Safari. But, bummer,WKWebView
doesn’t support the JavaScriptwindow.print()
function by default. No worries though, there’s a workaround!Here’s a more casual walkthrough of the solution:
window.print()
. Instead of doing the usual print thing, this sly script will send us a secret "print please!" message.WKWebView
configuration. Don’t forget to add a "printHandler" to handle the secret messages.WKWebView
with the new configuration.And there you have it! With a little JavaScript trickery, your users can now print the webpage as they can in Safari. You just took your
WKWebView
to the next level. High fives all around! 🙌Just remember to switch out
webVw
with the actual name of your WKWebView’s IBOutlet.Sorry I misunderstood you earlier.
So, we need a workaround. We’ll employ JavaScript injection using
WKUserScript
to catch thewindow.print()
function call within theWKWebView
. This is possible due to the interoperability of Swift with JavaScript withinWKWebView
.Now, let’s dissect the code:
WKUserScript
object with a JavaScript code snippet that redefines thewindow.print()
function. In our version, it sends a message using the WebKit message handler,window.webkit.messageHandlers.printHandler.postMessage('print')
.WKWebView
via its configuration, which contains a user content controller. We also add a message handler for ‘printHandler’, which is going to catch the message we’ve set up in our JavaScript.Setting up WKWebView: Now, initialize the
WKWebView
with the configuration. However, the earlier warning arises due to the WebView being assigned to a weak property, which leads to its immediate deallocation. Hence, we’re going to leverage the already setWKWebView
from the storyboard, which is managed by ARC.URL Loading: Here, we load the URL as usual.
Handling the script message:
WKScriptMessageHandler
protocol implementation helps us handle the receipt of the print message. When we receive the "printHandler" message, we call a native functionprintPage()
.UIPrintInteractionController
to present the system print dialog in theprintPage()
function.This solution is somewhat a bridge between the webpage’s JavaScript environment and our native code.
Now, if
window.print()
function isn’t being called as expected, you should inspect the JavaScript code running on the webpage. It’s possible that thewindow.print()
function is being defined after the page load, overriding your custom function. You can use polling to consistently check for the definition ofwindow.print()
function, and replace it with your custom function if it’s been overwritten.Finally, this solution assumes that the webpage is executing the
window.print()
function to initiate printing. If the page uses a different mechanism, this solution won’t work, and we’d need to inspect the page’s JavaScript further.