Jump to content
Sign in to follow this  
DonSa

Callback a javasctipt on Webbrowser in Firemokey for both Android and iOS

Recommended Posts

I have a sample code to callback from TWebbrowser, for example: get a selected text on webbrowser...
It is OK in Firemonkey Android. But in Firemonkey iOS, there is error at line: "FJavaScriptValueCallback := TJavaScriptValueCallback.Create;" with message: Incompatibe types TJavaScriptValueCallback  and TWKScriptMessage. I don't know in iOS, what object evaqulient with class that i ahve decalred in Android: TJavaScriptValueCallback = class(TJavalocal, JValueCallBack)

 

Please give idea! Thanks!

This is my code:

unit uMain;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects,
  FMX.TabControl, FMX.WebBrowser, System.IOUtils, FMX.Controls.Presentation,
  FMX.Edit, FMX.Memo.Types, FMX.ScrollBox, FMX.Memo, FMX.StdCtrls, System.JSON,
  System.Actions, FMX.ActnList, FMX.ListView.Types, FMX.ListView.Appearances,
  FMX.ListView.Adapters.Base, FMX.ListView, System.StrUtils, FMX.ListBox,
  FMX.Layouts, FMX.MultiView, System.RegularExpressions, FMX.Platform,
  FMX.Clipboard
  {$IFDEF ANDROID}
  , Androidapi.JNIBridge, Androidapi.JNI.WebKit, Androidapi.JNI.JavaTypes,
  FMX.StdActns, FMX.MediaLibrary.Actions, System.ImageList, FMX.ImgList
  {$ENDIF}
  {$IFDEF IOS}
  , iOSapi.WebKit, iOSapi.Foundation, Macapi.Helpers, iOSapi.Helpers, iOSapi.UIKit,
  System.ImageList, FMX.ImgList, FMX.StdActns, FMX.MediaLibrary.Actions
  {$ENDIF};
 
type

  TJavaScriptResultEvent = procedure(Sender: TObject; const JavaScriptResult: string) of object;
  {$IFDEF ANDROID}
  TJavaScriptValueCallback = class(TJavalocal, JValueCallBack)
  {$ENDIF}
  {$IFDEF IOS}
  TJavaScriptValueCallback = class(TWKScriptMessage)
  {$ENDIF}
  private
    FOnResult: TJavaScriptResultEvent;

  public
    {$IFDEF ANDROID}
    { JValueCallback }
    procedure onReceiveValue(value:JObject); cdecl;
    {$ENDIF}
    {$IFDEF IOS}
    { TWKScriptMessage }
    procedure onReceiveValue(controller: WKUserContentController; message: WKScriptMessage);
    {$ENDIF}

    property OnResult: TJavaScriptResultEvent read FOnResult write FOnResult;

  end;

  TfrmMain = class(TForm)
 
  private
    { Private declarations }

    FJavaScriptValueCallback: TJavaScriptValueCallback;
  public
    { Public declarations }

    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.fmx}

{ TJavaScriptValueCallback }
{$IFDEF ANDROID}
procedure TJavaScriptValueCallback.onReceiveValue(value: JObject);
begin
  if Assigned(FOnResult) then
    FOnResult(Self, JStringToString(TJString.Wrap(value)).DeQuotedString('"'));
end;
{$ENDIF}

{$IFDEF IOS}
procedure TJavaScriptValueCallback.onReceiveValue(controller: WKUserContentController; message: WKScriptMessage);
var MessageText: string;
begin
  if Assigned(FOnResult) then
  begin
      if Assigned(message.body) then
      begin
        MessageText := NSStrToStr(TNSString.Wrap(message.body));
        FOnResult(Self, MessageText);
      end;
  end;
end;

constructor TfrmMain.Create(AOwner: TComponent);
begin
  inherited;
  FJavaScriptValueCallback := TJavaScriptValueCallback.Create;

end;

destructor TfrmMain.Destroy;
begin
  FJavaScriptValueCallback.Free;
  inherited;
end;
{$ENDIF}

end.

 
 

Share this post


Link to post

TL;DR;

 

There was a scripting solution from freeonterninate: ScriptGate

https://bitbucket.org/freeonterminate/scriptgate/src/master/

 

I don't use this currently and this is quite old, so I would bet it's not working anymore with current TWebBrowser.

Maybe it will be helpful anyway, and you might get this working (again ?).

Would be great to get some feedback on the status of this project.

Edited by Rollo62
  • Like 1

Share this post


Link to post
10 hours ago, DonSa said:

But in Firemonkey iOS, there is error at line: "FJavaScriptValueCallback := TJavaScriptValueCallback.Create;" with message: Incompatibe types TJavaScriptValueCallback  and TWKScriptMessage

As per the documentation, you do not create an instance of WKScriptMessage, and in any event, you cannot descend from TWKScriptMessage anyway. Also as per the documentation it is used when you implement custom Javascript message handlers. 

 

What you could do is use the evaluateJavaScript method of WKWebView and pass to it a completion handler, which could be declared on your main form like this:

procedure JavaScriptCompletionHandler(obj: Pointer; error: NSError);

..and implement it like this:

procedure TfrmMain.JavaScriptCompletionHandler(obj: Pointer; error: NSError);
var
  LJavaScriptResult: string;
  LCode: Integer;
begin
  if obj <> nil then
    LJavaScriptResult := NSStrToStr(TNSString.Wrap(obj))
  else
    LJavaScriptResult := 'null';
  if error = nil then
    LCode := 0
  else
    LCode := error.code;
  // Do something with LJavaScriptResult and LCode, here
end;

Call evaluateJavascript like this:

LWebView.evaluateJavaScript(StrToNSStr(AJavaScript), JavaScriptCompletionHandler)

Where LWebView is a reference to the WKWebView in the iOS implementation of TWebBrowser

  • Like 1

Share this post


Link to post

thank Dave Nottage and Rollo62. It was ok for both iOS and Android

  • Like 2

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×