Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: WebViewSyncPlugin #253

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

chore: WebViewSyncPlugin #253

wants to merge 1 commit into from

Conversation

crleona
Copy link
Collaborator

@crleona crleona commented Jan 9, 2025

Summary

Adds a prototype plugin to sync user, device, and session ids to all webviews in an app. This may be an easier approach for hybrid apps to sync Amplitude properties to their webviews, vs manually injecting device and session ids.

Screenshot 2025-01-09 at 9 50 39 AM

(The extraneous session start events are generated from the JS library auto tracking - we should add a method to set the session id without generating these).

Customers that are newly adopting this sync strategy may want to change the JS plugin to compare and report mismatches in device / user / session id vs setting them directly.

Current rough JS plugin:

amplitude.add((function () {
    if (!window.amp_webview_config) {
        return {};
    }

    var amplitude = null;
    var apiKey = null;

    const updateConfig = function(config) {
        if (!amplitude || !config) {
            return;
        }

        if (apiKey != config["api_key"]) {
            return;
        }

        const userId = config["user_id"];
        if (amplitude.getUserId() != userId) {
            amplitude.setUserId(userId);
        }

        const deviceId = config["device_id"];
        if (amplitude.getDeviceId() != deviceId) {
            amplitude.setDeviceId(deviceId);
        }

        const sessionId = config["session_id"];
        if (amplitude.getSessionId() != sessionId) {
            amplitude.setSessionId(sessionId);
        }
    }

    function setup(config, amp) {
        amplitude = amp;
        apiKey = config.apiKey;
        window.amp_webview_config.subscribe(updateConfig);
        const webviewConfig = window.amp_webview_config.getConfig();
        if (webviewConfig) {
            updateConfig(webviewConfig);
        }
    }

    function teardown() {
        window.amp_webview_config.unsubscribe(updateConfig);
    }
  
    return {
      setup: setup,
      teardown: teardown,
    };
  })());

How it works:

  • We swizzle WKWebView init to inject our loader script into each webview as it's created. The loader script has to be static as we can't change or remove it, so we need to inject the actual data elsewhere.
  • Each time the script loads (ie, when a page changes) the script sends a signal to re-inject the current amplitude data. This also is re-injected on config change.
  • Pre-injection guarantees availability on page load. Clients will be notified of any config changes when registered.
  • If the injected script is not detected or the api key is mismatched (we may load a third party website), config changes are ignored.

Checklist

  • Does your PR title have the correct title format?
  • Does your PR have a breaking change?: no

@crleona crleona requested a review from a team January 9, 2025 18:03
@Mercy811
Copy link
Collaborator

Mercy811 commented Jan 9, 2025

Thanks @crleona for better supporting web views.

(The extraneous session start events are generated from the JS library auto tracking - we should add a method to set the session id without generating these).

I don't see why customers should turn session tracking on in webviews as it's part of the mobile app. The session should start when they open the mobile app instead of open webviews. Customers should turn browser SDK session tracking off.

@crleona
Copy link
Collaborator Author

crleona commented Jan 9, 2025

I don't see why customers should turn session tracking on in webviews as it's part of the mobile app. The session should start when they open the mobile app instead of open webviews. Customers should turn browser SDK session tracking off.

@Mercy811 -
I agree they should not have session tracking on both, but for pages that may be used in both webview and browser contexts we'd either need clients to flag that and disable session tracking themselves or we just bypass it as described here. The latter seems a bit easier to me, but it does require changes to the browser API. (iirc we had a direct parallel in the legacy SDKs, though). Are there any cases that would break with this approach or is there any other context I'm missing? We should be able to test this without it but longer term (and especially if adoption picks up) it seems like an easy win.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants