Audience Management

Airship provides several ways to segment and personalize your audience through tags, attributes, events, and subscription lists. For more in-depth overview on each of those concepts, see Audience User Guide and Personalization User Guide.

This guide will cover how to link channels to a user as well as set segmentation and personalization data at both the user and device level.

Channels

Each device/app install will generate a unique identifier known as the Channel ID. Once a Channel ID is created, it will persist in the application until the app is reinstalled, or has its internal data is cleared.

Accessing the Airship Channel ID

Apps can access the Channel ID directly through the SDK.

Accessing the channel ID

val channelId = UAirship.shared().channel.id
String channelId = UAirship.shared().getChannel().getId();
let channelID = Airship.channel.identifier
NSString *channelID = UAirship.channel.identifier;
var channelId = UrbanAirship.getChannelId().then(channelId => {
    console.log('Channel: ', channelId);
}));
String channelId = await Airship.channelId;
UAirship.getChannelID(function (channelID) {
    console.log("Channel: " + channelID)
})
string channelId = Airship.Instance.ChannelId;
var channelId = Airship.channel.identifier;
string channelId = UAirship.Shared.ChannelId;

The Channel ID is asynchronously created, so it may not be available right away on the first run. Changes to Channel data will automatically be batched and applied when the Channel is created, so there is no need to wait for the Channel to be available before modifying any data.

Applications that need to access the Channel ID can use a listener to be notified when it is available.

Listening for the Channel ID

