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 campagne) 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.
Conditions préalables
Avant de commencer, effectuez l’intégration initiale des notifications push pour votre plateforme :
Analytique push native vs. journalisation d’événements personnalisés
Les workflows suivants ont chacun des surfaces de reporting différentes.
| Catégorie d’analytique | Description | Où elle apparaît |
|---|---|---|
| Analytique push native | Indicateurs push tels que les ouvertures et les ouvertures influencées, liés aux campagnes push de Braze | Analytique des campagnes push, événements d’engagement lié aux messages Currents, générateur de rapports |
| Événements personnalisés et attributs | Données analytiques que vous définissez et journalisez via les méthodes du SDK ou l’endpoint /users/track |
Profils utilisateur, segmentation, campagnes et Canvas basés sur des actions, analytique des événements personnalisés |
Journaliser un événement personnalisé (tel que push_notification_opened) n’est pas la même chose que le suivi natif des ouvertures push de Braze. Les événements personnalisés ne renseignent pas les indicateurs natifs d’ouverture des campagnes 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 de base du canal, y compris les ouvertures push et les ouvertures influencées. Aucun code supplémentaire n’est nécessaire pour l’analytique push standard. Pour une liste complète des données collectées automatiquement, consultez Collecte de données du SDK.
Pour plus de détails, consultez les ressources suivantes :
- Collecte de données du SDK pour une liste complète des données collectées automatiquement et facultatives.
- Ouvertures influencées pour comprendre comment Braze calcule les ouvertures influencées.
- Événements d’engagement lié aux messages pour les schémas d’événements en aval dans Currents.
Préserver l’analytique push native avec un gestionnaire push personnalisé
Vous pouvez utiliser un gestionnaire push personnalisé lorsque vous devez intégrer plusieurs fournisseurs 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 push personnalisé, vous devez tout de même transmettre les payloads push aux méthodes du SDK de Braze. Cela permet à Braze d’extraire les données de suivi intégrées et de journaliser l’analytique push native (ouvertures, ouvertures influencées et indicateurs de distribution).
Si vous avez 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 terminée par le système Android.
1
2
3
4
5
6
7
8
9
10
11
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 :
1
2
3
4
5
6
7
if let braze = AppDelegate.braze, braze.notifications.handleBackgroundNotification(
userInfo: userInfo,
fetchCompletionHandler: completionHandler
) {
return
}
completionHandler(.noData)
Réponses aux notifications utilisateur :
1
2
3
4
5
6
7
if let braze = AppDelegate.braze, braze.notifications.handleUserNotification(
response: response,
withCompletionHandler: completionHandler
) {
return
}
completionHandler()
Notifications au premier plan :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 le 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.
Journaliser des données personnalisées à partir des payloads push
Utilisez cette section lorsque vous devez journaliser des données supplémentaires à partir des paires clé-valeur du payload 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 Journaliser des événements personnalisés.
Option A : Journaliser avec l’endpoint /users/track
Vous pouvez journaliser des données analytiques en temps réel en appelant l’endpoint /users/track.
Pour identifier le profil utilisateur, incluez braze_id dans les paires clé-valeur de votre payload push.
Transmettre braze_id permet uniquement d’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 et 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 analytiques sont d’abord persistées puis envoyées au prochain lancement de l’application.
Les données analytiques 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 analytiques.
Journaliser 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’analytique que vous souhaitez journaliser :
- Événements personnalisés : Actions effectuées par les utilisateurs (par exemple, compléter un flux ou appuyer sur un élément d’interface spécifique). Utilisez les événements personnalisés pour les déclencheurs basés sur des actions, la segmentation et l’analytique des événements. Pour plus d’informations, consultez Événements personnalisés et Journaliser des événements personnalisés.
- Attributs personnalisés : Champs de profil que vous définissez (par exemple,
plan_tieroupreferred_language) et mettez à jour au fil du temps. Pour plus d’informations, consultez Attributs personnalisés et Définir les attributs utilisateur. - Attributs utilisateur : Champs de profil standard (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 au 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 d’événement. Pour plus d’informations 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 Journaliser des événements personnalisés (Android, Web) et Définir les attributs utilisateur (Android, Web).
Enregistrer des événements personnalisés
Créez le payload analytique en construisant un dictionnaire, en renseignant les métadonnées et en l’enregistrant avec le 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-y les données et enregistrez.
- Si aucun tableau n’existe, enregistrez un nouveau tableau.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- (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];
}
}
Envoyer des événements personnalisés à Braze
Journalisez les données analytiques 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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
- (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];
}
Enregistrer des attributs personnalisés
Créez le dictionnaire analytique de zéro, 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-y les données et enregistrez.
- Si aucun tableau n’existe, enregistrez un nouveau tableau.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- (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];
}
}
Envoyer des attributs personnalisés à Braze
Journalisez les données analytiques 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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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)
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- (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]];
}
}
Enregistrer des attributs utilisateur
Lors de l’enregistrement des attributs utilisateur, créez un objet personnalisé pour capturer quel champ utilisateur est mis à 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-y les données et enregistrez.
- Si aucun tableau n’existe, enregistrez un nouveau tableau.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- (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];
}
}
Envoyer des attributs utilisateur à Braze
Journalisez les données analytiques 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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
- (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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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)
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
@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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@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
1
2
3
4
5
6
7
8
9
10
11
12
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
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@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’analytique :
| Catégorie d’analytique | Où consulter dans Braze |
|---|---|
| Analytique push native | Pour consulter les indicateurs d’ouverture push au niveau de la campagne, accédez à la page Analytique de la campagne de votre campagne push. Pour les définitions des indicateurs, consultez Ouvertures influencées. Pour créer des vues analytiques personnalisées, accédez à Analytique > Générateur de rapports (Nouveau). 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é aux messages. |
| Événements personnalisés et attributs | Pour consulter les tendances des événements personnalisés, accédez à Analytique > Rapport des événements personnalisés. Pour plus de détails, consultez Événements personnalisés. Pour inspecter les valeurs au niveau utilisateur, accédez à la page Rechercher des utilisateurs 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.
Modifier cette page sur GitHub