Analytique push et journalisation d’événements personnalisés
Cette page couvre les workflows suivants : l’analytique push native (ouvertures, ouvertures influencées et rapports de Campaign) et la journalisation de données personnalisées (événements personnalisés et attributs) à partir des payloads push. Utilisez ce guide pour identifier le workflow qui correspond à votre cas d’utilisation et suivez les étapes pour votre plateforme.
Prérequis
Avant de commencer, effectuez l’intégration initiale des notifications push pour votre plateforme :
Analyse native des notifications push vs. enregistrement d’événements personnalisés
Les workflows suivants ont chacun des surfaces de reporting différentes.
| Catégorie d’analyse | Description | Où elle apparaît |
|---|---|---|
| Analyse native des notifications push | Indicateurs de notification push tels que les ouvertures et les ouvertures influencées, liés aux Campaigns de notification push de Braze | Analyse des Campaigns de notification push, événements d’engagement liés aux messages Currents, générateur de rapports |
| Événements personnalisés et attributs | Analyses que vous définissez et enregistrez via les méthodes du SDK ou l’endpoint /users/track |
Profils utilisateur, segmentation, Campaigns et Canvas déclenchés par une action, analyse des événements personnalisés |

L’enregistrement d’un événement personnalisé (tel que push_notification_opened) n’est pas la même chose que le suivi natif des ouvertures de notifications push dans Braze. Les événements personnalisés ne remplissent pas les indicateurs natifs d’ouverture des Campaigns de notification push ni l’attribution push.
Ce que Braze enregistre automatiquement
Lorsque votre intégration SDK est configurée, Braze enregistre automatiquement les données d’interaction principales des canaux, y compris les ouvertures de notifications push et les ouvertures influencées. Aucun code supplémentaire n’est requis pour les analyses standard des notifications push. Pour une liste complète des données collectées automatiquement, consultez Collecte de données SDK.
Pour plus de détails, consultez les ressources suivantes :
- Collecte de données SDK pour une liste complète des données collectées automatiquement et des données optionnelles.
- Ouvertures influencées pour découvrir comment Braze calcule les ouvertures influencées.
- Événements d’engagement liés aux messages pour les schémas d’événements en aval dans Currents.
Préserver les analyses de notification push native avec un gestionnaire de notifications push personnalisé
Il peut être nécessaire d’utiliser un gestionnaire de notifications push personnalisé lorsque vous devez intégrer plusieurs fournisseurs de notifications push, traiter des données de payload supplémentaires ou implémenter une logique d’affichage de notification personnalisée. Si vous utilisez un gestionnaire de notifications push personnalisé, vous devez tout de même transmettre les payloads de notification push aux méthodes du SDK Braze. Cela permet à Braze d’extraire les données de suivi intégrées et d’enregistrer les analyses de notification push native (ouvertures, ouvertures influencées et indicateurs de distribution).
Si vous disposez d’un FirebaseMessagingService personnalisé, appelez BrazeFirebaseMessagingService.handleBrazeRemoteMessage(...) dans votre méthode onMessageReceived. Gardez à l’esprit que votre sous-classe FirebaseMessagingService doit terminer son exécution dans les 9 secondes suivant l’invocation pour éviter d’être signalée ou interrompue par le système Android.
public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if (BrazeFirebaseMessagingService.handleBrazeRemoteMessage(this, remoteMessage)) {
// Braze processed a Braze push payload.
} else {
// Non-Braze payload: pass to your other handlers.
}
}
}
Pour un exemple d’implémentation complet, consultez l’application exemple Firebase push du SDK Android de Braze.
Dans une intégration push manuelle, transmettez les rappels de notifications en arrière-plan et de notifications utilisateur à Braze.
Notifications en arrière-plan :
if let braze = AppDelegate.braze, braze.notifications.handleBackgroundNotification(
userInfo: userInfo,
fetchCompletionHandler: completionHandler
) {
return
}
completionHandler(.noData)
Réponses aux notifications utilisateur :
if let braze = AppDelegate.braze, braze.notifications.handleUserNotification(
response: response,
withCompletionHandler: completionHandler
) {
return
}
completionHandler()
Notifications au premier plan :
func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
) {
if let braze = AppDelegate.braze {
braze.notifications.handleForegroundNotification(notification: notification)
}
if #available(iOS 14.0, *) {
completionHandler([.banner, .list, .sound])
} else {
completionHandler([.alert, .sound])
}
}
Pour un exemple d’implémentation complet, consultez l’exemple push manuel du SDK Swift de Braze (AppDelegate.swift).
Pour les notifications push Web, configurez votre service de traitement et l’initialisation du SDK comme décrit dans Notifications push Web.
Pour plus d’exemples de code, consultez le dépôt du SDK Web de Braze.
Journalisation de données personnalisées à partir des payloads de notifications push
Utilisez cette section lorsque vous devez journaliser des données supplémentaires à partir des paires clé-valeur des payloads de notifications push, telles que des événements personnalisés ou des attributs liés à votre logique métier.
Pour plus d’informations sur les événements personnalisés, consultez Événements personnalisés. Pour journaliser des événements personnalisés via les méthodes du SDK, consultez Journalisation des événements personnalisés.
Option A : Journaliser avec l’endpoint /users/track
Vous pouvez journaliser des données d’analyse en temps réel en appelant l’endpoint /users/track.
Pour identifier le profil utilisateur, incluez braze_id dans les paires clé-valeur du payload de votre notification push.

