ReviewOS

craft-native/craft

fix(android): hand a link that arrives before onLink to the first subscriber, as iOS now does

#215
Closed glennmichael123 opened this 9 days ago ·
9 days ago

The iOS fix for #198 establishes a contract that Android does not yet meet:

A link that arrives before anything is subscribed is handed to the first craft.deepLinks.onLink / craft.onDeepLink subscriber, including the link that launched the app, marked initial: true. A page that calls getInitialURL() first, or in the same tick, gets the launch link from there and not a second time from onLink.

Where Android stands

  • Cold start dispatches nothing. MainActivity.onCreate calls handleIncomingDeepLink(intent, dispatch = false). The launch link reaches only getInitialURL(), so a page that subscribes and never asks never learns how it was opened. That is exactly #198's failure on iOS.
  • Warm links race the page. CraftBridge.sendEvent queues events until bridgeReady and flushes them from the injectBridge callback. The flush happens immediately after the script that defines onLink runs, so no page code can have subscribed yet, and a link queued during a reload is dispatched to nobody. This is the same timing iOS had.
  • onLink returns nothing where iOS now returns an unsubscribe function.

What parity looks like

Port the page half of the iOS change. It is plain JavaScript in the injected script:

  • an undelivered list filled by a craftDeepLink listener while nothing is subscribed;
  • _subscribeDeepLinks, which replays that list to the first subscriber on the next turn and returns an unsubscribe;
  • _claimInitialDeepLink, called by getInitialURL, which withdraws the entry marked initial.

On the native side, dispatch the launch link on cold start with initial: true instead of suppressing it.

The E2E harness can cover it the way iOS is covered. adb shell am start -a android.intent.action.VIEW -d <link> cold-starts the app with no confirmation prompt, and the driver page's probeDeepLinks already reports what it received. It needs a host-side read on Android, which logcat already provides.

Found while fixing #198.

Sign in to comment on this issue.