Flutter SDK Lifecycle
This page covers how the Magify Flutter SDK starts up, tracks sessions, and keeps its remote configuration in sync over the life of your app.
Initialization
Everything goes through the MagifyClient singleton, reached through MagifyClient.instance.
Call init once, as early as possible during startup, and await it before making any other
call:
await MagifyClient.instance.init(
const MagifyConfig(
applicationName: 'MyApplication',
defaultConfig: 'assets/magify_default_config.json',
isSandbox: false,
),
);
Calling init more than once is safe: later calls return the future of the first call and
do not create a second client instance — the config passed to those later calls is
ignored. A failed call is not cached, so the next call retries the initialization. A failure
throws MagifyException.
bool get isInitialized reports whether init has completed successfully. It is
synchronous — use it for guard checks, not as a substitute for awaiting init.
Sessions
The SDK tracks how many times the app has been launched. You do not need to send an
app-launch event yourself — the SDK sends it automatically, once per session, as part of
init.
MagifyClient.instance.sessionNumberChanges.listen((sessionNumber) {
debugPrint('Session started: $sessionNumber');
});
Remote configuration
The SDK downloads a remote config on init and keeps it available for features,
storedFeatures and content to read.
MagifyClient.instance.configLoaded.listen((_) {
// Feature flags, stored features and content are safe to re-read now.
});
await MagifyClient.instance.update();
Call update() whenever your app wants a fresher config on demand — for example when it
returns to the foreground — rather than waiting for the SDK's own scheduled refresh.
Context sync time
Future<ContextSyncTime?> get contextSyncTime returns the clock offset between the device
and the Magify backend, as measured during the last context sync. It is null until the
first sync has completed.
final syncTime = await MagifyClient.instance.contextSyncTime;
if (syncTime != null) {
debugPrint('Device/backend clock offset: ${syncTime.offset}');
}
Use offset when your app needs backend-accurate timestamps (for example, time-limited
offers) but only has the device clock available.
Resetting local state
Future<void> resetState() drops locally-held client state — counters, trackers and cached
campaigns — and then reloads the remote config. Treat it as a development/debugging helper,
not a user logout.
Platform difference: on iOS, resetState() also sends a fresh app-launch event and
resets the session counter back to 1; on Android it resets and reloads the config without
touching the session counter. Keep this in mind if your app or your tests read
sessionNumber right after calling resetState().
await MagifyClient.instance.resetState();
Errors
A failed SDK call throws MagifyException, carrying code, message and details. Model
constructors (and a couple of validation calls, like setPurchaseVerificationPolicy) throw
ArgumentError instead, for input that's invalid before the call is even made.
Next step
Now that you understand initialization, sessions and config refresh, continue to Privacy to configure logging, GeoIP resolution and authorization status.