Le passage de braze_id ne fait qu’identifier le profil. Vous devez toujours implémenter la logique qui lit les valeurs du payload et envoie la requête /users/track avec les événements ou attributs que vous souhaitez journaliser.
Option B : Journaliser avec les méthodes du SDK après le lancement de l’application
Vous pouvez également enregistrer les données du payload localement, puis journaliser les événements personnalisés et les attributs via les méthodes du SDK après l’initialisation de l’application. Cette approche est courante dans les flux d’extension de contenu de notification, où les données d’analyse sont d’abord persistées puis envoyées lors du prochain lancement de l’application.

Les données d’analyse ne sont pas envoyées à Braze tant que l’application n’est pas lancée. Selon vos paramètres de fermeture, il peut y avoir un délai entre le moment où l’utilisateur ferme la notification et celui où l’application s’ouvre et envoie les données d’analyse.
Journalisation depuis une extension de contenu de notification (Swift)
Les étapes suivantes décrivent comment enregistrer et envoyer des événements personnalisés, des attributs personnalisés et des attributs utilisateur depuis une extension de contenu de notification Swift.
Étape 1 : Configurer les groupes d’applications dans Xcode
Dans Xcode, ajoutez la capacité App Groups à la cible de votre application principale. Activez App Groups, puis cliquez sur + pour ajouter un nouveau groupe. Utilisez l’identifiant de bundle de votre application pour créer l’identifiant du groupe (par exemple, group.com.company.appname.xyz). Activez App Groups à la fois pour la cible de votre application principale et pour la cible de l’extension de contenu.

Étape 2 : Choisir ce que vous souhaitez journaliser
Avant d’implémenter les extraits de code, choisissez la catégorie d’analyse que vous souhaitez journaliser :
- Événements personnalisés : actions effectuées par les utilisateurs (par exemple, compléter un parcours ou appuyer sur un élément spécifique de l’interface). Utilisez les événements personnalisés pour les déclencheurs basés sur les actions, la segmentation et l’analyse des événements. Pour en savoir plus, consultez Événements personnalisés et Journalisation des événements personnalisés.
- Attributs personnalisés : champs de profil que vous définissez (par exemple,
plan_tieroupreferred_language) et que vous mettez à jour au fil du temps. Pour en savoir plus, consultez Attributs personnalisés et Définition des attributs utilisateur. - Attributs utilisateur : champs de profil standards (par exemple, e-mail, prénom et numéro de téléphone). Dans l’exemple de code, ceux-ci sont représentés par un modèle typé
UserAttributepuis mappés aux champs utilisateur de Braze.
Les fichiers utilitaires de cette section (RemoteStorage, UserAttribute et EventName Dictionary) sont des fichiers utilitaires locaux utilisés par cet exemple d’implémentation. Ce ne sont pas des classes intégrées du SDK. Ils stockent les données dérivées du payload dans UserDefaults, définissent un modèle typé pour les mises à jour utilisateur en attente et standardisent la construction du payload des événements. Pour en savoir plus sur le comportement du stockage local des données, consultez Stockage.

