Printing from a WKWebView

I need to print some outline art for kids to color. It’s just the image, no UI, no other content.

Does anyone know how to print from a WKWebView? I have a button in my app that calls upon a window.print() function that works on desktop, but not on iOS.

How can I bring the window picker on iOS to select the Print option? From what I’ve read, there’s no easy way. Would it just be easier to open a browser with the image I need to print and print from Safari instead?

Again postmessage is your friend.

A little looking around there are a few pages out there that imply you just need use the formatter and UIPrintInteractionController

So another hack to test if it can be done. ( I was suprised on my first try it worked. )

//-- Posted messages  from Hype page
if message.name == "print"{

    let webviewPrint = webView.viewPrintFormatter()
    let printInfo = UIPrintInfo(dictionary: nil)
    printInfo.jobName = "page"
    printInfo.outputType = .general
    let printController = UIPrintInteractionController.shared
    printController.printInfo = printInfo
    printController.showsNumberOfCopies = false
    printController.printFormatter = webviewPrint
    printController.present(animated: true, completionHandler: nil)
    
}


This should give you a starting point…

THank you for this. But I pasted this code on my WebViewController and got several errors. I guess it needs a function before, but not sure what that is.

Likely you are pasting that in the wrong place ( top level) ??!.

I did not elaborate as you seemed to get the gist of my previous examples for you…

which has similar postMessage handlers.

The code above is doing a similar thing but is using the print code.

This example is on older 12.2 iOS as I am constrained to that build at the min.
But should open ok.

hype
printTest.hype.zip (19.4 KB)

xcode
printTest.zip (437.8 KB)

Ah yes, I’m a designer, so no knowledge of swift whatsoever. Previously I was able to compare your Xcode files with mine and figure out which code to copy/paste to make the external URL work.

With the print function, though, because I already had a

let messageName = “openStore”

for the URL function, I used the same messageName for printing, but it didn’t work.

I’m attaching my Xcode with your Hype file. Perhaps you can take a look and see what’s wrong? I changed your button so it’s now

window.webkit.messageHandlers.openStore.postMessage(‘print’); // post

Thanks again!

AlplhaPod.zip (1.9 MB)

It is because you have two if conditions looking for the same thing.

You really need to get some basics under your belt in JS and then some of swift may make sense to you since a lot of the structure in the very basic syntax is similar.

In you example

change this lines.

 //-- declare a message name to use later
       let messageName = "openStore"

to

 //-- declare a message name to use later
       let openStore = "openStore"
      let printPage = "print"

change the lines

//MARK: - PRINT
    if message.name == "openStore"{
        
        let webviewPrint = webView.viewPrintFormatter()

to

//MARK: - PRINT
        if message.name == printPage {
            
            let webviewPrint = webView.viewPrintFormatter()

change the line

wcontroller.add( self , name: messageName )

to

wcontroller.add( self , name: openStore )

wcontroller.add( self , name: printPage )

This will now accept two postMessages with different names from hype.

The print one

window.webkit.messageHandlers.print.postMessage('print');

and openStore

window.webkit.messageHandlers.openStore.postMessage('https://www.hackingwithswift.com/read/32/3/how-to-use-sfsafariviewcontroller-to-browse-a-web-page');


The name of a postMessage is shown here ( in bold)…

window.webkit.messageHandlers.openStore.postMessage(

`window.webkit.messageHandlers.print.postMessage(

3 Likes

Yes, that worked!

Thank you so much. I agree, I need to take some courses on JS and Swift pronto. Thanks for all your help, I really appreciate it.

I added:

printInfo.orientation = .landscape

since there’s no way to change the orientation within the iOS ecosystem, oddly enough, and landscape would truncate images.

1 Like