Análisis push y registro de eventos personalizados
Esta página cubre los siguientes flujos de trabajo: análisis nativos de push (aperturas, Influenced Opens e informes de Campaign) y registro de datos personalizados (eventos personalizados y atributos) a partir de cargas útiles push. Usa esta guía para identificar qué flujo de trabajo se aplica a tu caso de uso y sigue los pasos para tu plataforma.
Requisitos previos
Antes de empezar, completa la integración inicial de notificaciones push para tu plataforma:
Análisis nativos de push frente a registro de eventos personalizados
Los siguientes flujos de trabajo tienen distintas superficies de informes.
| Categoría de análisis | Descripción | Dónde aparece |
|---|---|---|
| Análisis nativos de push | Métricas de push como aperturas e Influenced Opens, vinculadas a Campaigns de push en Braze | Análisis de Campaigns de push, eventos de participación en mensajes de Currents, generador de informes |
| Eventos y atributos personalizados | Análisis que defines y registras a través de métodos del SDK o del endpoint /users/track |
Perfiles de usuario, segmentación, Campaigns y Canvas basados en acciones, análisis de eventos personalizados |

Registrar un evento personalizado (como push_notification_opened) no es lo mismo que el seguimiento nativo de aperturas de push en Braze. Los eventos personalizados no alimentan las métricas nativas de aperturas de Campaigns de push ni la atribución de push.
Lo que Braze registra automáticamente
Cuando tu integración de SDK está configurada, Braze registra automáticamente los datos principales de interacción del canal, incluyendo aperturas push e Influenced Opens. No se requiere código adicional para el análisis estándar de push. Para consultar una lista completa de los datos recopilados automáticamente, consulta Recopilación de datos del SDK.
Para más detalles, consulta lo siguiente:
- Recopilación de datos del SDK para una lista completa de datos recopilados automáticamente y opcionales.
- Influenced Opens para saber cómo Braze calcula las Influenced Opens.
- Eventos de participación en mensajes para esquemas de eventos posteriores en Currents.
Conservar los análisis push nativos con el manejo push personalizado
Es posible que utilices un controlador push personalizado cuando necesites integrar varios proveedores push, procesar datos de carga útil adicionales o implementar una lógica de visualización de notificaciones personalizada. Si utilizas un controlador push personalizado, debes seguir pasando las cargas útiles push a los métodos del SDK de Braze. Esto permite a Braze extraer los datos de seguimiento integrados y registrar los análisis push nativos (aperturas, Influenced Opens y métricas de entrega).
Si tienes un FirebaseMessagingService personalizado, llama a BrazeFirebaseMessagingService.handleBrazeRemoteMessage(...) dentro de tu método onMessageReceived. Ten en cuenta que tu subclase de FirebaseMessagingService debe terminar la ejecución en 9 segundos desde la invocación para evitar ser marcada o terminada por el sistema 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.
}
}
}
Para ver un ejemplo de implementación completo, consulta la aplicación de ejemplo de push Firebase del SDK de Braze para Android.
En una integración push manual, reenvía las devoluciones de llamada de notificaciones en segundo plano y de notificaciones de usuario a Braze.
Notificaciones en segundo plano:
if let braze = AppDelegate.braze, braze.notifications.handleBackgroundNotification(
userInfo: userInfo,
fetchCompletionHandler: completionHandler
) {
return
}
completionHandler(.noData)
Respuestas a notificaciones de usuario:
if let braze = AppDelegate.braze, braze.notifications.handleUserNotification(
response: response,
withCompletionHandler: completionHandler
) {
return
}
completionHandler()
Notificaciones en primer plano:
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])
}
}
Para ver un ejemplo de implementación completo, consulta el ejemplo de push manual del SDK Swift de Braze (AppDelegate.swift).
Para notificaciones push web, configura tu prestador de servicios y la inicialización del SDK como se describe en Notificaciones push web.
Para más ejemplos de código, consulta el repositorio del SDK Web de Braze.
Registro de datos personalizados desde cargas útiles push
Utiliza esta sección cuando necesites registrar datos adicionales de los pares clave-valor de la carga útil push, como eventos personalizados o atributos vinculados a tu lógica de negocio.
Para más información sobre eventos personalizados, consulta Eventos personalizados. Para registrar eventos personalizados a través de métodos del SDK, consulta Registro de eventos personalizados.
Opción A: Registrar con el endpoint /users/track
Puedes registrar análisis en tiempo real llamando al endpoint /users/track.
Para identificar el perfil de usuario, incluye braze_id en los pares clave-valor de tu carga útil push.

Pasar braze_id solo identifica el perfil. Aún necesitas lógica de implementación que lea los valores de la carga útil y envíe la solicitud /users/track con los eventos o atributos que deseas registrar.
Opción B: Registrar con métodos del SDK después del lanzamiento de la aplicación
También puedes guardar los datos de la carga útil de forma local y registrar eventos personalizados y atributos a través de métodos del SDK después de que la aplicación se inicialice. Este enfoque es común en flujos de extensión de contenido de notificaciones, donde los datos de análisis se persisten primero y se envían en el siguiente lanzamiento de la aplicación.

Los análisis no se envían a Braze hasta que la aplicación se lance. Dependiendo de tu configuración de descarte, puede haber un retraso entre el momento en que el usuario descarta la notificación y el momento en que la aplicación se abre y envía los análisis.
Registro desde una extensión de contenido de notificación (Swift)
Los siguientes pasos explican cómo guardar y enviar eventos personalizados, atributos personalizados y atributos de usuario desde una extensión de contenido de notificación en Swift.
Paso 1: Configura los grupos de aplicaciones en Xcode
En Xcode, añade la capacidad App Groups al destino de tu aplicación principal. Activa App Groups y haz clic en + para añadir un nuevo grupo. Utiliza el identificador de paquete de tu aplicación para crear el identificador de grupo (por ejemplo, group.com.company.appname.xyz). Activa App Groups tanto para el destino de tu aplicación principal como para el destino de la extensión de contenido.