UAirship.shared().channel.addChannelListener(object : AirshipChannelListener {
    override fun onChannelCreated(channelId: String) {
        // created
    }

    override fun onChannelUpdated(channelId: String) {
        // updated - tags, tokens, opt-in status changed
    }
})
UAirship.shared().getChannel().addChannelListener(new AirshipChannelListener() {
    @Override
    public void onChannelCreated(@NonNull String channelId) {
        // created
    }

    @Override
    public void onChannelUpdated(@NonNull String channelId) {
        // updated - tags, tokens, opt-in status changed
    }
});
NotificationCenter.default.addObserver(self, selector: #selector(refreshView), name: Channel.channelCreatedEvent, object: nil);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshView) name:UAChannel.channelCreatedEvent object:nil];
UrbanAirship.addListener(EventType.Register, (event) => {
    console.log('Channel registration updated: ', event.channelId);
    console.log('Registration token: ', event.registrationToken);
});
Airship.onChannelRegistration.listen((event) {
    debugPrint('Channel registration $event');
});
document.addEventListener("urbanairship.registration", function (event) {
    if (event.error) {
        console.log('There was an error registering for push notifications')
    } else {
        console.log("Registered with ID: " + event.channelID)
    }
})
static void OnChannelCreation(object sender, ChannelEventArgs args) {
    Console.WriteLine("Channel created: " + args.ChannelId);
}

Airship.Instance.OnChannelCreation += OnChannelCreation;

static void OnChannelUpdate(object sender, ChannelEventArgs args) {
    Console.WriteLine("Channel updated: " + args.ChannelId);
}

Airship.Instance.OnChannelUpdate += OnChannelUpdate;
Airship.addEventListener(Airship.Airship.eventChannelCreated, function(e) {
    Ti.API.info('Channel created' + e.channelId);
});
UAirship.Shared.OnChannelUpdated += (string channelId) => {
    Debug.Log ("Channel updated: " + channelId);
};

Channel capture tool

The Channel ID is valuable for troubleshooting individual device issues in production apps. The Channel Capture tool that can be used to expose the Channel ID to the user, who can then send it to support.

If the Channel Capture tool is enabled, it will listen for 6 app foregrounds within 30 seconds. On the 6th open, the Channel ID will be copied to the user’s clipboard with a leading ua:. Paste your Channel ID from the clipboard to your preferred document. If there is no channel, only the ua: will be present. The Channel ID will remain on the clipboard for 60 seconds on iOS, and until cleared on Android.

The channel capture tool can be disabled through the Airship Config options.

Disabling channel capture tool

val options = AirshipConfigOptions.newBuilder()
    // ...
    .setChannelCaptureEnabled(false)
    .build()
AirshipConfigOptions options = AirshipConfigOptions.newBuilder()
    // ...
    .setChannelCaptureEnabled(false)
    .build();
config.isChannelCaptureEnabled = false
config.isChannelCaptureEnabled = NO;
// Not supported
// Not supported
// Not supported
// Not supported
// Not supported
// Not supported

Delaying channel creation

The Airship Channel will only be created if at least 1 feature is enabled in Privacy Manager. For more info on Privacy Manager, see: Data Collection.

Contacts

A Contact allows you to associate multiple devices to a single user or profile that may be associated with more than one device (e.g., an end-user’s tablet and phone). A device can only be associated with a single Contact.

A Contact can be either anonymous or named. When you name a Contact, you are assigning a Named User ID to the contact. Identifying a contact with a Named User allows you to modify the Contact through Named User APIs and use the Named User ID for segmentation. Anonymous contacts still allow tags, attributes, subscription lists, and channel association.

When a Contact goes from anonymous to named, the anonymous data will automatically carry over to the Named User ID, if the Named User is new. If the Named User already exists, a conflict event will be emitted by the SDK and the app is responsible for migrating anonymous data to the existing Named User.

Managing the Contact’s identifier (Named User ID)

 Note

By default, Contacts can only be associated server-side, via the Named User API. In order to identify a Contact via the SDK, you must change the application’s Named Users security setting to allow Named Users to be set from devices. See: Enable Named Users.

Identify can be called multiple times with the same Named User ID. The SDK will automatically deduplicate identify calls made with the same Named User ID. If the ID is changed from a previous value, the Contact will automatically be dissociated from the previous Named User ID.

Identifying the contact

UAirship.shared().contact.identify("some named user ID")
UAirship.shared().getContact().identify("some named user ID");
Airship.contact.identify("some named user ID")
[UAirship.contact identify:@"some named user ID"];
UrbanAirship.setNamedUser("some named user ID")
Airship.setNamedUser("some named user ID");
UAirship.setNamedUser("some named user ID")
Airship.Instance.NamedUser = "some named user ID";
Airship.contact.identify("some named user ID");
UAirship.Instance.NamedUser = "some named user ID";

If the user logs out of the device, you may want to reset the contact. This will clear any anonymous data and dissociate the contact from the Named User ID, if set. This should only be called when the user manually logs out of the app, otherwise you will not be able to target the Channel by its Contact data.

Resetting the Contact

UAirship.shared().contact.reset()
UAirship.shared().getContact().reset();
Airship.contact.reset()
[UAirship.contact reset];
UrbanAirship.setNamedUser(null)
Airship.setNamedUser(null);
UAirship.setNamedUser(null)
Airship.Instance.NamedUser = null;
Airship.contact.reset();
UAirship.Instance.NamedUser = null;

Email channel association

When an email address is registered through the SDK, it will be registered for both transactional and commercial emails by default. To change this behavior, you can override the options to request Double Opt-InA process where users who sign up for messaging must confirm opting in before they can receive messages. for commercial messages.

Associated an email channel

val properties = JsonMap.newBuilder().put("place", "paris").build()
val options = EmailRegistrationOptions.commercialOptions(commercialDate, transactionalDate, properties)
UAirship.shared().contact.registerEmail("your@example.com", options)
JsonMap properties = JsonMap.newBuilder().put("place", "paris").build();
EmailRegistrationOptions options = EmailRegistrationOptions.commercialOptions(commercialDate, transactionalDate, properties);
UAirship.shared().getContact().registerEmail("your@example.com", options);
let options = EmailRegistrationOptions.commercialOptions(transactionalOptedIn: transactionalDate, commercialOptedIn: commercialDate, properties: properties)
Airship.contact.registerEmail("your@example.com", options: Options)
UAEmailRegistrationOptions* options = [UAEmailRegistrationOptions commercialOptionsWithTransactionalOptedIn:transactionalDate commercialOptedIn:commercialDate properties:properties];
[UAirship.contact registerEmail:@"your@example.com" options:options];
// Not supported
// Not supported
// Not supported
// Not supported
// Not supported
// Not supported

SMS channel association

When an MSISDNThe mobile phone number of an individual in your Airship audience. Each MSISDN represents an individual mobile device. is registered through the SDK, Airship sends a message to that number, prompting them to opt in. For more information, see the SMS platform documentation: Non-Mobile Double Opt-In.

Associated an SMS channel

val options = SmsRegistrationOptions.options("senderId")
UAirship.shared().contact.registerSms("yourMsisdn", options)
SmsRegistrationOptions options = SmsRegistrationOptions.options("senderId");
UAirship.shared().getContact().registerSms("yourMsisdn", options);
let options = SMSRegistrationOptions.optIn(senderID: "senderId")
Airship.contact.registerSMS("yourMsisdn", options: Options)
UASMSRegistrationOptions* options = [UASMSRegistrationOptions optInSenderID:@"senderId"];
[UAirship.contact registerSMS:"yourMsisdn" options:options];
// Not supported
// Not supported
// Not supported
// Not supported
// Not supported
// Not supported

Open Channel association

Open Channels support notifications to any medium that can accept a JSON payload, through either the Airship API or web dashboard. For more information about Open Channels, see the Open Channels documentation.

Associated an Open Channel

val options = OpenChannelRegistrationOptions.options("platformName")
UAirship.shared().contact.registerOpenChannel("address", options)
OpenChannelRegistrationOptions options = OpenChannelRegistrationOptions.options("platformName");
UAirship.shared().getContact().registerOpenChannel("address", options);
let options = OpenRegistrationOptions.optIn(senderID: "platformName")
Airship.contact.registerOpen("address", options: Options)
UAOpenRegistrationOptions* options = [UAOpenRegistrationOptions optInSenderID:@"platformName"];
[UAirship.contact registerOpen:"address" options:options];
// Not supported
// Not supported
// Not supported
// Not supported
// Not supported
// Not supported

Device Tags

Device tags are tags managed on the Channel by the SDK. These tags can be modified or fetched from the Channel.

Modifying tags

UAirship.shared().channel.editTags()
    .addTag("some_tag")
    .removeTag("some_other_tag")
    .apply()
UAirship.shared().getChannel().editTags()
    .addTag("some_tag")
    .removeTag("some_other_tag")
    .apply();
Airship.channel.editTags { editor in
    editor.set(["one", "two", "three"])
    editor.add("a_tag")
    editor.remove("three")
}
[UAirship.channel editTags:^(UATagEditor *editor) {
    [editor setTags:@[@"one", @"two", @"three"]];
    [editor addTag:@"a_tag"];
    [editor removeTag:@"three"];
}];
UrbanAirship.addTag("some tag");
UrbanAirship.removeTag("other tag");
Airship.addTags(["flutter"]);
Airship.removeTags(["some-tag"]);
UAirship.setTags(["loves_cats", "shops_for_games"], function () {
})
// Add tags
Airship.Instance.EditDeviceTags()
    .AddTags(new string[] { "one", "two", "three" })
    .Apply();

// Add a tag
Airship.Instance.EditDeviceTags()
    .AddTag("a_tag")
    .Apply();

// Remove a tag
Airship.Instance.EditDeviceTags()
    .RemoveTag("a_tag")
    .Apply();
Airship.channel.tags = ["some-tag", "other-tag"];
// Add tag
UAirship.Shared.AddTag ("some-tag");

// Remove tag
UAirship.Shared.RemoveTag ("other-tag");

Since the device is managing the tags, they can be fetched from the SDK.

Accessing tags

Val tags = UAirship.shared().channel.tags
ArrayList<String> tags = UAirship.shared().channel.tags;
let tags = Airship.channel.tags
NSArray* tags = [[UAirship channel] tags];
UrbanAirship.getTags().then((tags) => {
    console.log('Tags: ', tags)
});
List<String> tags = await Airship.tags;
UAirship.getTags(function (tags) {
    tags.forEach(function (tag) {
        console.log("Tag: " + tag)
    })
})
IEnumerable<string> tags = Airship.Instance.Tags;
var tags = Airship.tags;
IEnumerable<string> tags = UAirship.Shared.Tags;

Tag Groups

Tag groups are tags scoped within a group. Tag groups are supported at both the Channel and Contact level. Tag groups are only able to be modified from the SDK but not fetched. If you need to be able to fetch the tag groups, consider using subscription lists.

Modifying tag groups

// Channel Tag Group Example
UAirship.shared().channel.editTagGroups()
    .addTag("loyalty", "bronze-member")
    .removeTag("loyalty", "bronze-member")
    .setTag("games", "bingo")
    .apply()

// Contact Tag Group Example
UAirship.shared().contact.editTagGroups()
    .addTag("loyalty", "bronze-member")
    .removeTag("loyalty", "bronze-member")
    .setTag("games", "bingo")
    .apply()
// Channel Tag Group Example
UAirship.shared().getChannel().editTagGroups()
    .addTag("loyalty", "bronze-member")
    .removeTag("loyalty", "bronze-member")
    .setTag("games", "bingo")
    .apply();

// Contact Tag Group Example
UAirship.shared().getContact().editTagGroups()
    .addTag("loyalty", "bronze-member")
    .removeTag("loyalty", "bronze-member")
    .setTag("games", "bingo")
    .apply();
// Channel Tag Group Example
Airship.channel.editTagGroups { editor in
    editor.add(["silver-member", "gold-member"], group:"loyalty")
    editor.remove(["bronze-member", "club-member"], group:"loyalty")
    editor.set(["bingo"], group:"games")
}

// Contact Tag Group Example
Airship.contact.editTagGroups { editor in
    editor.add(["silver-member", "gold-member"], group:"loyalty")
    editor.remove(["bronze-member", "club-member"], group:"loyalty")
    editor.set(["bingo"], group:"games")
}
// Channel Tag Group Example
[UAirship.channel editTagGroups:^(UATagGroupsEditor *editor) {
    [editor addTags:@[@"silver-member", @"gold-member"] group:@"loyalty"];
    [editor removeTags:@[@"bronze-member", @"club-member"] group:@"loyalty"];
    [editor setTags:@[@"bingo"] group:@"games"];
}];

// Contact Tag Group Example
[UAirship.contact editTagGroups:^(UATagGroupsEditor *editor) {
    [editor addTags:@[@"silver-member", @"gold-member"] group:@"loyalty"];
    [editor removeTags:@[@"bronze-member", @"club-member"] group:@"loyalty"];
    [editor setTags:@[@"bingo"] group:@"games"];
}];
// Channel Tag Group Example
UrbanAirship.editChannelTagGroups()
    .addTags("loyalty", ["silver-member"])
    .removeTags("loyalty", ["bronze-member"])
    .apply()

// Named User Tag Group Example
UrbanAirship.editContactTagGroups()
    .addTags("loyalty", ["silver-member"])
    .removeTags("loyalty", ["bronze-member"])
    .apply()
// Channel Tag Group Example
Airship.editChannelTagGroups()
    ..addTags("loyalty", ["silver-member"])
    ..removeTags("loyalty", ["bronze-member"])
    ..apply()

// Named User Tag Group Example
Airship.editNamedUserTagGroups()
    ..addTags("loyalty", ["silver-member"])
    ..removeTags("loyalty", ["bronze-member"])
    ..apply()
// Channel Tag Group Example
UAirship.editChannelTagGroups()
    .addTags("loyalty", ["silver-member"])
    .removeTags("loyalty", ["bronze-member"])
    .apply()

// Named User Tag Group Example
UAirship.editNamedUserTagGroups()
    .addTags("loyalty", ["silver-member"])
    .removeTags("loyalty", ["bronze-member"])
    .apply()
// Channel Tag Group Example
Airship.Instance.EditChannelTagGroups()
    .AddTags(new string[] { "silver-member", "gold-member" }, "loyalty")
    .SetTags(new string[] { "bingo" }, "games")
    .RemoveTags(new string[] { "bronze-member", "club-member"}, "loyalty")
    .Apply();


// Named User Tag Group Example
Airship.Instance.EditNamedUserTagGroups()
    .AddTags(new string[] { "silver-member", "gold-member" }, "loyalty")
    .SetTags(new string[] { "bingo" }, "games")
    .RemoveTags(new string[] { "bronze-member", "club-member" }, "loyalty")
    .Apply();
// Channel Tag Group Example
Airship.channel.editTagGroups()
    .addTags("loyalty", ["silver-member"])
    .removeTags("loyalty", ["bronze-member"])
    .apply()

// Set tags on a group
Airship.contact.editTagGroups()
    .addTags("loyalty", ["silver-member"])
    .removeTags("loyalty", ["bronze-member"])
    .apply()
// Channel Tag Group Example
UAirship.Shared.EditChannelTagGroups ()
    .AddTag ("loyalty", "silver-member")
    .RemoveTag ("loyalty", "bronze-member")
    .Apply ();

// Named User Tag Group Example
UAirship.Shared.EditNamedUserTagGroups ()
    .AddTag ("loyalty", "silver-member")
    .RemoveTag ("loyalty", "bronze-member")
    .Apply ();

Attributes

Attributes are key-value pairs, associated with either the channel or contact.

Modifying attributes

// Channel Attributes Example
UAirship.shared().channel.editAttributes()
    .setAttribute("device_name", "Bobby's Phone")
    .setAttribute("average_rating", 4.99)
    .removeAttribute("connection_type")
    .apply()

// Contact Attributes Example
UAirship.shared().contact.editAttributes()
    .setAttribute("first_name", "Bobby")
    .setAttribute("birthday", Date(524300400000))
    .apply()
// Channel Attributes Example
UAirship.shared().getChannel().editAttributes()
    .setAttribute("device_name", "Bobby's Phone")
    .setAttribute("average_rating", 4.99)
    .removeAttribute("connection_type")
    .apply();

// Contact Attributes Example
UAirship.shared().getContact().editAttributes()
    .setAttribute("first_name", "Bobby")
    .setAttribute("birthday", Date(524300400000))
    .apply();
// Channel Attributes Example
Airship.channel.editAttributes { editor in
    editor.set(string: "Bobby's Phone", attribute: "device_name")
    editor.set(number: 4.99, attribute: "average_rating")
    editor.remove("connection_type")
}

// Contact Attributes Example
Airship.contact.editAttributes { editor in
    editor.set(string: "Bobby", attribute: "first_name")
}
// Channel Attributes Example
[UAirship.channel editAttributes:^(UAAttributesEditor * editor) {
    [editor setString:@"Bobby's Phone" attribute:@"device_name"];
    [editor setNumber:@(4.99) attribute:@"average_rating"];
    [editor removeAttribute:@"connection_type"];
}];

// Contact Attributes Example
[UAirship.contact editAttributes:^(UAAttributesEditor * editor) {
    [editor setString:@"Bobby" attribute:@"first_name"];
}];
// Channel Attributes Example
UrbanAirship.editChannelAttributes()
    .setAttribute("device_name", "Bobby's Phone")
    .setAttribute("average_rating", 4.99)
    .removeAttribute("connection_type")
    .apply()

// Contact Attributes Example
UrbanAirship.editNamedUserAttributes()
    .setAttribute("first_name", "Bobby")
    .apply()
// Channel Attributes Example
Airship.editAttributes()
    ..setAttribute("device_name", "Bobby's Phone")
    ..setAttribute("average_rating", 4.99)
    ..removeAttribute("connection_type")
    ..apply()

// Contact Attributes Example
Airship.editNamedUserAttributes()
    ..setAttribute("first_name", "Bobby")
    ..apply()
// Channel Attributes Example
UrbanAirship.editChannelAttributes()
    .setAttribute("device_name", "Bobby's Phone")
    .setAttribute("average_rating", 4.99)
    .removeAttribute("connection_type")
    .apply()

// Contact Attributes Example
UrbanAirship.editNamedUserAttributes()
    .setAttribute("first_name", "Bobby")
    .apply()
// Channel Attributes Example
Airship.Instance.EditChannelAttributes()
    .SetAttribute("device_name", "Bobby's Phone")
    .SetAttribute("average_rating", 4.99)
    .RemoveAttribute("connection_type")
    .Apply();

// Contact Attributes Example
Airship.Instance.EditNamedUserAttributes()
    .SetAttribute("first_name", "Bobby")
    .Apply();
// Channel Attributes Example
Airship.channel.editAttributes()
    .setAttribute("device_name", "Bobby's Phone")
    .setAttribute("average_rating", 4.99)
    .removeAttribute("connection_type")
    .apply()

// Contact Attributes Example
Airship.contact.editAttributes()
    .setAttribute("first_name", "Bobby")
    .apply()
// Channel Attributes Example
UAirship.Shared.EditChannelAttributes()
    .SettAttribute("device_name", "Bobby's Phone")
    .SetAttribute("average_rating", 4.99)
    .RemoveAttribute("connection_type")
    .Apply()

// Contact Attributes Example
UAirship.Shared.EditNamedUserAttributes()
    .SettAttribute("first_name", "Bobby")
    .Apply()

Subscription lists

Subscription lists allow a Channel or Contact to subscribe to topic based messaging.

Channel subscriptions apply only to the single channel.

Modifying Channel subscription lists

UAirship.shared().channel.editSubscriptionLists()
    .subscribe("food")
    .unsubscribe("sports")
    .apply()
UAirship.shared().getChannel().editSubscriptionLists();
    .subscribe("food");
    .unsubscribe("sports");
    .apply();
let editor = Channel.shared.editSubscriptionLists();
editor.subscribe("food")
editor.unsubscribe("sports")
editor.apply()
UASubscriptionListEditor *editor = [[UAChannel shared] editSubscriptionLists];
[editor subscribe:@"food"];
[editor unsubscribe:@"sports"];
[editor apply];
UrbanAirship.editChannelSubscriptionLists()
    .subscribe("food")
    .unsubscribe("sports")
    .apply()
Airship.editChannelSubscriptionLists()
    ..subscribe("food")
    ..unsubscribe("sports")
    ..apply();
UAirship.editChannelSubscriptionLists()
    .subscribe("food")
    .unsubscribe("sports")
    .apply()
// Not supported
// Not supported
// Not supported

Contact subscriptions are set at the user-level. When you modify a Contact subscription list, you must also include a Channel scope specifying the types that the subscription list applies to.

Modifying contact subscription lists

UAirship.shared().contact.editSubscriptionLists()
    .subscribe("food", "app")
    .unsubscribe("sports", "sms")
    .apply()
UAirship.shared().getContact().editSubscriptionLists();
    .subscribe("food", "app");
    .unsubscribe("sports", "sms");
    .apply();
let editor = Contact.shared.editSubscriptionLists();
editor.subscribe("food", scope: "app"")
editor.unsubscribe("sports", scope: "sms")
editor.apply()
UAScopedSubscriptionListEditor *editor = [[UAContact shared] editSubscriptionLists];
[editor subscribe:"food" scope:"app"];
[editor unsubscribe:"sports" scope:"sms"];
[editor apply];
UrbanAirship.editContactSubscriptionLists()
    .subscribe("food", "app")
    .unsubscribe("sports", "sms")
    .apply()
Airship.editContactSubscriptionLists()
    ..subscribe("food", ["sms"])
    ..unsubscribe("sports", ["email"])
    ..apply();
UAirship.editContactSubscriptionLists()
    .subscribe("food", "app")
    .unsubscribe("sports", "sms")
    .apply()
// Not supported
// Not supported
// Not supported

Channel subscription lists are returned as a simple list of subscription IDs.

Fetching channel subscription lists

// Include subscription list changes that have been requested via SubscriptionListEditor
// and will be applied during the next channel update.
val includePendingUpdates = true
val subscriptionsPendingResult =
    UAirship.shared().channel.getSubscriptionLists(includePendingUpdates)
// Include subscription list changes that have been requested via SubscriptionListEditor
// and will be applied during the next channel update.
boolean includePendingUpdates = true;
PendingResult<Set<String>> subscriptionsPendingResult = 
    UAirship.shared().getChannel().getSubscriptionLists(includePendingUpdates);
Channel.shared.fetchSubscriptionLists { channelSubscriptionLists, Error in
    // Use the channelSubscriptionLists
}
[[UAChannel shared] fetchSubscriptionListsWithCompletionHandler:^(NSArray<NSString *> * _Nullable channelSubscriptionLists, NSError * _Nullable error) {
    // Use the channelSubscriptionLists
}];
UrbanAirship.getSubscriptionLists(["channel"]).then((subscriptionList) => {
    var channelSubscriptionLists = subscriptionList.channel;
});
SubscriptionList subscriptionList = await Airship.getSubscriptionLists(["channel"]);
List<String> channelSubscriptionLists = subscriptionList.channelSubscriptionLists;
SubscriptionList subscriptionList = await Airship.getSubscriptionLists(["channel"]);
List<String> channelSubscriptionLists = subscriptionList.channelSubscriptionLists;
// Not supported
// Not supported
// Not supported

Contact subscription lists are returned as a map of subscription list IDs to a list of platform scopes.

Fetching contact subscription lists

// Include subscription list changes that have been requested via SubscriptionListEditor
// and will be applied during the next contact update.
val includePendingUpdates = true
val subscriptionsPendingResult = 
    UAirship.shared().contact.getSubscriptionLists(includePendingUpdates)
// Include subscription list changes that have been requested via SubscriptionListEditor
// and will be applied during the next contact update.
boolean includePendingUpdates = true;
PendingResult<Map<String, Set<Scope>>> subscriptionsPendingResult = 
    UAirship.shared().getContact().getSubscriptionLists(includePendingUpdates);
Contact.shared.fetchSubscriptionLists { contactSubscriptionLists, error in
    // Use the contactSubscriptionLists
}
[[UAContact shared] fetchSubscriptionListsWithCompletionHandler:^(NSDictionary<NSString *,UAChannelScopes *> * _Nullable contactSubscriptionLists, NSError * error) {
    // Use the contactSubscriptionLists
}];
UrbanAirship.getSubscriptionLists(["contact"]).then((subscriptionList) => {
    var contactSubscriptionList = subscriptionList.contact;
});
SubscriptionList subscriptionList = await Airship.getSubscriptionLists(["contact"]);
List<ContactSubscriptionList> contactSubscriptionList = subscriptionList.contactSubscriptionLists;
SubscriptionList subscriptionList = await Airship.getSubscriptionLists(["contact"]);
List<ContactSubscriptionList> contactSubscriptionList = subscriptionList.contactSubscriptionLists;
// Not supported
// Not supported
// Not supported