appeller une fonction objective-C depuis une webview

yodarkyodark Membre
18:28 modifié dans API UIKit #1
Bonjour à  tous,

Est il possible d'appeler une fonction d'objective-C depuis une webview ? genre une url spéciale qui appellerait une fonction dans le code objective C ? Quand je clique sur un lieu au lieu de m'ouvrir une nouvelle page j'aimerais effectuer une action dans mon application !
Est-ce possible ?

Réponses

  • NoNo Membre
    18:28 modifié #2
    Dans l'absolu, c'est (presque) possible en passant pat le pont javascript <-> Objective-C.

    Mais tout dépend d'un certain nombre de paramètres :
    - la webview est elle hébergée par l'application qui possède la fonction à  appeler ?
    - la page html affichée dans la webview est-elle une page que tu possèdes (que tu peux aisément modifié pour coder l'appel à  Obj-C) ?
  • yodarkyodark Membre
    18:28 modifié #3
    Le fichier HTML que je charge est présente sur le web mais gérée par moi ! Donc plein controle sur le code
  • Philippe49Philippe49 Membre
    mars 2009 modifié #4
    cette méthode ne te suffit pas ?

    webView:shouldStartLoadWithRequest:navigationType:
    Sent before a web view begins loading content. This method is optional.

    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType



  • NoNo Membre
    18:28 modifié #5
    dans 1236972062:

    cette méthode ne te suffit pas ?
    webView:shouldStartLoadWithRequest:navigationType:
    Sent before a web view begins loading content. This method is optional.
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType


    Philippe, t'as compris son besoin.
    Il veut, à  partir d'une page html, pouvoir appeler du cocoa en dehors de cette page, sans être obligé de déclencher le chargement d'une autre page.
  • NoNo Membre
    18:28 modifié #6
    Bon, commençons.
    Grâce au pont Obj-C/javascript, ces 2 langages (et leur environnement afférent) peuvent se causer.

    Commençons par la partie Obj-C.
    J'ai un objet (que j'utilise comme contrôleur de la webView).
    L'outlet vers la webView se nome wb :
    <br />@implementation Controleur<br /><br />- (void)awakeFromNib<br />{<br />&nbsp;  // mon objet controleur est delegate de la webview<br />&nbsp;  [wb setFrameLoadDelegate:self];<br /><br />&nbsp;  // charegement d&#39;une page html dans la webview<br />&nbsp;  NSString *p=[[NSBundle mainBundle] pathForResource:@&quot;html&quot; ofType:@&quot;htm&quot;];<br />&nbsp;  [[wb mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:p]]];<br />}<br /><br />- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame<br />{<br />&nbsp;  // lorsque la page html est totalement chargée dans la webview, alors cette méthode delegate est appelée.<br /><br />&nbsp;  // récupération de l&#39;objet javascript &quot;window&quot;<br />&nbsp;  id jswindow=[wb windowScriptObject];<br /><br />&nbsp;  // enregistrement de self (mon objet controleur) dans cet objet javascript &quot;window&quot;<br />&nbsp;  [jswindow setValue:self forKey:@&quot;CocoaObjetControleur&quot;];<br />}<br /><br />+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector<br />{<br />&nbsp;  // autorisation à  javascript d&#39;utiliser l&#39;appel au sélecteur &quot;appelJavascript&quot;<br />&nbsp;  return (aSelector!=@selector(appelJavascript));<br />}<br /><br />- (void)appelJavascript<br />{<br />&nbsp;  // cette méthode est appelée lors du clic sur le lien dans la page html de la webview<br />&nbsp;  NSBeep();<br />}<br /><br />@end<br />
    


    Ensuite, pour la partie html (et plus spécifiquement javascript) :
    <br />&lt;html&gt;<br />&nbsp;  &lt;head&gt;<br />&nbsp; &nbsp; &nbsp; &lt;script type=&quot;text/javascript&quot;&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp;  function AppelCocoa()<br />&nbsp; &nbsp; &nbsp; &nbsp;  {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // lecture de la propriete &quot;CocoaObjetControleur&quot; qui contient la reference a mon objet Controleur<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var objetControleur=window.CocoaObjetControleur;<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // appel de la methode ObjC &quot;appelJavascript&quot; de mon objet Controleur<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (objetControleur) objetControleur.appelJavascript();<br />&nbsp; &nbsp; &nbsp; &nbsp;  }<br />&nbsp; &nbsp; &nbsp; &lt;/script&gt;<br />&nbsp;  &lt;/head&gt;<br />&nbsp;  &lt;body&gt;<br />&nbsp; &nbsp; &nbsp; Je fais un appel a la methode &lt;a href=&quot;javascript:AppelCocoa()&quot;&gt;&lt;b&gt;AppelCocoa&lt;/b&gt;&lt;/a&gt; de mon objet Controleur.<br />&nbsp;  &lt;/body&gt;<br />&lt;/html&gt;<br />
    


    Voilà  !
    A chaque appui sur le lien AppelCocoa dans la page html, la méthode -(void)appelCocoa de l'objet Contrôleur sera exécutée.
  • Philippe49Philippe49 Membre
    mars 2009 modifié #7
    Ben oui c'est ce que j'ai compris. Après le clic sur un lien de la page web, le message que j'ai cité est envoyé au UIWebViewDelegate, et ce delegate fait ce qu'il veut. Si le delegate renvoie NO (c'est le cas de le dire) à  ce message, la page n'est pas chargée, et une action peut être déclenchée par le delegate.
    Enfin c'est comme cela que je comprends la doc.

    [EDIT] sauf si le lien ne déclenche pas de chargement .. c'est possible cela ?
  • Philippe49Philippe49 Membre
    18:28 modifié #8
    dans 1237033652:

    Grâce au pont Obj-C/javascript, ces 2 langages (et leur environnement afférent) peuvent se causer.

    Belle possibilité.
  • yodarkyodark Membre
    18:28 modifié #9
    Oui ce code est très intéressant ! Je vais le garder sous la main !

    Pour l'instant j'ai trouvé une autre méthode

    - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url


    Il me suffit de faire
    monapplication://monparametre
    Pour appeller une fonction depuis du HTML
  • AliGatorAliGator Membre, Modérateur
    18:28 modifié #10
    Oui belle solution No, je ne connaissais pas cette possibilité.

    Pour ma part comme solution je n'aurais proposé que celle évoquée par yodark, à  savoir prévoir un lien de type "toto://machin" dans ma page HTML, et faire gérer par le delegate les clics sur les liens, pour effectuer un traitement particulier si le protocole est "toto://" (et le traitement par défaut sinon)... Mais il est bon de savoir que Objective-C et Javascript peuvent interagir de manière si gracieuse aussi, ça promet des trucs sympas si on a besoin :)
  • maxi_moussemaxi_mousse Membre
    18:28 modifié #11
    Bonjour,

    je remonte ce sujet vieux d'1 an et demi, car je suis en plein dedans mais je n'y arrive pas !

    Je charge dans mon appli une vue HTML (donc dans une webView) avec plusieurs boutons qui représentent chacun l'icône d'une application. Au clic sur une icône, je veux "emmener" l'utilisateur sur la page appleStore correspondant à  l'appli. Si l'on place le lien ("http://itunes.apple.com/fr/app/nom-de-lapp/id123456789";) directement dans la balise <a href=> de la page html, cela renvoie vers l'appStore version web (au sein de la webView). Hors bien entendu ce que je souhaite c'est renvoyer l'utilisateur vers l'application App Store de son iPhone (et sur la page de l'application).

    La solution décrite par No ne semble être dispo que su Mac OS X (ou alors je suis vraiment une buse)

    Quant à  celle évoquée par yodark, je ne comprends pas son utilisation en rapport avec une UIWebView...


    Quelqu'un pour m'aider s'il vous plaà®t ?  :)
  • maxi_moussemaxi_mousse Membre
    18:28 modifié #12
    Bon je me répond à  moi-même.
    En effet la solution utilisant la méthode  - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url  permet de récupérer l'url à  partir du moment ou le protocole est bidon. Ensuite en bidouillant j'arrive à  reconstruire l'URL pour lancer l'application App Store de l'iPhone sur la bonne page de l'appli à  télécharger.

    Bidouille bidouille...
Connectez-vous ou Inscrivez-vous pour répondre.