WebKit 1 exposed the WebFrameView where I could call a print operation.
- (void)webView:(WebView *)sender printFrameView:(WebFrameView *)frameView {
NSPrintOperation *printOperation = [frameView printOperationWithPrintInfo:[NSPrintInfo sharedPrintInfo]];
[printOperation runOperation];
}
With WKWebKit API I can't seem to figure out how to perform a similar action or which view to grab for printing. All my efforts have come up with blank pages.
Amazingly, WKWebView
still doesn't support printing on macOS, despite the legacy WebView being deprecated.
Looking at https://github.com/WebKit/webkit/commit/0dfc67a174b79a8a401cf6f60c02150ba27334e5 , printing was implemented years ago as a private API, but for some reason, has not been exposed. If you don't mind using a private API, you can print a WKWebView
with:
public extension WKWebView {
// standard printing doesn't work for WKWebView; see http://www.openradar.me/23649229 and https://bugs.webkit.org/show_bug.cgi?id=151276
@available(OSX, deprecated: 10.16, message: "WKWebView printing will hopefully get fixed someday – maybe in 10.16?")
private static let webViewPrintSelector = Selector(("_printOperationWithPrintInfo:")) // https://github.com/WebKit/webkit/commit/0dfc67a174b79a8a401cf6f60c02150ba27334e5
func webViewPrintOperation(withSettings printSettings: [NSPrintInfo.AttributeKey : Any]) -> NSPrintOperation? {
guard self.responds(to: Self.webViewPrintSelector) else {
return nil
}
guard let po: NSPrintOperation = self.perform(Self.webViewPrintSelector, with: NSPrintInfo(dictionary: printSettings))?.takeUnretainedValue() as? NSPrintOperation else {
return nil
}
// without initializing the print view's frame we get the breakpoint at AppKitBreakInDebugger:
// ERROR: The NSPrintOperation view's frame was not initialized properly before knowsPageRange: returned. This will fail in a future release! (WKPrintingView)
po.view?.frame = self.bounds
return po
}
}
You can have this be the default print operation for your NSDocument
subclass by adding:
override func printOperation(withSettings printSettings: [NSPrintInfo.AttributeKey : Any]) throws -> NSPrintOperation {
return myWebView.webViewPrintOperation(withSettings: printSettings) ?? try super.printOperation(withSettings: printSettings)
}
Here is marcprux swift solution in Objective C:
SEL printSelector = NSSelectorFromString(@"_printOperationWithPrintInfo:");
if ([self.webView respondsToSelector:printSelector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
NSPrintOperation *printOperation = (NSPrintOperation*) [self.webView performSelector:printSelector withObject:[NSPrintInfo sharedPrintInfo]];
#pragma clang diagnostic pop
return printOperation;
}