initialize method

Future<void> initialize(
  1. DigiaConfig config
)

Implementation

Future<void> initialize(DigiaConfig config) async {
  if (_initialized) {
    debugPrint('[Digia] initialize() called more than once — ignored.');
    return;
  }
  _config = config;
  _initialized = true;
  _sdkState = SDKState.initializing;

  // Apply the global font family to all Digia-rendered text (mirrors
  // Android setting DigiaFontConfig.fontFamily at the top of init).
  EngageFonts.fontFamily = config.fontFamily;

  WidgetsBinding.instance.addObserver(this);

  // Construct the guide manager now so it registers the showcase controller
  // and listens to the orchestrator before any campaign is routed.
  _guideManager;

  // The whole init runs under one guard (mirrors Android's DigiaInstance):
  // any failure leaves the SDK in [SDKState.failed] and resets the
  // started flag so a later call can retry.
  try {
    // Resolve the engage API host from the config (explicit `baseUrl` wins,
    // else derived from `environment`) before ANY network call is made —
    // campaign fetch, analytics track, and session reporting all read the
    // URLs from [DigiaEndpoints]. Mirrors Android's endpoint configuration.
    DigiaEndpoints.configure(config);

    // Register the host's action override (if any) on the shared runner.
    EngageActionRunner.shared.interceptor = config.onAction;

    // ── Resolve base URL (sandbox → dev.digia.tech, prod → app.digia.tech) ─
    DigiaEndpoints.configure(config);

    // ── Fetch + cache engage campaigns ──────────────────────────────────
    await PreferencesStore.instance.initialize();
    // Resolve the shared session (reused across a relaunch within the timeout)
    // before anything reads it — both analytics event grouping and frequency's
    // session-scoped caps depend on it.
    await SessionManager.instance
        .initialize(config.analyticsConfig.sessionTimeoutMs);
    await DigiaAnalyticsService.instance
        .initialize(config.analyticsConfig, config.apiKey);
    _wireSessionReporting(config);
    final deviceId = EngageSettings.instance.getUuid();
    _submissionReporter = SubmissionReporter(config, deviceId);
    final campaigns = await CampaignFetcher(config, deviceId).fetch();
    _campaignStore.populate(campaigns);

    // ── Ready ───────────────────────────────────────────────────────────
    _sdkState = SDKState.ready;
    if (_campaignStore.isEmpty) {
      debugPrint('[Digia] No campaigns fetched — CampaignStore is empty.');
    } else {
      _logIfVerbose('Fetched ${campaigns.length} campaign(s).');
    }
    _flushPendingPayloadIfAny();

    _logIfVerbose('Digia initialized with apiKey=${config.apiKey}, '
        'environment=${config.environment.name}.');
  } catch (e) {
    _initialized = false;
    _sdkState = SDKState.failed;
    debugPrint('[Digia] initialize failed: $e');
    // A template presented during init left a CEP slot held (we returned
    // `true` from onCampaignTriggered). Init failed so it will never route —
    // release the slot, else later in-apps queue forever.
    final pending = _pendingPayload;
    _pendingPayload = null;
    if (pending != null) {
      _events.toCep(const ExperienceDismissed(), pending);
    }
  }
}