The Kochava SDK APIs can be used from within a WebView for scenarios where you have a native app with an embedded WebView. The examples provided in this topic shows the most common usage but additional APIs can be added by following the same pattern.
Calling the SDK from within your WebView requires the following steps.
- Include the JavaScript snippet within your WebView.
- Add a handler that intercepts the API calls in your native code.
- Call the JavaScript APIs in your WebView.
Include the JavaScript Snippet
Place the following JavaScript snippet within your website. This must be available in a way where it can be called from your own JavaScript.
Example — JavaScript Snippet:
function registerIdentityLink(name, value) {
postUrl('kochavameasurement://registerIdentityLink?name='+encodeURIComponent(name)+'&value='+encodeURIComponent(value));
}
function sendEvent(eventName, eventData) {
postUrl('kochavameasurement://sendEvent?eventName='+encodeURIComponent(eventName)+'&eventData='+encodeURIComponent(JSON.stringify(eventData)));
}
function postUrl(url) {
var i = document.createElement('iframe');
i.style.display = 'none';
i.onload = function() { i.parentNode.removeChild(i); };
i.src = url;
document.body.appendChild(i);
}
Add Native Handler
Add the native code which interacts with the WebView. This code will handle the API calls from the JavaScript snippet in the WebView and route them to the appropriate native API.
Example — Native Handler
public final class SampleUtilizationFromAWebView extends WebViewClient { /** * Override the URL handler and see if we are consuming the url load. */ @Override public boolean shouldOverrideUrlLoading(@NonNull final WebView webView, @NonNull final String urlString) { if (kochavaMeasurementUrlHandler(urlString)) { return true; } // Handle others as needed // ... return false; } /** * Checks if the given url is a Kochava command and performs its action as required. * <p> * @return true if it is Kochava Measurement Command and false for all others. */ private boolean kochavaMeasurementUrlHandler(@NonNull final String urlString) { final String kochavaPrefix = "kochavameasurement://"; if(!urlString.startsWith(kochavaPrefix)) { // Not a Kochava Measurement Command return false; } // Handle all Kochava Measurement Commands if(urlString.startsWith(kochavaPrefix + "registerIdentityLink")) { final Uri url = Uri.parse(urlString); final String name = url.getQueryParameter("name"); final String value = url.getQueryParameter("value"); Tracker.getInstance().registerIdentityLink(name != null ? name : "", value); } else if (urlString.startsWith(kochavaPrefix + "sendEvent")) { final Uri url = Uri.parse(urlString); final String eventName = url.getQueryParameter("eventName"); final String eventData = url.getQueryParameter("eventData"); JSONObject eventDataParsed; try { eventDataParsed = new JSONObject(eventData); } catch (JSONException e) { eventDataParsed = new JSONObject(); // Handle exception as needed } Event.buildWithEventName(eventName != null ? eventName : "") .mergeCustomDictionary(eventDataParsed) .send(); } else { // Unrecognized Kochava Measurement Command } // Processed Kochava Measurement Command return true; } }
class MyViewController: UIViewController, WKNavigationDelegate { // MARK: - WKNavigationDelegate func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { guard !self.webView( webView, kochavaDidDecidePolicyFor: navigationAction, decisionHandler: decisionHandler ) else { return } decisionHandler(.allow) } func webView(_ webView: WKWebView, kochavaDidDecidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) -> Bool { // VALIDATE ELSE RETURN guard let url = navigationAction.request.url, let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) else { return false } let urlString = url.absoluteString guard urlString.hasPrefix("kochavameasurement://") else { return false } // MAIN let queryItems = urlComponents.queryItems switch urlString { case _ where urlString.hasPrefix("kochavameasurement://sendEvent"): let event = Event(type: .custom) event.customEventName = KochavaMeasurement.Event.EventName.from(queryItems?.first {$0.name == "eventName"}?.value) event.infoDictionary = Dictionary<AnyHashable, Any>.from(queryItems?.first {$0.name == "eventData"}?.value) event.send() case _ where urlString.hasPrefix("kochavameasurement://registerIdentityLink"): IdentityLink.register( name: IdentityLink.Name.from(queryItems?.first {$0.name == "name"}?.value) ?? "", identifier: IdentityLink.Identifier.from(queryItems?.first {$0.name == "value"}?.value) ) default: break // Unknown Kochava command. Handle silently. } decisionHandler(.cancel) return true } }
Call the JavaScript APIs
From your code in the WebView you can now call the SDK’s JavaScript API as defined in the snippet included above.
Example — Basic Usage:
<button style="width: 100%; font-size: 16pt" onclick='
registerIdentityLink("user_id", "abcdefg");
'>Register Identity Link</button>
<p/>
<button style="width: 100%; font-size: 16pt" onclick='
var eventData = {};
eventData["user_id"] = "abcdefg";
eventData["user_name"] = "user_123";
sendEvent("Registration Complete", eventData);
'>Send Event</button>