web-dev-qa-db-fra.com

Attraper un événement Javascript dans iOS WKWebview avec Swift

Je crée une application avec des langages de programmation Web et je veux démarrer la caméra lorsque l'utilisateur clique sur un bouton HTML. Puisque je veux que ma vue de caméra soit personnalisée, je dois la concevoir avec Swift. Donc, lorsque l'utilisateur clique sur ce bouton HTML, je veux "attraper" ce clic dans Swift afin que je puisse démarrer ma vue native de la caméra.

Je sais que cela peut être fait avec WKWebview, mais je ne sais pas vraiment comment faire cela.

Par exemple, mon code Javascript (jQuery) pourrait ressembler à ça:

// User clicks to start the native camera with Swift
$(".camera_button").click(function() {
    // Function to call the camera view from JS to Swift
});

Pouvez-vous m'aider à faire ça?

Merci.

20
fraxool

Sur la base de la réponse de @Alex Pelletier, qui m'a vraiment aidé, voici la solution à ma question.

Dans ma fonction "loadView ()", voici ce que j'ai:

let contentController = WKUserContentController();
contentController.addScriptMessageHandler(
    self,
    name: "callbackHandler"
)

let config = WKWebViewConfiguration()
config.userContentController = contentController

webView = WKWebView(frame: CGRectZero, configuration: config)
webView.navigationDelegate = self
view = webView

Ma fonction pour gérer l'événement Javascript qui est envoyé à Swift:

func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage)
    {
        if(message.name == "callbackHandler") {
            print("Launch my Native Camera")
        }
    }

... Et enfin, mon code Javascript (jQuery) lorsqu'un clic se produit sur le bouton de ma caméra (en HTML):

$(document).ready(function() {

    function callNativeApp () {
        try {
            webkit.messageHandlers.callbackHandler.postMessage("camera");
        } catch(err) {
            console.log('The native context does not exist yet');
        }
    }

    $(".menu-camera-icon").click(function() {
        callNativeApp();
    });
});

J'espère que cela aidera quelqu'un d'autre :-)!

32
fraxool

Permet d'abord de créer un fichier js. Dans le js, lorsqu'un élément a été cliqué, vous pouvez renvoyer un message comme ceci:

varmessageToPost = {'ButtonId':'clickMeButton'};
window.webkit.messageHandlers.buttonClicked.postMessage(messageToPost);

Après avoir créé le fichier js et la vue wkweb, vous devez injecter le script:

  // Setup WKUserContentController instance for injecting user script
  var userController:WKUserContentController= WKUserContentController()

  // Get script that's to be injected into the document
  let js:String= GetScriptFromResources()

  // Specify when and where and what user script needs to be injected into the web document
  var userScript:WKUserScript =  WKUserScript(source: js,
                                         injectionTime: WKUserScriptInjectionTime.AtDocumentEnd
                                         forMainFrameOnly: false)

  // Add the user script to the WKUserContentController instance
  userController.addUserScript(userScript)

  // Configure the WKWebViewConfiguration instance with the WKUserContentController
  webCfg.userContentController= userController;

  //set the message handler
  userController.addScriptMessageHandler(self, name: "buttonClicked")  

Enfin, vous devez ajouter une fonction d'écoute:

func userContentController(userContentController: WKUserContentController,
                           didReceiveScriptMessage message: WKScriptMessage) {

        if let messageBody:NSDictionary= message.body as? NSDictionary{
            // Do stuff with messageBody
        }

    }

Code source

11
Alex Pelletier