Embed the Preference Center

Create custom Preference Center UIs by fetching the config and building your own subscription management interface.

This guide covers creating custom Preference Center UIs for Flutter applications. Unlike the default Preference Center, you’ll build your own UI from scratch using the Preference Center configuration and subscription list APIs.

Override Default Display Behavior

To use a custom Preference Center instead of the default UI, disable auto-launch for the specific Preference Center ID and handle display events:

// Disable the OOTB UI for this Preference Center
Airship.preferenceCenter.setAutoLaunchDefaultPreferenceCenter(
  "preference-center-id",
  false
);

// Add a listener to handle display events
StreamSubscription? subscription;

subscription = Airship.preferenceCenter.onDisplay.listen((event) {
  final preferenceCenterId = event.preferenceCenterId;
  // Navigate to your custom preference center UI
  navigateToCustomPreferenceCenter(preferenceCenterId);
});

Fetching Preference Center Config

The Preference Center config contains all the information needed to build your UI, including subscription lists, sections, and display settings.

PreferenceCenterConfig config = await Airship.preferenceCenter.getConfig("preference-center-id");
 Note

The config might not be available immediately on first app start. Implement exponential backoff if automatically retrying, or provide a UI for users to manually retry.

Building Your Custom UI

You’ll need to:

  1. Fetch the config to get the list of subscription lists and their current state
  2. Build your UI using the config data (sections, subscription lists, display settings)
  3. Update subscription lists when users make changes using the Subscription List APIs

Example Implementation

import 'package:flutter/material.dart';
import 'package:airship_flutter/airship_flutter.dart';

class CustomPreferenceCenterScreen extends StatefulWidget {
  final String preferenceCenterId;

  const CustomPreferenceCenterScreen({
    Key? key,
    required this.preferenceCenterId,
  }) : super(key: key);

  @override
  _CustomPreferenceCenterScreenState createState() =>
      _CustomPreferenceCenterScreenState();
}

class _CustomPreferenceCenterScreenState
    extends State<CustomPreferenceCenterScreen> {
  PreferenceCenterConfig? _config;
  bool _loading = true;
  Map<String, bool> _subscriptions = {};

  @override
  void initState() {
    super.initState();
    _loadConfig();
  }

  Future<void> _loadConfig() async {
    try {
      final config = await Airship.preferenceCenter.getConfig(
        widget.preferenceCenterId,
      );
      
      // Load current subscription status
      final currentSubs = await Airship.contact.subscriptionLists;
      final subsMap = <String, bool>{};
      
      for (var section in config.sections) {
        for (var item in section.items) {
          if (item.subscriptionId != null) {
            subsMap[item.subscriptionId!] = currentSubs.contains(item.subscriptionId);
          }
        }
      }

      setState(() {
        _config = config;
        _subscriptions = subsMap;
        _loading = false;
      });
    } catch (error) {
      print('Failed to load config: $error');
      setState(() {
        _loading = false;
      });
    }
  }

  Future<void> _toggleSubscription(String listId, bool subscribe) async {
    try {
      if (subscribe) {
        await Airship.contact.editSubscriptionLists()
            .subscribe(listId)
            .apply();
      } else {
        await Airship.contact.editSubscriptionLists()
            .unsubscribe(listId)
            .apply();
      }

      setState(() {
        _subscriptions[listId] = subscribe;
      });
    } catch (error) {
      print('Failed to update subscription: $error');
    }
  }

  @override
  Widget build(BuildContext context) {
    if (_loading) {
      return Scaffold(
        appBar: AppBar(title: Text('Loading...')),
        body: Center(child: CircularProgressIndicator()),
      );
    }

    if (_config == null) {
      return Scaffold(
        appBar: AppBar(title: Text('Error')),
        body: Center(
          child: Text('Failed to load Preference Center'),
        ),
      );
    }

    return Scaffold(
      appBar: AppBar(
        title: Text(_config!.display?.name ?? 'Preferences'),
      ),
      body: ListView.builder(
        itemCount: _config!.sections.length,
        itemBuilder: (context, sectionIndex) {
          final section = _config!.sections[sectionIndex];
          
          return Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              if (section.display?.name != null)
                Padding(
                  padding: EdgeInsets.all(16),
                  child: Text(
                    section.display!.name!,
                    style: Theme.of(context).textTheme.titleLarge,
                  ),
                ),
              ...section.items.map((item) {
                final subscriptionId = item.subscriptionId;
                if (subscriptionId == null) return SizedBox.shrink();

                return SwitchListTile(
                  title: Text(item.display?.name ?? ''),
                  subtitle: item.display?.description != null
                      ? Text(item.display!.description!)
                      : null,
                  value: _subscriptions[subscriptionId] ?? false,
                  onChanged: (value) {
                    _toggleSubscription(subscriptionId, value);
                  },
                );
              }).toList(),
              Divider(),
            ],
          );
        },
      ),
    );
  }
}
 Important

Preference Center configuration is currently limited to subscription lists only. Use the Subscription List APIs to manage user subscriptions.