Paso 2: Elige qué registrar
Antes de implementar los fragmentos de código, elige qué categoría de análisis quieres registrar:
- Eventos personalizados: acciones que los usuarios realizan (por ejemplo, completar un flujo o tocar un elemento específico de la interfaz). Utiliza eventos personalizados para desencadenantes basados en acciones, segmentación y análisis de eventos. Para más información, consulta Eventos personalizados y Registro de eventos personalizados.
- Atributos personalizados: campos del perfil que tú defines (por ejemplo,
plan_tieropreferred_language) y actualizas con el tiempo. Para más información, consulta Atributos personalizados y Configuración de atributos de usuario. - Atributos de usuario: campos estándar del perfil (por ejemplo, correo electrónico, nombre y número de teléfono). En el código de ejemplo, estos se representan mediante un modelo tipado
UserAttributey luego se asignan a los campos de usuario de Braze.
Los archivos auxiliares en esta sección (RemoteStorage, UserAttribute y EventName Dictionary) son archivos de utilidad locales que esta implementación de ejemplo utiliza. No son clases integradas del SDK. Almacenan datos derivados de la carga útil en UserDefaults, definen un modelo tipado para actualizaciones de usuario pendientes y estandarizan la construcción de cargas útiles de eventos. Para más información sobre el comportamiento del almacenamiento local de datos, consulta Almacenamiento.

Los ejemplos de archivos auxiliares en esta sección son específicos de iOS (Swift y Objective-C). Para enfoques en Android y Web sobre el registro de eventos personalizados y atributos, consulta Registro de eventos personalizados (Android, Web) y Configuración de atributos de usuario (Android, Web).
Guardar eventos personalizados
Crea la carga útil de análisis construyendo un diccionario, rellenando los metadatos y guardándola con el archivo auxiliar.
- Inicializa un diccionario con los metadatos del evento.
- Inicializa
userDefaultspara recuperar y almacenar los datos del evento. - Si se encuentra un array existente, añade y guarda.
- Si no existe ningún array, guarda uno nuevo.
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];
}
}
Enviar eventos personalizados a Braze
Registra los análisis guardados justo después de la inicialización del SDK.
- Itera sobre los eventos pendientes.
- Itera sobre los pares clave-valor de cada evento.
- Busca la clave
event_name. - Añade los pares clave-valor restantes al diccionario
properties. - Registra cada evento personalizado.
- Elimina los eventos pendientes del almacenamiento.
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];
}
Guardar atributos personalizados
Crea el diccionario de análisis como un nuevo diseño y luego persístelo.
- Inicializa un diccionario con los metadatos del atributo.
- Inicializa
userDefaultspara recuperar y almacenar los datos del atributo. - Si se encuentra un array existente, añade y guarda.
- Si no existe ningún array, guarda uno nuevo.
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];
}
}
Enviar atributos personalizados a Braze
Registra los análisis guardados justo después de la inicialización del SDK.
- Itera sobre los atributos pendientes.
- Itera sobre cada par clave-valor.
- Registra cada clave y valor de atributo personalizado.
- Elimina los atributos pendientes del almacenamiento.
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]];
}
}
Guardar atributos de usuario
Al guardar atributos de usuario, crea un objeto personalizado para capturar qué campo de usuario se está actualizando (email, first_name, phone_number, etc.). El objeto debe ser compatible con el almacenamiento y la recuperación a través de UserDefaults. Consulta el archivo auxiliar UserAttribute en la pestaña Archivos auxiliares para ver un ejemplo.
- Inicializa un objeto
UserAttributecodificado con el tipo correspondiente. - Inicializa
userDefaultspara recuperar y almacenar los datos. - Si se encuentra un array existente, añade y guarda.
- Si no existe ningún array, guarda uno nuevo.
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];
}
}
Enviar atributos de usuario a Braze
Registra los análisis guardados justo después de la inicialización del SDK.
- Itera sobre los datos de
pendingAttributes. - Decodifica cada
UserAttribute. - Establece los campos de usuario según el tipo de atributo.
- Elimina los atributos de usuario pendientes del almacenamiento.
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];
}
Archivo auxiliar 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."];
}
}
Archivo auxiliar 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
Archivo auxiliar del diccionario EventName
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
Análisis de resultados
Utiliza la superficie de informes que coincida con la categoría de análisis:
| Categoría de análisis | Dónde verlo en Braze |
|---|---|
| Análisis nativos de push | Para ver las métricas de apertura de push a nivel de Campaign, navega a la página Campaign Analytics de tu Campaign de push. Para las definiciones de las métricas, consulta Influenced Opens. Para crear vistas de análisis personalizadas, navega a Analytics > Report Builder (New). Para los pasos de navegación, consulta Generador de informes. Para los esquemas de eventos a nivel de almacén de datos, consulta Eventos de participación en mensajes. |
| Eventos y atributos personalizados | Para ver las tendencias de eventos personalizados, navega a Analytics > Custom Events Report. Para más detalles, consulta Eventos personalizados. Para inspeccionar valores a nivel de usuario, navega a la página Search Users y abre un perfil. Para los pasos, consulta Perfiles de usuario. Para filtrar audiencias por estos valores, navega a Audience > Segments. Para los pasos de navegación, consulta Crear un Segment y las opciones de filtro en Filtros de segmentación. |
Para la creación de informes personalizados, consulta Generador de informes.