init static method

Future<Nylo> init({
  1. required EnvGetter env,
  2. BootConfig? setup,
  3. Map<AppLifecycleState, dynamic Function()>? appLifecycle,
  4. List<FutureOr<Runnable>>? services,
})

Initialize Nylo

env - The environment getter function from your generated env.g.dart file. Run metro make:key then metro make:env to generate this file. Example: env: Env.get

services - List of services to initialize after setup completes. Services are initialized in order and must extend Runnable or NyService. Supports both sync and async service factories (e.g., Future<Runnable>).

Example:

await Nylo.init(
  env: Env.get,
  setup: Boot.nylo,
  services: [
    // Async factory pattern - returns Future<Runnable>
    FirebaseKit.init(
      options: DefaultFirebaseOptions.currentPlatform,
      services: [
        FirebaseKitMessaging(sendTokenOnBoot: true),
        FirebaseKitAnalytics(enableAutoTracking: true),
      ],
    ),
    // Direct instantiation
    MyCustomService(),
  ],
);

// Later in your app, retrieve services:
final firebase = service<FirebaseKit>();
final messaging = firebase.getService<FirebaseKitMessaging>();

Services go through three lifecycle phases:

  1. onInit() - Called for each service in order
  2. onReady() - Called after all services are initialized
  3. onAppReady() - Called when the app is fully ready

Implementation

static Future<Nylo> init({
  required EnvGetter env,
  BootConfig? setup,
  Map<AppLifecycleState, Function()>? appLifecycle,
  List<FutureOr<Runnable>>? services,
}) async {
  // Register environment configuration first
  NyEnvRegistry.register(getter: env);

  Intl.defaultLocale = getEnv('DEFAULT_LOCALE', defaultValue: 'en');

  try {
    await _configureLocalTimeZone();
  } catch (e) {
    // Timezone configuration failed, continue without it
  }

  Nylo nyloApp = Nylo();

  if (setup != null) {
    nyloApp = await setup.setup();
  }
  if (!isTestMode) {
    try {
      nyloApp._cache = await NyCache.getInstance();
    } catch (e) {
      // Cache initialization failed (e.g. path_provider native library issue)
    }
  }

  // Initialize theme manager after themes are registered
  await NyThemeManager.instance.init();

  if (nyloApp._enableErrorStack == true) {
    await ErrorStack.init(
      level: nyloApp._errorStackLogLevel ?? ErrorStackLogLevel.verbose,
      initialRoute: nyloApp.getInitialRoute(),
      errorWidget: nyloApp._errorStackErrorWidget,
    );
    nyloApp.addNavigatorObserver(ErrorStackNavigatorObserver());
  }
  if (nyloApp._useLocalNotifications == true) {
    FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
        FlutterLocalNotificationsPlugin();
    if (nyloApp._initializationSettings != null) {
      nyloApp.setLocalNotifications(flutterLocalNotificationsPlugin);
    }
  }

  // Initialize services
  if (services != null && services.isNotEmpty) {
    // Resolve all FutureOr<Runnable> to Runnable instances
    final List<Runnable> resolvedServices = [];
    for (final serviceOrFuture in services) {
      final Runnable resolvedService = await serviceOrFuture;
      resolvedServices.add(resolvedService);
      // Register in the service registry by type
      Runnable.register(resolvedService);
    }
    _services = resolvedServices;

    // Phase 1: Initialize all services
    for (final service in resolvedServices) {
      await service.onInit();
    }
    // Phase 2: All services ready
    for (final service in resolvedServices) {
      await service.onReady();
    }
    // Phase 3: App fully ready (navigation available)
    for (final service in resolvedServices) {
      await service.onAppReady();
    }
  }

  Backpack.instance.save("nylo", nyloApp);

  // Call boot after all initialization is complete
  if (setup != null) {
    await setup.boot(nyloApp);
  }

  return nyloApp;
}