Use Analytics in a WebView on iOS

Use Analytics in a WebView on iOS Calls to log events or set user properties fired from within a WebView must be forwarded to native code before they can be sent to app reports in Google Analytics.

Implement Javascript handler

The first step in using Google Analytics' app reports in a WebView is to create JavaScript functions to forward events and user properties to native code. The following example shows how to do this in a way that is compatible with both Android and iOS native code:
function logEvent(name, params) {
  if (!name) {
    return;
  }

  if (window.AnalyticsWebInterface) {
    // Call Android interface
    window.AnalyticsWebInterface.logEvent(name, JSON.stringify(params));
  } else if (window.webkit
      && window.webkit.messageHandlers
      && window.webkit.messageHandlers.firebase) {
    // Call iOS interface
    var message = {
      command: 'logEvent',
      name: name,
      parameters: params
    };
    window.webkit.messageHandlers.firebase.postMessage(message);
  } else {
    // No Android or iOS interface found
    console.log("No native APIs found.");
  }
}

function setUserProperty(name, value) {
  if (!name || !value) {
    return;
  }

  if (window.AnalyticsWebInterface) {
    // Call Android interface
    window.AnalyticsWebInterface.setUserProperty(name, value);
  } else if (window.webkit
      && window.webkit.messageHandlers
      && window.webkit.messageHandlers.firebase) {
    // Call iOS interface
    var message = {
      command: 'setUserProperty',
      name: name,
      value: value
   };
    window.webkit.messageHandlers.firebase.postMessage(message);
  } else {
    // No Android or iOS interface found
    console.log("No native APIs found.");
  }
}

Implement native interface

To invoke native iOS code from JavaScript, create a message handler class conforming to the WKScriptMessageHandler protocol. You can make Mobile app reporting in Google Analytics calls inside the userContentController:didReceiveScriptMessage: callback:

Objective-C

- (void)userContentController:(WKUserContentController *)userContentController
      didReceiveScriptMessage:(WKScriptMessage *)message {
  if ([message.body[@"command"] isEqual:@"setUserProperty"]) {
    [FIRAnalytics setUserPropertyString:message.body[@"value"] forName:message.body[@"name"]];
  } else if ([message.body[@"command"] isEqual: @"logEvent"]) {
    [FIRAnalytics logEventWithName:message.body[@"name"] parameters:message.body[@"parameters"]];
  }
}

Swift

func userContentController(_ userContentController: WKUserContentController,
                           didReceive message: WKScriptMessage) {
  guard let body = message.body as? [String: Any] else { return }
  guard let command = body["command"] as? String else { return }
  guard let name = body["name"] as? String else { return }

  if command == "setUserProperty" {
    guard let value = body["value"] as? String else { return }
    FIRAnalytics.setUserPropertyString(value, forName: name)
  } else if command == "logEvent" {
    guard let params = body["parameters"] as? [String: NSObject] else { return }
    FIRAnalytics.logEvent(withName: name, parameters: params)
  }
}

Finally, add the message handler to the webview's user content controller:

Objective-C

 [self.webView.configuration.userContentController addScriptMessageHandler:self
                                                                     name:@"firebase"];

Swift

self.webView.configuration.userContentController.add(self, name: "firebase")

Next steps

For a fully functional implementation of Google Analytics’ app reports in a WebView, see the analytics-webview sample.