Skip to content

Drivers

View raw .md
On this page

Introduction#

A driver is the platform abstraction layer that delivers raw URI events to the DeeplinkManager. Drivers translate platform-specific deep link mechanisms — Universal Links on iOS and macOS, App Links on Android — into a uniform Stream<Uri> that the rest of the plugin consumes.

The plugin ships with AppLinksDriver, which covers all supported native platforms via the app_links package. If you need to source URIs from a custom mechanism (push notifications, in-app QR scanning, test harnesses), you can implement the DeeplinkDriver contract and register it in place of the default driver.

The DeeplinkDriver Contract#

All drivers extend the abstract class DeeplinkDriver, defined in lib/src/drivers/deeplink_driver.dart:

dart
abstract class DeeplinkDriver {
  String get name;
  bool get isSupported;
  Future<void> initialize(Map<String, dynamic> config);
  Future<Uri?> getInitialLink();
  Stream<Uri> get onLink;
  void dispose();
}

name#

dart
String get name;

A stable identifier for the driver. Used for logging and diagnostics. Return a lowercase, hyphenated string, for example 'app_links' or 'my-custom-driver'.

isSupported#

dart
bool get isSupported;

Returns true when the driver can operate on the current platform. The DeeplinkServiceProvider skips driver initialization and stream setup when this returns false, so your check must be synchronous. Use Platform.isAndroid, Platform.isIOS, etc., guarded by a try/catch for environments where dart:io is unavailable, and check kIsWeb before any Platform access.

dart
Stream<Uri> get onLink;

A broadcast stream that emits every URI received while the application is running. The DeeplinkServiceProvider subscribes to this stream during the boot phase and forwards each emission to DeeplinkManager.handleUri(). Return Stream.empty() on unsupported platforms.

initialize#

dart
Future<void> initialize(Map<String, dynamic> config);

Called once by the service provider before any link is consumed. Use this to create platform clients, open channels, or apply configuration values sourced from the deeplink config map. Keep this method idempotent — the provider does not guard against duplicate calls.

dart
Future<Uri?> getInitialLink();

Returns the URI that cold-started the application, or null if the app was launched normally. This is called once after initialize() completes. Swallow exceptions internally and return null on failure — callers do not expect this method to throw.

dispose#

dart
void dispose();

Releases any resources held by the driver (stream subscriptions, platform channels, timers). Called by the service provider during application teardown. If your driver holds no resources, the body can be left empty.

AppLinksDriver#

AppLinksDriver is the default driver. It delegates to the app_links package, which handles Universal Links (iOS / macOS) and App Links (Android) without any native Dart code in this plugin.

dart
import 'package:magic_deeplink/magic_deeplink.dart';

// AppLinksDriver is registered automatically by DeeplinkServiceProvider.
// You only need to interact with it directly when writing custom boot logic.
final driver = AppLinksDriver();
await driver.initialize({});

final initial = await driver.getInitialLink(); // Uri? from cold start
driver.onLink.listen((uri) {
  // Handle foreground links
});

Platform Support#

Platform Supported
Android Yes — App Links (HTTPS intent filter)
iOS Yes — Universal Links (apple-app-site-association)
macOS Yes — Universal Links
Web No
Windows No
Linux No

AppLinksDriver.isSupported returns false for web (kIsWeb) and for any platform not in the set {Android, iOS, macOS}. The service provider will not attempt initialization or stream subscription when isSupported is false.

Custom Drivers#

Implementing the Contract#

Extend DeeplinkDriver and implement every member of the contract. The example below shows a driver that emits URIs received from a push notification payload:

dart
import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:magic_deeplink/magic_deeplink.dart';

class PushNotificationDriver extends DeeplinkDriver {
  final StreamController<Uri> _controller =
      StreamController<Uri>.broadcast();

  @override
  String get name => 'push-notification';

  @override
  bool get isSupported {
    if (kIsWeb) return false;
    try {
      return Platform.isAndroid || Platform.isIOS;
    } catch (_) {
      return false;
    }
  }

  @override
  Future<void> initialize(Map<String, dynamic> config) async {
    // Subscribe to your notification service here and pipe URIs
    // into _controller whenever a deep link payload arrives.
  }

  @override
  Future<Uri?> getInitialLink() async {
    // Return a URI if the app was cold-started from a notification,
    // or null if no link was attached to the launch payload.
    return null;
  }

  @override
  Stream<Uri> get onLink => _controller.stream;

  /// Call this from your notification handler to emit a URI.
  void emit(Uri uri) => _controller.add(uri);

  @override
  void dispose() {
    _controller.close();
  }
}

Registering a Custom Driver#

Pass your driver to DeeplinkManager.setDriver() before the service provider's boot() phase completes. The canonical place is inside a custom service provider's boot() method, or directly in your AppServiceProvider:

dart
import 'package:magic/magic.dart';
import 'package:magic_deeplink/magic_deeplink.dart';

class AppServiceProvider extends ServiceProvider {
  @override
  void register() {}

  @override
  Future<void> boot() async {
    final manager = app.make<DeeplinkManager>('deeplinks');
    manager.setDriver(PushNotificationDriver());
  }
}

You can also set the driver imperatively at any point before the first link is consumed:

dart
DeeplinkManager().setDriver(PushNotificationDriver());
  • Handlers — Chain-of-responsibility URI handling after the driver emits a link
  • Configuration — config/deeplink.dart driver selection and options
  • Service Provider — Boot lifecycle, driver initialization, and stream wiring
esc

Search index did not load.

No match for "".

Try a class like rounded-lg or a widget like WButton.