Xam.Plugin.Webview icon indicating copy to clipboard operation
Xam.Plugin.Webview copied to clipboard

Callback return

Open LeoDecking opened this issue 6 years ago • 4 comments

Could you implement the possibility to return something from c# to javascript?

Example:

C#:

WebView.AddLocalCallback("square", (str) => 
{
    int i = int.Parse(str);
    return i*i;
});

JavaScript:

var s = square(5);

LeoDecking avatar Apr 12 '18 20:04 LeoDecking

I'm also interested in this as it's the way the XLabs one does it.

How is the webapp to request data from the Native CSharp code?

Jacko1394 avatar Sep 10 '18 09:09 Jacko1394

Did you find any solution yet? @LeoDecking , @Jacko1394

ravinderjangra avatar Jun 10 '19 08:06 ravinderjangra

Without making changes to Ryan's source code, this is how I achieved a Callback return value from C# to Javascript:

C#


public class Bridge {
  public const string Wait = "WAIT";
  public static EventHandler<string> OnPromiseCompleted;

  public static async Task<string> TheNativeFunction(string json) {
    // json param is from javascript code
    Trace.WriteLine(json);
    // do c sharp stuff here...
    var result = "{\"success\": true}" // json value to return to javascript
    return result;
  }
}

public class ViewModel {

  public FormsWebView WebView { get; set; }

  public void Init() {
    // This is used to complete bridge functions that involve some time to complete:
    Bridge.OnPromiseCompleted += CompletePromise;

    FormsWebView.AddGlobalCallback("xamarinCode", async (string arg) => {

      string result;

      try {
        IsBusy = true;
        result = await Bridge.TheNativeFunction(arg);
      } catch (Exception ex) {
        result = ex.Message;
      }

      if (result == Bridge.Wait) {
        Trace.WriteLine("WAITING....");
        return;
      }
      CompletePromise(null, result);
    });

  }

  private async void CompletePromise(object sender, string result) {
    try {
      await WebView.InjectJavascriptAsync($"nativeReturn({result});");
    } catch (Exception ex) {
      Trace.WriteLine(ex.Message);
    }
    IsBusy = false;
  }
}

Javascript

var nativeReturn;

// Bridge function:
send: function(data) {
  return new Promise(function(resolve, reject) {
    try {
      nativeReturn = resolve; // sets reference for native code to return to
      let encoded = encodeURIComponent(JSON.stringify(data)); // this is the data to send to c#
      xamarinCode(encoded); // sends command to native c#
    } catch (e) {
      console.log(e);
      reject(e);
    }
  });
}

// USAGE:
send('command json goes here').then(function(result) {
  console.log(result); // promise completes
});

Jacko1394 avatar Jun 12 '19 07:06 Jacko1394

Thanks, @Jacko1394. I'll try using this and it'll be great if you can share other references as well (if you have something in mind).

ravinderjangra avatar Jun 12 '19 08:06 ravinderjangra