Les exemples de fichiers utilitaires de cette section sont spécifiques à iOS (Swift et Objective-C). Pour les approches Android et Web de journalisation des événements personnalisés et des attributs, consultez Journalisation des événements personnalisés (Android, Web) et Définition des attributs utilisateur (Android, Web).
Enregistrement des événements personnalisés
Créez le payload d’analyse en construisant un dictionnaire, en renseignant les métadonnées et en l’enregistrant à l’aide du fichier utilitaire.
- Initialisez un dictionnaire avec les métadonnées de l’événement.
- Initialisez
userDefaultspour récupérer et stocker les données d’événement. - Si un tableau existant est trouvé, ajoutez les données et enregistrez.
- Si aucun tableau n’existe, enregistrez un nouveau tableau.
func saveCustomEvent(with properties: [String: Any]? = nil) {
// 1
let customEventDictionary = Dictionary(eventName: "YOUR-EVENT-NAME", properties: properties)
// 2
let remoteStorage = RemoteStorage(storageType: .suite)
// 3
if var pendingEvents = remoteStorage.retrieve(forKey: .pendingCustomEvents) as? [[String: Any]] {
pendingEvents.append(contentsOf: [customEventDictionary])
remoteStorage.store(pendingEvents, forKey: .pendingCustomEvents)
} else {
// 4
remoteStorage.store([customEventDictionary], forKey: .pendingCustomEvents)
}
}
- (void)saveCustomEvent:(NSDictionary<NSString *, id> *)properties {
// 1
NSDictionary<NSString *, id> *customEventDictionary = [[NSDictionary alloc] initWithEventName:@"YOUR-EVENT-NAME" properties:properties];
// 2
RemoteStorage *remoteStorage = [[RemoteStorage alloc] initWithStorageType:StorageTypeSuite];
NSMutableArray *pendingEvents = [[remoteStorage retrieveForKey:RemoteStorageKeyPendingCustomEvents] mutableCopy];
// 3
if (pendingEvents) {
[pendingEvents addObject:customEventDictionary];
[remoteStorage store:pendingEvents forKey:RemoteStorageKeyPendingCustomEvents];
} else {
// 4
[remoteStorage store:@[ customEventDictionary ] forKey:RemoteStorageKeyPendingCustomEvents];
}
}
Envoi des événements personnalisés à Braze
Journalisez les données d’analyse enregistrées juste après l’initialisation du SDK.
- Parcourez les événements en attente.
- Parcourez les paires clé-valeur de chaque événement.
- Vérifiez la présence de la clé
event_name. - Ajoutez les paires clé-valeur restantes au dictionnaire
properties. - Journalisez chaque événement personnalisé.
- Supprimez les événements en attente du stockage.
func logPendingCustomEventsIfNecessary() {
let remoteStorage = RemoteStorage(storageType: .suite)
guard let pendingEvents = remoteStorage.retrieve(forKey: .pendingCustomEvents) as? [[String: Any]] else { return }
// 1
for event in pendingEvents {
var eventName: String?
var properties: [AnyHashable: Any] = [:]
// 2
for (key, value) in event {
if key == "event_name" {
// 3
if let eventNameValue = value as? String {
eventName = eventNameValue
} else {
print("Invalid type for event_name key")
}
} else {
// 4
properties[key] = value
}
}
// 5
if let eventName = eventName {
AppDelegate.braze?.logCustomEvent(name: eventName, properties: properties)
}
}
// 6
remoteStorage.removeObject(forKey: .pendingCustomEvents)
}
- (void)logPendingEventsIfNecessary {
RemoteStorage *remoteStorage = [[RemoteStorage alloc] initWithStorageType:StorageTypeSuite];
NSArray *pendingEvents = [remoteStorage retrieveForKey:RemoteStorageKeyPendingCustomEvents];
// 1
for (NSDictionary<NSString *, id> *event in pendingEvents) {
NSString *eventName = nil;
NSMutableDictionary *properties = [NSMutableDictionary dictionary];
// 2
for (NSString* key in event) {
if ([key isEqualToString:@"event_name"]) {
// 3
if ([[event objectForKey:key] isKindOfClass:[NSString class]]) {
eventName = [event objectForKey:key];
} else {
NSLog(@"Invalid type for event_name key");
}
} else {
// 4
properties[key] = event[key];
}
}
// 5
if (eventName != nil) {
[AppDelegate.braze logCustomEvent:eventName properties:properties];
}
}
// 6
[remoteStorage removeObjectForKey:RemoteStorageKeyPendingCustomEvents];
}
Enregistrement des attributs personnalisés
Créez le dictionnaire d’analyse en tant que nouveau design, puis persistez-le.
- Initialisez un dictionnaire avec les métadonnées de l’attribut.
- Initialisez
userDefaultspour récupérer et stocker les données d’attribut. - Si un tableau existant est trouvé, ajoutez les données et enregistrez.
- Si aucun tableau n’existe, enregistrez un nouveau tableau.
func saveCustomAttribute() {
// 1
let customAttributeDictionary: [String: Any] = ["YOUR-CUSTOM-ATTRIBUTE-KEY": "YOUR-CUSTOM-ATTRIBUTE-VALUE"]
// 2
let remoteStorage = RemoteStorage(storageType: .suite)
// 3
if var pendingAttributes = remoteStorage.retrieve(forKey: .pendingCustomAttributes) as? [[String: Any]] {
pendingAttributes.append(contentsOf: [customAttributeDictionary])
remoteStorage.store(pendingAttributes, forKey: .pendingCustomAttributes)
} else {
// 4
remoteStorage.store([customAttributeDictionary], forKey: .pendingCustomAttributes)
}
}
- (void)saveCustomAttribute {
// 1
NSDictionary<NSString *, id> *customAttributeDictionary = @{ @"YOUR-CUSTOM-ATTRIBUTE-KEY": @"YOUR-CUSTOM-ATTRIBUTE-VALUE" };
// 2
RemoteStorage *remoteStorage = [[RemoteStorage alloc] initWithStorageType:StorageTypeSuite];
NSMutableArray *pendingAttributes = [[remoteStorage retrieveForKey:RemoteStorageKeyPendingCustomAttributes] mutableCopy];
// 3
if (pendingAttributes) {
[pendingAttributes addObject:customAttributeDictionary];
[remoteStorage store:pendingAttributes forKey:RemoteStorageKeyPendingCustomAttributes];
} else {
// 4
[remoteStorage store:@[ customAttributeDictionary ] forKey:RemoteStorageKeyPendingCustomAttributes];
}
}
Envoi des attributs personnalisés à Braze
Journalisez les données d’analyse enregistrées juste après l’initialisation du SDK.
- Parcourez les attributs en attente.
- Parcourez chaque paire clé-valeur.
- Journalisez chaque clé et valeur d’attribut personnalisé.
- Supprimez les attributs en attente du stockage.
func logPendingCustomAttributesIfNecessary() {
let remoteStorage = RemoteStorage(storageType: .suite)
guard let pendingAttributes = remoteStorage.retrieve(forKey: .pendingCustomAttributes) as? [[String: Any]] else { return }
// 1
pendingAttributes.forEach { setCustomAttributesWith(keysAndValues: $0) }
// 4
remoteStorage.removeObject(forKey: .pendingCustomAttributes)
}
func setCustomAttributesWith(keysAndValues: [String: Any]) {
// 2
for (key, value) in keysAndValues {
// 3
if let value = value as? [String] {
setCustomAttributeArrayWithKey(key, andValue: value)
} else {
setCustomAttributeWithKey(key, andValue: value)
}
}
}
- (void)logPendingCustomAttributesIfNecessary {
RemoteStorage *remoteStorage = [[RemoteStorage alloc] initWithStorageType:StorageTypeSuite];
NSArray *pendingAttributes = [remoteStorage retrieveForKey:RemoteStorageKeyPendingCustomAttributes];
// 1
for (NSDictionary<NSString*, id> *attribute in pendingAttributes) {
[self setCustomAttributeWith:attribute];
}
// 4
[remoteStorage removeObjectForKey:RemoteStorageKeyPendingCustomAttributes];
}
- (void)setCustomAttributeWith:(NSDictionary<NSString *, id> *)keysAndValues {
// 2
for (NSString *key in keysAndValues) {
// 3
[self setCustomAttributeWith:key andValue:[keysAndValues objectForKey:key]];
}
}
Enregistrement des attributs utilisateur
Lors de l’enregistrement des attributs utilisateur, créez un objet personnalisé pour capturer le champ utilisateur en cours de mise à jour (email, first_name, phone_number, etc.). L’objet doit être compatible avec le stockage et la récupération via UserDefaults. Consultez le fichier utilitaire UserAttribute dans l’onglet Fichiers utilitaires pour un exemple.
- Initialisez un objet
UserAttributeencodé avec le type correspondant. - Initialisez
userDefaultspour récupérer et stocker les données. - Si un tableau existant est trouvé, ajoutez les données et enregistrez.
- Si aucun tableau n’existe, enregistrez un nouveau tableau.
func saveUserAttribute() {
// 1
guard let data = try? PropertyListEncoder().encode(UserAttribute.email("USER-ATTRIBUTE-VALUE")) else { return }
// 2
let remoteStorage = RemoteStorage(storageType: .suite)
// 3
if var pendingAttributes = remoteStorage.retrieve(forKey: .pendingUserAttributes) as? [Data] {
pendingAttributes.append(contentsOf: [data])
remoteStorage.store(pendingAttributes, forKey: .pendingUserAttributes)
} else {
// 4
remoteStorage.store([data], forKey: .pendingUserAttributes)
}
}
- (void)saveUserAttribute {
// 1
UserAttribute *userAttribute = [[UserAttribute alloc] initWithUserField:@"USER-ATTRIBUTE-VALUE" attributeType:UserAttributeTypeEmail];
NSError *error;
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:userAttribute requiringSecureCoding:YES error:&error];
if (error != nil) {
// log error
}
// 2
RemoteStorage *remoteStorage = [[RemoteStorage alloc] initWithStorageType:StorageTypeSuite];
NSMutableArray *pendingAttributes = [[remoteStorage retrieveForKey:RemoteStorageKeyPendingUserAttributes] mutableCopy];
// 3
if (pendingAttributes) {
[pendingAttributes addObject:data];
[remoteStorage store:pendingAttributes forKey:RemoteStorageKeyPendingUserAttributes];
} else {
// 4
[remoteStorage store:@[data] forKey:RemoteStorageKeyPendingUserAttributes];
}
}
Envoi des attributs utilisateur à Braze
Journalisez les données d’analyse enregistrées juste après l’initialisation du SDK.
- Parcourez les données
pendingAttributes. - Décodez chaque
UserAttribute. - Définissez les champs utilisateur en fonction du type d’attribut.
- Supprimez les attributs utilisateur en attente du stockage.
func logPendingUserAttributesIfNecessary() {
let remoteStorage = RemoteStorage(storageType: .suite)
guard let pendingAttributes = remoteStorage.retrieve(forKey: .pendingUserAttributes) as? [Data] else { return }
// 1
for attributeData in pendingAttributes {
// 2
guard let userAttribute = try? PropertyListDecoder().decode(UserAttribute.self, from: attributeData) else { continue }
// 3
switch userAttribute {
case .email(let email):
AppDelegate.braze?.user.set(email: email)
}
}
// 4
remoteStorage.removeObject(forKey: .pendingUserAttributes)
}
- (void)logPendingUserAttributesIfNecessary {
RemoteStorage *remoteStorage = [[RemoteStorage alloc] initWithStorageType:StorageTypeSuite];
NSArray *pendingAttributes = [remoteStorage retrieveForKey:RemoteStorageKeyPendingUserAttributes];
// 1
for (NSData *attributeData in pendingAttributes) {
NSError *error;
// 2
UserAttribute *userAttribute = [NSKeyedUnarchiver unarchivedObjectOfClass:[UserAttribute class] fromData:attributeData error:&error];
if (error != nil) {
// log error
}
// 3
if (userAttribute) {
switch (userAttribute.attributeType) {
case UserAttributeTypeEmail:
[self user].email = userAttribute.userField;
break;
}
}
}
// 4
[remoteStorage removeObjectForKey:RemoteStorageKeyPendingUserAttributes];
}
Fichier utilitaire RemoteStorage
enum RemoteStorageKey: String, CaseIterable {
// MARK: - Notification Content Extension Analytics
case pendingCustomEvents = "pending_custom_events"
case pendingCustomAttributes = "pending_custom_attributes"
case pendingUserAttributes = "pending_user_attributes"
}
enum RemoteStorageType {
case standard
case suite
}
class RemoteStorage: NSObject {
private var storageType: RemoteStorageType = .standard
private lazy var defaults: UserDefaults = {
switch storageType {
case .standard:
return .standard
case .suite:
// Use the App Group identifier you created in Step 1.
return UserDefaults(suiteName: "group.com.company.appname.xyz")!
}
}()
init(storageType: RemoteStorageType = .standard) {
self.storageType = storageType
}
func store(_ value: Any, forKey key: RemoteStorageKey) {
defaults.set(value, forKey: key.rawValue)
}
func retrieve(forKey key: RemoteStorageKey) -> Any? {
return defaults.object(forKey: key.rawValue)
}
func removeObject(forKey key: RemoteStorageKey) {
defaults.removeObject(forKey: key.rawValue)
}
func resetStorageKeys() {
for key in RemoteStorageKey.allCases {
defaults.removeObject(forKey: key.rawValue)
}
}
}
@interface RemoteStorage ()
@property (nonatomic) StorageType storageType;
@property (nonatomic, strong) NSUserDefaults *defaults;
@end
@implementation RemoteStorage
- (id)initWithStorageType:(StorageType)storageType {
if (self = [super init]) {
self.storageType = storageType;
}
return self;
}
- (void)store:(id)value forKey:(RemoteStorageKey)key {
[[self defaults] setValue:value forKey:[self rawValueForKey:key]];
}
- (id)retrieveForKey:(RemoteStorageKey)key {
return [[self defaults] objectForKey:[self rawValueForKey:key]];
}
- (void)removeObjectForKey:(RemoteStorageKey)key {
[[self defaults] removeObjectForKey:[self rawValueForKey:key]];
}
- (void)resetStorageKeys {
[[self defaults] removeObjectForKey:[self rawValueForKey:RemoteStorageKeyPendingCustomEvents]];
[[self defaults] removeObjectForKey:[self rawValueForKey:RemoteStorageKeyPendingCustomAttributes]];
[[self defaults] removeObjectForKey:[self rawValueForKey:RemoteStorageKeyPendingUserAttributes]];
}
- (NSUserDefaults *)defaults {
if (!_defaults) {
switch (self.storageType) {
case StorageTypeStandard:
_defaults = [NSUserDefaults standardUserDefaults];
break;
case StorageTypeSuite:
_defaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.company.appname.xyz"];
break;
}
}
return _defaults;
}
- (NSString*)rawValueForKey:(RemoteStorageKey)remoteStorageKey {
switch(remoteStorageKey) {
case RemoteStorageKeyPendingCustomEvents:
return @"pending_custom_events";
case RemoteStorageKeyPendingCustomAttributes:
return @"pending_custom_attributes";
case RemoteStorageKeyPendingUserAttributes:
return @"pending_user_attributes";
default:
[NSException raise:NSGenericException format:@"Unexpected FormatType."];
}
}
Fichier utilitaire UserAttribute
enum UserAttribute: Hashable {
case email(String?)
}
// MARK: - Codable
extension UserAttribute: Codable {
private enum CodingKeys: String, CodingKey {
case email
}
func encode(to encoder: Encoder) throws {
var values = encoder.container(keyedBy: CodingKeys.self)
switch self {
case .email(let email):
try values.encodeIfPresent(email, forKey: .email)
}
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
let email = try values.decodeIfPresent(String.self, forKey: .email)
self = .email(email)
}
}
@implementation UserAttribute
- (id)initWithUserField:(NSString *)userField attributeType:(UserAttributeType)attributeType {
if (self = [super init]) {
self.userField = userField;
self.attributeType = attributeType;
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:self.userField forKey:@"userField"];
[encoder encodeInteger:self.attributeType forKey:@"attributeType"];
}
- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super init]) {
self.userField = [decoder decodeObjectForKey:@"userField"];
NSInteger attributeRawValue = [decoder decodeIntegerForKey:@"attributeType"];
self.attributeType = (UserAttributeType) attributeRawValue;
}
return self;
}
@end
Fichier utilitaire EventName dictionary
extension Dictionary where Key == String, Value == Any {
init(eventName: String, properties: [String: Any]? = nil) {
self.init()
self[PushNotificationKey.eventName.rawValue] = eventName
if let properties = properties {
for (key, value) in properties {
self[key] = value
}
}
}
}
@implementation NSMutableDictionary (Helper)
+ (instancetype)dictionaryWithEventName:(NSString *)eventName
properties:(NSDictionary *)properties {
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[@"event_name"] = eventName;
if (properties) {
for (id key in properties) {
dict[key] = properties[key];
}
}
return dict;
}
@end
Analyser les résultats
Utilisez la surface de reporting correspondant à la catégorie d’analyse :
| Catégorie d’analyse | Où consulter dans Braze |
|---|---|
| Analyse native des notifications push | Pour afficher les indicateurs d’ouverture push au niveau de la campagne, accédez à la page Campaign Analytics de votre Campaign push. Pour les définitions des indicateurs, consultez Ouvertures influencées. Pour créer des vues d’analyse personnalisées, accédez à Analytics > Report Builder (New). Pour les étapes de navigation, consultez Générateur de rapports. Pour les schémas d’événements au niveau de l’entrepôt de données, consultez Événements d’engagement liés aux messages. |
| Événements et attributs personnalisés | Pour afficher les tendances des événements personnalisés, accédez à Analytics > Custom Events Report. Pour plus de détails, consultez Événements personnalisés. Pour inspecter les valeurs au niveau utilisateur, accédez à la page Search Users et ouvrez un profil. Pour les étapes, consultez Profils utilisateur. Pour filtrer les audiences par ces valeurs, accédez à Audience > Segments. Pour les étapes de navigation, consultez Créer un Segment et les options de filtre dans Filtres de segmentation. |
Pour la création de rapports personnalisés, consultez Générateur de rapports.