{"_id":"5ab565f212d24900747242ae","category":{"_id":"5ab565f112d249007472429b","version":"5ab565f112d2490074724298","project":"57c88b374434350e00509d7f","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2014-11-05T21:53:37.386Z","from_sync":false,"order":2,"slug":"reference","title":"Reference"},"parentDoc":null,"project":"57c88b374434350e00509d7f","user":"55e5ba046015ce1900eadb8e","version":{"_id":"5ab565f112d2490074724298","project":"57c88b374434350e00509d7f","__v":1,"createdAt":"2018-03-23T20:39:13.299Z","releaseDate":"2018-03-23T20:39:13.299Z","categories":["5ab565f112d2490074724299","5ab565f112d249007472429a","5ab565f112d249007472429b","5ab565f112d249007472429c"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"3.6.0","version":"3.6.0"},"githubsync":"","__v":0,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2016-03-21T09:58:37.161Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":12,"body":"Events are an important part of monitoring the health of your app and providing your users with the best experience possible. Tracking key actions allows you to view funnels and gain important metrics.\n\n####Automatic Events\n\nOnce you initialize the SDK, Primer automatically tracks some key events for you, including but not limited to: install, app launch, session start, and the presentation of onboarding flows and screens.\n\n####Custom Events\n\nTo accompany our automatic events, we let you track your own custom ones, so you can make them part of your analytical process on the Dashboard. There are no limitations on what you track, and no setup is necessary for new event names or parameters, just pass in a string for the name and a dictionary of parameters, and they all get associated with the event.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"NSString *name = :::at:::\\\"Time Travel Occurred\\\";\\nNSDictionary *parameters = @{@\\\"Date\\\": @\\\"October 23, 2015\\\"};\\n\\n[Primer trackEventWithName:name parameters:parameters];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"let name = \\\"Time Travel Occurred\\\"\\nlet parameters: [String : Any] = [\\\"Date\\\": \\\"October 23, 2015\\\"]\\n\\nPrimer.trackEvent(withName: name, parameters:parameters)\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\n####Sending Events to Mixpanel\n\nIf you use Mixpanel for your event analysis, Primer can send the events used to track the success of your new onboarding directly in your Mixpanel account. For most Mixpanel setups, this is as easy as contacting your Primer service rep and providing the following information: Mixpanel Token, and Mixpanel Distinct ID. If you are using your User ID, iOS IFA, or iOS IFV as your distinct ID, this integration can be enabled without any code changes and take effect immediately.\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"Determining your distinct ID\",\n  \"body\": \"This is the type of the ID you are referencing when calling Mixpanel's `createAlias:` or `identify:` methods. You can read more about identifying users in Mixpanel's <a href=\\\"https://mixpanel.com/help/reference/ios\\\" target=\\\"_blank\\\">iOS Reference Guide</a> and <a href=\\\"https://mixpanel.com/help/questions/articles/assigning-your-own-unique-ids-to-users\\\" target=\\\"_blank\\\">User Identify Guide</a>.\"\n}\n[/block]\nIf you are specifying another ID value, such as a Parse anonymous ID, then you'll need to send that value to Primer so we can use it when sending events to Mixpanel. To do so, attach a property to your Primer user called `mixpanel_distinct_id` with the value of that user's Mixpanel distinct ID, as soon as you have access to it, and you have initialized the Primer SDK:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"[Primer appendUserProperties:@{@\\\"mixpanel_distinct_id\\\": @\\\"abcd1234\\\"}];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"Primer.appendUserProperties([\\\"mixpanel_distinct_id\\\": \\\"abcd1234\\\"])\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\nPlease get in contact with your Primer service rep or email support@goprimer.com to enable sending your events to Mixpanel!\n\n####Local Event Forwarding\n\nIn case you'd like to get notified about one of our automatic events being triggered we forward them through the `NSNotification` system. All you have to do is register an observer for `PMREventFiredNotification` then parse the user information dictionary to get the event's type, name, and parameters (using `PMREventNotificationTypeKey`, `PMREventNotificationNameKey`, `PMREventNotificationParametersKey` respectively).\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Register the observer\\n\\n[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePrimerEventFired:) name:PMREventFiredNotification object:nil];\\n\\n// Handle the notification\\n\\n- (void)handlePrimerEventFired:(NSNotification *)notification {\\n    NSString *type = [notification.userInfo objectForKey:PMREventNotificationTypeKey];\\n    if ([type isEqualToString:PMRFlowStartedEvent]) {\\n        NSLog(@\\\"Primer Flow started.\\\");\\n    }\\n}\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"// Register the observer\\n\\nNotificationCenter.default.addObserver(self, selector: #selector(AppDelegate.handlePrimerEventFired(notification:)), name: NSNotification.Name.PMREventFired, object: nil)\\n\\n// Handle the notification\\n\\n@objc func handlePrimerEventFired(notification: NSNotification) {\\n    let type = notification.userInfo?[PMREventNotificationTypeKey] as? String\\n    if type == PMRFlowStartedEvent {\\n        print(\\\"Primer Flow started.\\\")\\n    }\\n}\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\nThese event types trigger a notification:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Event\",\n    \"h-1\": \"Type key\",\n    \"0-0\": \"Session Started\",\n    \"0-1\": \"PMRSessionStartedEvent\",\n    \"0-2\": \"When a new session has started.\",\n    \"h-2\": \"Triggered\",\n    \"1-0\": \"Signup\",\n    \"2-0\": \"Login\",\n    \"4-0\": \"Logout\",\n    \"5-0\": \"Flow Started\",\n    \"6-0\": \"Flow Completed\",\n    \"8-0\": \"Screen Displayed\",\n    \"9-0\": \"Action Tapped\",\n    \"1-1\": \"PMRSignupEvent\",\n    \"2-1\": \"PMRLoginEvent\",\n    \"4-1\": \"PMRLogoutEvent\",\n    \"5-1\": \"PMRFlowStartedEvent\",\n    \"6-1\": \"PMRFlowCompletedEvent\",\n    \"8-1\": \"PMRScreenDisplayedEvent\",\n    \"9-1\": \"PMRActionTappedEvent\",\n    \"1-2\": \"When a user gets signed up.\",\n    \"2-2\": \"When a user gets logged in.\",\n    \"4-2\": \"When a user gets logged out.\",\n    \"5-2\": \"When a Primer Flow has started.\",\n    \"6-2\": \"When a Primer Flow has completed.\",\n    \"8-2\": \"When a Primer Flow's screen gets displayed.\",\n    \"9-2\": \"When an action is tapped on a Primer screen.\",\n    \"10-1\": \"PMRPermissionRequestedEvent\",\n    \"11-1\": \"PMRPermissionGrantedEvent\",\n    \"12-1\": \"PMRPermissionDeniedEvent\",\n    \"13-1\": \"PMRPermissionRestrictedEvent\",\n    \"14-1\": \"PMRPurchasedEvent\",\n    \"15-1\": \"PMRSubscribedEvent\",\n    \"16-1\": \"PMRInAppPurchaseCancelledEvent\",\n    \"17-1\": \"PMRInAppPurchaseRestrictedEvent\",\n    \"18-1\": \"PMRInAppPurchaseFailedEvent\",\n    \"18-2\": \"When an In-App Purchase fails.\",\n    \"17-2\": \"When a restriction blocks an In-App Purchase.\",\n    \"16-2\": \"When an In-App Purchase is cancelled.\",\n    \"15-2\": \"When an IAP subscription is purchased.\",\n    \"14-2\": \"When an IAP product is purchased.\",\n    \"13-2\": \"When a restriction blocks a permission request.\",\n    \"12-2\": \"When a permission gets denied.\",\n    \"11-2\": \"When a permission gets granted.\",\n    \"10-2\": \"When a permission is requested.\",\n    \"10-0\": \"Permission Requested\",\n    \"11-0\": \"Permission Granted\",\n    \"12-0\": \"Permission Denied\",\n    \"13-0\": \"Permission Restricted\",\n    \"14-0\": \"IAP Purchased\",\n    \"15-0\": \"IAP Subscribed\",\n    \"16-0\": \"IAP Cancelled\",\n    \"17-0\": \"IAP Restricted\",\n    \"18-0\": \"IAP Failed\",\n    \"3-0\": \"Facebook Login\",\n    \"3-1\": \"PMRFacebookLogin\",\n    \"3-2\": \"When a user gets logged in with Facebook.\",\n    \"7-0\": \"Flow Skipped\",\n    \"7-1\": \"PMRFlowSkipped\",\n    \"7-2\": \"When a Primer Flow is skipped (for other reasons than it being empty).\"\n  },\n  \"cols\": 3,\n  \"rows\": 19\n}\n[/block]\n####Logging\n\nIf you are interested in more internal events and actions of the SDK we provide a logging system that prints different levels of information into the developer console. Possible logging levels are `None`, `Error`, `Warning`, `lnfo`, and `Debug`. The default level of logging for debug builds is `Warning` and for live apps it's `None`. You can override this by setting a value directly:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"[Primer setLoggingLevel:PMRLoggingLevelInfo];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"Primer.setLoggingLevel(.info)\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\nHere's what kind of information each level provides:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Level\",\n    \"h-1\": \"Information\",\n    \"0-0\": \"Error\",\n    \"1-0\": \"Warning\",\n    \"2-0\": \"Info\",\n    \"3-0\": \"Debug\",\n    \"0-1\": \"Error logs are about events that have a high impact, possible blocking the SDK from functioning.\\n They help you know when the integration is not set up properly.\",\n    \"1-1\": \"Warning logs are important messages that influence the intended and correct behaviour of the SDK.\\n They help you know when you could improve the way you use the SDK.\",\n    \"2-1\": \"Info logs are shedding light on the internal actions of the SDK.\\n They help you know what is happening at all moments.\",\n    \"3-1\": \"Debug logs are revealing verbose information about the internal actions of the SDK.\\n They help you debug specific issues around SDK behaviour.\"\n  },\n  \"cols\": 2,\n  \"rows\": 4\n}\n[/block]","excerpt":"","slug":"event-tracking","type":"basic","title":"Event Tracking"}
Events are an important part of monitoring the health of your app and providing your users with the best experience possible. Tracking key actions allows you to view funnels and gain important metrics. ####Automatic Events Once you initialize the SDK, Primer automatically tracks some key events for you, including but not limited to: install, app launch, session start, and the presentation of onboarding flows and screens. ####Custom Events To accompany our automatic events, we let you track your own custom ones, so you can make them part of your analytical process on the Dashboard. There are no limitations on what you track, and no setup is necessary for new event names or parameters, just pass in a string for the name and a dictionary of parameters, and they all get associated with the event. [block:code] { "codes": [ { "code": "NSString *name = @\"Time Travel Occurred\";\nNSDictionary *parameters = @{@\"Date\": @\"October 23, 2015\"};\n\n[Primer trackEventWithName:name parameters:parameters];", "language": "objectivec" }, { "code": "let name = \"Time Travel Occurred\"\nlet parameters: [String : Any] = [\"Date\": \"October 23, 2015\"]\n\nPrimer.trackEvent(withName: name, parameters:parameters)", "language": "swift" } ] } [/block] ####Sending Events to Mixpanel If you use Mixpanel for your event analysis, Primer can send the events used to track the success of your new onboarding directly in your Mixpanel account. For most Mixpanel setups, this is as easy as contacting your Primer service rep and providing the following information: Mixpanel Token, and Mixpanel Distinct ID. If you are using your User ID, iOS IFA, or iOS IFV as your distinct ID, this integration can be enabled without any code changes and take effect immediately. [block:callout] { "type": "info", "title": "Determining your distinct ID", "body": "This is the type of the ID you are referencing when calling Mixpanel's `createAlias:` or `identify:` methods. You can read more about identifying users in Mixpanel's <a href=\"https://mixpanel.com/help/reference/ios\" target=\"_blank\">iOS Reference Guide</a> and <a href=\"https://mixpanel.com/help/questions/articles/assigning-your-own-unique-ids-to-users\" target=\"_blank\">User Identify Guide</a>." } [/block] If you are specifying another ID value, such as a Parse anonymous ID, then you'll need to send that value to Primer so we can use it when sending events to Mixpanel. To do so, attach a property to your Primer user called `mixpanel_distinct_id` with the value of that user's Mixpanel distinct ID, as soon as you have access to it, and you have initialized the Primer SDK: [block:code] { "codes": [ { "code": "[Primer appendUserProperties:@{@\"mixpanel_distinct_id\": @\"abcd1234\"}];", "language": "objectivec" }, { "code": "Primer.appendUserProperties([\"mixpanel_distinct_id\": \"abcd1234\"])", "language": "swift" } ] } [/block] Please get in contact with your Primer service rep or email support@goprimer.com to enable sending your events to Mixpanel! ####Local Event Forwarding In case you'd like to get notified about one of our automatic events being triggered we forward them through the `NSNotification` system. All you have to do is register an observer for `PMREventFiredNotification` then parse the user information dictionary to get the event's type, name, and parameters (using `PMREventNotificationTypeKey`, `PMREventNotificationNameKey`, `PMREventNotificationParametersKey` respectively). [block:code] { "codes": [ { "code": "// Register the observer\n\n[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePrimerEventFired:) name:PMREventFiredNotification object:nil];\n\n// Handle the notification\n\n- (void)handlePrimerEventFired:(NSNotification *)notification {\n NSString *type = [notification.userInfo objectForKey:PMREventNotificationTypeKey];\n if ([type isEqualToString:PMRFlowStartedEvent]) {\n NSLog(@\"Primer Flow started.\");\n }\n}", "language": "objectivec" }, { "code": "// Register the observer\n\nNotificationCenter.default.addObserver(self, selector: #selector(AppDelegate.handlePrimerEventFired(notification:)), name: NSNotification.Name.PMREventFired, object: nil)\n\n// Handle the notification\n\n@objc func handlePrimerEventFired(notification: NSNotification) {\n let type = notification.userInfo?[PMREventNotificationTypeKey] as? String\n if type == PMRFlowStartedEvent {\n print(\"Primer Flow started.\")\n }\n}", "language": "swift" } ] } [/block] These event types trigger a notification: [block:parameters] { "data": { "h-0": "Event", "h-1": "Type key", "0-0": "Session Started", "0-1": "PMRSessionStartedEvent", "0-2": "When a new session has started.", "h-2": "Triggered", "1-0": "Signup", "2-0": "Login", "4-0": "Logout", "5-0": "Flow Started", "6-0": "Flow Completed", "8-0": "Screen Displayed", "9-0": "Action Tapped", "1-1": "PMRSignupEvent", "2-1": "PMRLoginEvent", "4-1": "PMRLogoutEvent", "5-1": "PMRFlowStartedEvent", "6-1": "PMRFlowCompletedEvent", "8-1": "PMRScreenDisplayedEvent", "9-1": "PMRActionTappedEvent", "1-2": "When a user gets signed up.", "2-2": "When a user gets logged in.", "4-2": "When a user gets logged out.", "5-2": "When a Primer Flow has started.", "6-2": "When a Primer Flow has completed.", "8-2": "When a Primer Flow's screen gets displayed.", "9-2": "When an action is tapped on a Primer screen.", "10-1": "PMRPermissionRequestedEvent", "11-1": "PMRPermissionGrantedEvent", "12-1": "PMRPermissionDeniedEvent", "13-1": "PMRPermissionRestrictedEvent", "14-1": "PMRPurchasedEvent", "15-1": "PMRSubscribedEvent", "16-1": "PMRInAppPurchaseCancelledEvent", "17-1": "PMRInAppPurchaseRestrictedEvent", "18-1": "PMRInAppPurchaseFailedEvent", "18-2": "When an In-App Purchase fails.", "17-2": "When a restriction blocks an In-App Purchase.", "16-2": "When an In-App Purchase is cancelled.", "15-2": "When an IAP subscription is purchased.", "14-2": "When an IAP product is purchased.", "13-2": "When a restriction blocks a permission request.", "12-2": "When a permission gets denied.", "11-2": "When a permission gets granted.", "10-2": "When a permission is requested.", "10-0": "Permission Requested", "11-0": "Permission Granted", "12-0": "Permission Denied", "13-0": "Permission Restricted", "14-0": "IAP Purchased", "15-0": "IAP Subscribed", "16-0": "IAP Cancelled", "17-0": "IAP Restricted", "18-0": "IAP Failed", "3-0": "Facebook Login", "3-1": "PMRFacebookLogin", "3-2": "When a user gets logged in with Facebook.", "7-0": "Flow Skipped", "7-1": "PMRFlowSkipped", "7-2": "When a Primer Flow is skipped (for other reasons than it being empty)." }, "cols": 3, "rows": 19 } [/block] ####Logging If you are interested in more internal events and actions of the SDK we provide a logging system that prints different levels of information into the developer console. Possible logging levels are `None`, `Error`, `Warning`, `lnfo`, and `Debug`. The default level of logging for debug builds is `Warning` and for live apps it's `None`. You can override this by setting a value directly: [block:code] { "codes": [ { "code": "[Primer setLoggingLevel:PMRLoggingLevelInfo];", "language": "objectivec" }, { "code": "Primer.setLoggingLevel(.info)", "language": "swift" } ] } [/block] Here's what kind of information each level provides: [block:parameters] { "data": { "h-0": "Level", "h-1": "Information", "0-0": "Error", "1-0": "Warning", "2-0": "Info", "3-0": "Debug", "0-1": "Error logs are about events that have a high impact, possible blocking the SDK from functioning.\n They help you know when the integration is not set up properly.", "1-1": "Warning logs are important messages that influence the intended and correct behaviour of the SDK.\n They help you know when you could improve the way you use the SDK.", "2-1": "Info logs are shedding light on the internal actions of the SDK.\n They help you know what is happening at all moments.", "3-1": "Debug logs are revealing verbose information about the internal actions of the SDK.\n They help you debug specific issues around SDK behaviour." }, "cols": 2, "rows": 4 } [/block]