handleDeepLink method

Future<Map<String, Object?>> handleDeepLink(
  1. Uri uri, {
  2. bool dry = false,
  3. bool runCallback = true,
})

Sends uri through the deep link chain, as if the platform had delivered it, and reports what each step did.

Runs onIncomingLinkAction unless runCallback is false, then routes unless dry, which resolves the URI and changes nothing. Returns the same shape either way, so a dry run and a real one read alike.

Deep links don't have to be switched on: a link resolves against the registered routes regardless, which is what makes it worth testing before wiring the platform up.

Implementation

Future<Map<String, Object?>> handleDeepLink(
  Uri uri, {
  bool dry = false,
  bool runCallback = true,
}) async {
  final NyDeepLinkHandler handler =
      _deepLinkHandler ??
      NyDeepLinkHandler(fallbackRoute: _deepLinkFallbackRoute);
  final DeepLinkTarget resolved = handler.resolve(uri);
  final Map<String, Object?> result = {
    'uri': uri.toString(),
    ...resolved.toJson(),
    'dry': dry,
  };

  if (!runCallback) {
    result['callback'] = 'skipped';
  } else if (onIncomingLinkAction == null) {
    result['callback'] = 'none';
  } else {
    final bool shouldRoute = await onIncomingLinkAction!(uri);
    result['callback'] = shouldRoute ? 'continued' : 'stopped';
    if (!shouldRoute) {
      return result..['routed'] = false;
    }
  }

  if (dry) return result..['routed'] = false;

  // routeTo only completes when the pushed route pops, so it is started
  // and not awaited - the same as NyDeepLinkHandler's own dispatch. The
  // caller decides how long to wait for the navigator to settle.
  result['from'] = Nylo.getCurrentRouteName();
  unawaited(
    routeTo(resolved.target, queryParameters: resolved.queryParameters),
  );
  return result..['routed'] = true;
}