2014-11-16 7 views
4

Я пытаюсь захватить вызов window.print() javascript из WKWebView с моим приложением, чтобы на самом деле отобразить диалоговое окно печати и разрешить им печатать с кнопки, представленной на странице (вместо кнопки внутри моего приложения). Кто-нибудь знает, как это сделать?Захват window.print() из WKWebView

В настоящее время для меня, щелкнув ссылку, которая вызывает window.print(), просто ничего не происходит, кроме как вызвать делегат метода solvePolicyForNavigationAction, и я не мог найти что-либо в нем.

+0

Могу ли я спросить, какой вид вы печатаете? – MobileOverlord

+0

Я печатаю вид WKWebViewPrintFormatter –

ответ

5

Выяснил это сразу после публикации (очевидно) ... Надеюсь, это поможет кому-то еще.

При создании веб-просмотра ...

let configuration = WKWebViewConfiguration() 
let script = WKUserScript(source: "window.print = function() { window.webkit.messageHandlers.print.postMessage('print') }", injectionTime: WKUserScriptInjectionTime.AtDocumentEnd, forMainFrameOnly: true) 
configuration.userContentController.addUserScript(script) 
configuration.userContentController.addScriptMessageHandler(self, name: "print") 
self.webView = WKWebView(frame: CGRectZero, configuration: configuration) 

Затем просто принять протокол WKScriptMessageHandler в контроллере представления и добавить нужный метод ...

func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) { 
    if message.name == "print" { 
     printCurrentPage() 
    } else { 
     println("Some other message sent from web page...") 
    } 
} 

func printCurrentPage() { 
    let printController = UIPrintInteractionController.sharedPrintController() 
    let printFormatter = self.webView.viewPrintFormatter() 
    printController?.printFormatter = printFormatter 

    let completionHandler: UIPrintInteractionCompletionHandler = { (printController, completed, error) in 
     if !completed { 
      if let e = error? { 
       println("[PRINT] Failed: \(e.domain) (\(e.code))") 
      } else { 
       println("[PRINT] Canceled") 
      } 
     } 
    } 

    if let controller = printController? { 
     if UIDevice.currentDevice().userInterfaceIdiom == .Pad { 
      controller.presentFromBarButtonItem(someBarButtonItem, animated: true, completionHandler: completionHandler) 
     } else { 
      controller.presentAnimated(true, completionHandler: completionHandler) 
     } 
    } 
} 
+0

Что такое 'self.browserController.addressBarActivityButton' для iPad? –

+1

На iPad вы должны представить контроллер печати с помощью кнопки/вида. Это всего лишь элемент кнопки «бар», из которого я представляю. Оставленный от копирования кода из моего проекта. –

0

есть undocumented делегат hooking window.print() s

class MyApp: WKUIDelegate { 
    func makeWebview() { 
     ... 
     self.webview.UIDelegate = self 
    } 
    func _webView(webView: WKWebView!, printFrame: WKFrameInfo) { 
     println("JS: window.print()") 
     printCurrentPage() 
    }  
} 
+0

Кажется странным, что они разоблачили метод делегата для создания нового окна, но сохранили его один. Надеюсь, они изменят это в будущем. Если вам не нужно, чтобы ваше приложение одобрялось яблоком, это, вероятно, хороший способ. –

+1

«Частные» методы WebView не настолько конфиденциальны, многие люди используют их в своих приложениях в App Store, и даже поддерживают подписи подчёркиваемых функций после их распространения на общедоступные методы. В частности, Apple добавила новый частный метод для WKWebView в iOS9/OSX10.11: _printOperationWithPrintInfo: https://github.com/WebKit/webkit/commit/0dfc67a174b79a8a401cf6f60c02150ba27334e5 – kfix