Unity Hybrid App Integration Guide

Unity Hybrid App Integration


There are several plugins that can be used for webviews in Unity. Since each plugin have different ways to integrate with hybrid apps, Airbridge provides methods to utilize the plugin through a JavaScript interface.



Interface


AirbridgeWebInterface webInterface;
webInterface = AirbridgeUnity.CreateWebInterface(
	"YOUR_WEB_TOKEN",     // web token
	(msg) => $@"..."      // post command function
);

📘

YOUR_WEB_TOKEN can be found at the Airbridge dashboard → Settings → Tokens → Web SDK.

public interface AirbridgeWebInterface
{
	string Script { get; }

	void Handle(string message);
}



Guide


Below are integration guides for three commonly used plugins.

  • gree/unity-webview
  • UniWebView
  • GPM (Game Package Manger)

WebViewObject webViewObject;
AirbridgeWebInterface webInterface;

public void Display()
{
	webInterface = AirbridgeUnity.CreateWebInterface(
		"YOUR_WEB_TOKEN",
		// Create a JavaScript that will forward messages to Unity through the WebView using postCommandFunction.
		(msg) => $@"
if (window && window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.unityControl) {{
	window.webkit.messageHandlers.unityControl.postMessage({msg});
}} else {{
	var iframe = document.createElement('IFRAME');
	iframe.setAttribute('src', 'unity:' + {msg});
	document.documentElement.appendChild(iframe);
	iframe.parentNode.removeChild(iframe);
	iframe = null;
}}");
  
  
	webViewObject.Init(
		cb: (msg) =>
		{
			// do something
    
    	// Allow the Airbridge Unity SDK to process the forwarded messages from the WebView. 
			webInterface.Handle(msg);
		},
		err: (msg) => { /* do something */ },
		httpErr: (msg) => { /* do something */ },
		started: (msg) =>
		{
			// do something
    
    	// JavaScript must be injected before the website loads.
#if UNITY_IOS
			webViewObject.EvaluateJS(webInterface.Script);
#endif
		},
		hooked: (msg) => { /* do something */ },
		ld: (msg) =>
		{
			// do something
    
			webViewObject.EvaluateJS(webInterface.Script);
		},
		...
	);
  ...
}

<script>
(function(a_,i_,r_,_b,_r,_i,_d,_g,_e){if(!a_[_b]){var d={queue:[],get isSDKEnabled(){return!1}};_r.concat(_i).forEach(function(a){var h=a.split("."),n=h.pop();h.reduce(function(k,l){return k[l]=k[l]||{}},d)[n]=function(){d.queue.push([a,arguments])}});a_[_b]=d;a_=i_.getElementsByTagName(r_)[0];i_=i_.createElement(r_);i_.onerror=function(){d.queue.filter(function(a){return 0<=_i.indexOf(a[0])}).forEach(function(a){a=a[1];a=a[a.length-1];"function"===typeof a&&a("error occur when load airbridge")})};i_.async=1;i_.src="//static.airbridge.io/sdk/latest/airbridge.min.js";a_.parentNode.insertBefore(i_,a_)}})(window,document,"script","airbridge","init startTracking fetchResource setBanner setDownload setDownloads openDeeplink setDeeplinks sendWeb setUserAgent setUserAlias addUserAlias setMobileAppData setUserId setUserEmail setUserPhone setUserAttributes clearUser setDeviceAlias removeDeviceAlias clearDeviceAlias setDeviceIFV setDeviceIFA setDeviceGAID events.send events.signIn events.signUp events.signOut events.purchased events.addedToCart events.productDetailsViewEvent events.homeViewEvent events.productListViewEvent events.searchResultViewEvent".split(" "),["events.wait","createTouchpoint"]); 

function initAirbridge() {
	if (typeof(AirbridgeNative) !== "undefined") {
		airbridge.init({
			app: 'App Name',
			webToken: 'Web SDK Token'
		});
	}
}
initAirbridge();
</script>

🚧

In the case of iOS, the JavaScript could be injected after the initialization of the web SDK. Change your web page code to the above if this is the case.

UniWebView webView;
AirbridgeWebInterface webInterface;

// Create a JavaScript that will initialize the Airbridge SDK on the web page that will load.
string InitAirbridgeScript
{
	get
	{
		return "initAirbridge();";
	}
}

public void Display()
{
	webInterface = AirbridgeUnity.CreateWebInterface(
		"YOUR_WEB_TOKEN",
    // Create a JavaScript that will forward messages to Unity through the WebView using postCommandFunction.
		(msg) => $@"window.location.href = 'uniwebview://airbridge?msg=' + {msg}"
	);

	webView.OnMessageReceived += (view, message) =>
	{
    // Allow the Airbridge Unity SDK to process the forwarded messages from the WebView. 
		if (message.Path.Equals("airbridge")) 
		{
			string msg = message.Args["msg"];
			webInterface.Handle(msg);
		}
	};

	webView.OnPageFinished += (view, statusCode, url) =>
	{
		InjectAirbridgeJavascript();
	};

	...
	webView.Show();
}

private void InjectAirbridgeJavascript()
{
	webView.EvaluateJavaScript(CreateSupportedJavascript(webInterface.Script), (payload) => 
	{
		if (payload.resultCode.Equals("0")) 
		{
			Debug.Log("Airbridge javascript injection succeeded");
#if UNITY_IOS
			webView.EvaluateJavaScript(CreateSupportedJavascript(InitAirbridgeScript), (payload) =>
			{
				if (payload.resultCode.Equals("0")) 

<script>
(function(a_,i_,r_,_b,_r,_i,_d,_g,_e){if(!a_[_b]){var d={queue:[],get isSDKEnabled(){return!1}};_r.concat(_i).forEach(function(a){var h=a.split("."),n=h.pop();h.reduce(function(k,l){return k[l]=k[l]||{}},d)[n]=function(){d.queue.push([a,arguments])}});a_[_b]=d;a_=i_.getElementsByTagName(r_)[0];i_=i_.createElement(r_);i_.onerror=function(){d.queue.filter(function(a){return 0<=_i.indexOf(a[0])}).forEach(function(a){a=a[1];a=a[a.length-1];"function"===typeof a&&a("error occur when load airbridge")})};i_.async=1;i_.src="//static.airbridge.io/sdk/latest/airbridge.min.js";a_.parentNode.insertBefore(i_,a_)}})(window,document,"script","airbridge","init startTracking fetchResource setBanner setDownload setDownloads openDeeplink setDeeplinks sendWeb setUserAgent setUserAlias addUserAlias setMobileAppData setUserId setUserEmail setUserPhone setUserAttributes clearUser setDeviceAlias removeDeviceAlias clearDeviceAlias setDeviceIFV setDeviceIFA setDeviceGAID events.send events.signIn events.signUp events.signOut events.purchased events.addedToCart events.productDetailsViewEvent events.homeViewEvent events.productListViewEvent events.searchResultViewEvent".split(" "),["events.wait","createTouchpoint"]); 

function initAirbridge() {
	if (typeof(AirbridgeNative) !== "undefined") {
		airbridge.init({
			app: 'App Name',
			webToken: 'Web SDK Token'
		});
	}
}
initAirbridge();
</script>

🚧

In the case of iOS, the JavaScript could be injected after the initialization of the web SDK. Change your web page code to the above if this is the case.

AirbridgeWebInterface webInterface;

// Create a JavaScript that will initialize the Airbridge SDK on the web page that will load.
string InitAirbridgeScript
{
    get
    {
        return "initAirbridge();";
    }
}

public void Display()
{
    webInterface = AirbridgeUnity.CreateWebInterface(
        "YOUR_WEB_TOKEN",
    // Create a JavaScript that will forward messages to Unity through the WebView using postCommandFunction.
        (msg) => $@"window.location.href = 'airbridge://?msg=' + {msg}"
    );

    GpmWebView.ShowUrl(
        "WEB_URL",
        new GpmWebViewRequest.Configuration() { ... },
        OnCallback,
        new List<string>()
        {
            "airbridge"    // PUT AIRBRIDGE SCHEME HERE
        }
    );
}


private void OnCallback(
    GpmWebViewCallback.CallbackType callbackType,
    string data,
    GpmWebViewError error
) 
{
    switch (callbackType)
    {
        case GpmWebViewCallback.CallbackType.PageLoad:
            if (string.IsNullOrEmpty(data) == false)
            {
                // do something
                
                GpmWebView.ExecuteJavaScript(webInterface.Script);
#if UNITY_IOS
                GpmWebView.ExecuteJavaScript(InitAirbridgeScript);
#endif
            }
            break;
        case GpmWebViewCallback.CallbackType.Scheme:
            if (error == null)
            {
                Uri uri = new Uri(data);
   						  // Allow the Airbridge Unity SDK to process the forwarded messages from the WebView. 
                if (uri.Scheme.Equals("airbridge"))
                {
                    try
                    {
                        string message = HttpUtility.ParseQueryString(uri.Query)["msg"];
                        string decodedMessage = HttpUtility.UrlDecode(message);
                        webInterface.Handle(decodedMessage);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Fail to receive message. Error: {0}", e.Message);
                    }
                }
            }
            else
            {
                Debug.Log(string.Format("Fail to custom scheme. Error: {0}", error));
            }
            break;
        ...
    }
}