{"_id":"5ab565f212d24900747242ad","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,"user":"55e5ba046015ce1900eadb8e","project":"57c88b374434350e00509d7f","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"},"__v":0,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2016-03-21T09:58:29.999Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":11,"body":"The SDK allows you to manage your user's state, properties, permissions, and purchases with ease. It's important to note that Primer does not provide a user storage system; you should still implement that functionality yourself.\n\n####Requiring Login\n\nBy default the SDK requires your users to log in, so the onboarding experience will be presented each time they launch the app until they either sign up or log in. If your app does not require users to have an account, you can turn this off, thus only showing the Primer experience once, the first time the app is installed and launched.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"[Primer setRequiresLogin:NO];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"Primer.setRequiresLogin(false)\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\n####State Management\n\nThe Primer iOS SDK automatically manages the user's state when it comes to signing up and logging in through the Primer experience's Signup or Login flows. However there might be other situations when your app allows users to sign up or log in. In these cases, you should notify the SDK about user state changes to appropriately track their behavior and manage their properties.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Sign a user up manually\\n\\n[Primer signUpUserWithID::::at:::\\\"user1234\\\"];\\n\\n// Log a user in manually\\n\\n[Primer logInUserWithID:@\\\"user1234\\\"];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"// Sign a user up manually\\n\\nPrimer.signUpUser(withID:\\\"user1234\\\")\\n\\n// Log a user in manually\\n\\nPrimer.logInUser(withID:\\\"user1234\\\")\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\nIf your app supports logging out there's also a way to let the SDK know about the change. When you call this Primer resets all state information, user properties, and Facebook sessions.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"[Primer logOutUser];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"Primer.logOutUser()\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\n####Current User\n\nEven if a user did not sign up or log in yet you can access a lot of information about them. To do so just get the current `PMRUser` instance and then access it's properties.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"PMRUser *user = [Primer currentUser];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"let user: PMRUser = Primer.currentUser()\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"We encourage holding only a local reference to the current user instance because on logout the SDK releases it and creates a new object, thus rendering any permanent reference outdated.\"\n}\n[/block]\nThe available properties are:\n* the unique user identifier,\n* the name of the user,\n* the user properties attached,\n* the user's active A/B/N tests,\n* the last viewed variation.\n\nNote that some of this information is only available after certain events. For example the user ID is not set until the user signs up or logs in; the name is only available once you set it; and the last viewed variation becomes available after the first Primer experience gets presented.\n\n####User Properties\n\nThe SDK keeps track of properties attached to each user, and syncs this information with the Primer servers, so whenever you log a user in with the same unique user ID, the same properties you attached earlier will be present. User properties are also attached to all events that the current user triggers, and they can be used for dynamic variable replacements on Primer experience screens. If you'd like to append some properties to the current user, just pass in a dictionary filled with the keys and values.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"NSDictionary *properties = @{@\\\"name\\\": @\\\"Steve\\\", @\\\"gender\\\": @\\\"male\\\", @\\\"age\\\": @(42)};\\n\\n[Primer appendUserProperties:properties];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"let properties: [String: Any] = [\\\"name\\\": \\\"Steve\\\", \\\"gender\\\": \\\"male\\\", \\\"age\\\": 42]\\n\\nPrimer.appendUserProperties(properties)\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"The `profile_pic` key is often used to personalize Primer experiences, so if you set it to anything other than an image or an image URL, some screens might look broken.\"\n}\n[/block]\n####Permissions\n\nThe Primer iOS SDK automatically handles everything related to asking for the user's permissions, except for two cases: handling notification settings changes, and setup for permission usage descriptions.\n\nTo handle push notifications on iOS 9 and below the SDK provides a simple method, `+applicationDidRegisterUserNotificationSettings`, that you should call from your app delegate's `-application:didRegisterUserNotificationSettings:` method. If you only support iOS 10 or above, you can skip this.\n\nFor permission usage descriptions you have to make sure to include the appropriate keys in your app's info plist, with a description. Without this the related system alert for the permission will not be presented to the users.\n\nThese keys are:\n- `NSLocationAlwaysUsageDescription` for location (always),\n- `NSLocationWhenInUseUsageDescription` for location (when in use),\n- `NSContactsUsageDescription` for contacts,\n- `NSMicrophoneUsageDescription` for microphone,\n- `NSCameraUsageDescription` for camera,\n- and `NSPhotoLibraryUsageDescription` for photo library.\n\nThe latter two is also needed if you use photo picker screens in your Primer experiences.\n\n####In-App Purchases\n\nBy default the SDK provides a basic, automatic handling of the user's purchases, and related events. However this might not fit more complex use-cases, when determining whether a product should be available for purchase is hard; like with consumables, or certain subscriptions.\n\nBecause of this Primer provides a purchase delegate protocol, `PMRPurchaseDelegate`, that your class can conform to, and inform the SDK about product availability when asked. Usually the best place to do so is a class that manages your In-App Purchases. Once you have an instance of a conforming class you can set it as the purchase delegate. Note that the SDK only holds a weak reference to this object (as is the norm with the delegation pattern), so your app should manage it.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"id <PMRPurchaseDelegate> storeManager = ...\\n[Primer setPurchaseDelegate:storeManager];\\n\\n// Then, inside your conforming class implement this method:\\n\\n- (void)areProductsAvailableWithIdentifiers:(NSArray<NSString *> *)identifiers completion:(PMRProductsAvailabilityBlock)completion;\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"let storeManager: PMRPurchaseDelegate = ...\\nPrimer.setPurchaseDelegate(storeManager)\\n\\n// Then, inside your conforming class implement this method:\\n\\nfunc areProductsAvailable(withIdentifiers identifiers: [String], completion: @escaping PMRProductsAvailabilityBlock)\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\nIn the implementation of this delegate method you should verify that the products with the given identifiers are up for sale. Once done, call the mandatory completion block with the array of all unavailable identifiers.\n\n####Accurate Install Tracking (New Integrations)\n\nIf you integrate the SDK into an application that is already live, returning users will incorrectly count as installs by default. To accurately track those users as returning users, pass the related launch option to Primer on SDK start.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"NSDictionary *launchOptions = {PMRLaunchOptionsIsFirstRunKey: @(NO)};\\n[Primer startWithToken:@\\\"[[app:token]]\\\" options:launchOptions];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"let launchOptions = [PMRLaunchOptionsIsFirstRunKey: false]\\nPrimer.start(withToken: \\\"[[app:token]]\\\", options: launchOptions)\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\nIt is recommended you get the actual first run boolean dynamically, based on your app's existing state.\n\nAlso, if you have a user already logged in, tell the SDK as described in [State Management](#section-state-management).","excerpt":"","slug":"user-management","type":"basic","title":"User Management"}
The SDK allows you to manage your user's state, properties, permissions, and purchases with ease. It's important to note that Primer does not provide a user storage system; you should still implement that functionality yourself. ####Requiring Login By default the SDK requires your users to log in, so the onboarding experience will be presented each time they launch the app until they either sign up or log in. If your app does not require users to have an account, you can turn this off, thus only showing the Primer experience once, the first time the app is installed and launched. [block:code] { "codes": [ { "code": "[Primer setRequiresLogin:NO];", "language": "objectivec" }, { "code": "Primer.setRequiresLogin(false)", "language": "swift" } ] } [/block] ####State Management The Primer iOS SDK automatically manages the user's state when it comes to signing up and logging in through the Primer experience's Signup or Login flows. However there might be other situations when your app allows users to sign up or log in. In these cases, you should notify the SDK about user state changes to appropriately track their behavior and manage their properties. [block:code] { "codes": [ { "code": "// Sign a user up manually\n\n[Primer signUpUserWithID:@\"user1234\"];\n\n// Log a user in manually\n\n[Primer logInUserWithID:@\"user1234\"];", "language": "objectivec" }, { "code": "// Sign a user up manually\n\nPrimer.signUpUser(withID:\"user1234\")\n\n// Log a user in manually\n\nPrimer.logInUser(withID:\"user1234\")", "language": "swift" } ] } [/block] If your app supports logging out there's also a way to let the SDK know about the change. When you call this Primer resets all state information, user properties, and Facebook sessions. [block:code] { "codes": [ { "code": "[Primer logOutUser];", "language": "objectivec" }, { "code": "Primer.logOutUser()", "language": "swift" } ] } [/block] ####Current User Even if a user did not sign up or log in yet you can access a lot of information about them. To do so just get the current `PMRUser` instance and then access it's properties. [block:code] { "codes": [ { "code": "PMRUser *user = [Primer currentUser];", "language": "objectivec" }, { "code": "let user: PMRUser = Primer.currentUser()", "language": "swift" } ] } [/block] [block:callout] { "type": "info", "body": "We encourage holding only a local reference to the current user instance because on logout the SDK releases it and creates a new object, thus rendering any permanent reference outdated." } [/block] The available properties are: * the unique user identifier, * the name of the user, * the user properties attached, * the user's active A/B/N tests, * the last viewed variation. Note that some of this information is only available after certain events. For example the user ID is not set until the user signs up or logs in; the name is only available once you set it; and the last viewed variation becomes available after the first Primer experience gets presented. ####User Properties The SDK keeps track of properties attached to each user, and syncs this information with the Primer servers, so whenever you log a user in with the same unique user ID, the same properties you attached earlier will be present. User properties are also attached to all events that the current user triggers, and they can be used for dynamic variable replacements on Primer experience screens. If you'd like to append some properties to the current user, just pass in a dictionary filled with the keys and values. [block:code] { "codes": [ { "code": "NSDictionary *properties = @{@\"name\": @\"Steve\", @\"gender\": @\"male\", @\"age\": @(42)};\n\n[Primer appendUserProperties:properties];", "language": "objectivec" }, { "code": "let properties: [String: Any] = [\"name\": \"Steve\", \"gender\": \"male\", \"age\": 42]\n\nPrimer.appendUserProperties(properties)", "language": "swift" } ] } [/block] [block:callout] { "type": "info", "body": "The `profile_pic` key is often used to personalize Primer experiences, so if you set it to anything other than an image or an image URL, some screens might look broken." } [/block] ####Permissions The Primer iOS SDK automatically handles everything related to asking for the user's permissions, except for two cases: handling notification settings changes, and setup for permission usage descriptions. To handle push notifications on iOS 9 and below the SDK provides a simple method, `+applicationDidRegisterUserNotificationSettings`, that you should call from your app delegate's `-application:didRegisterUserNotificationSettings:` method. If you only support iOS 10 or above, you can skip this. For permission usage descriptions you have to make sure to include the appropriate keys in your app's info plist, with a description. Without this the related system alert for the permission will not be presented to the users. These keys are: - `NSLocationAlwaysUsageDescription` for location (always), - `NSLocationWhenInUseUsageDescription` for location (when in use), - `NSContactsUsageDescription` for contacts, - `NSMicrophoneUsageDescription` for microphone, - `NSCameraUsageDescription` for camera, - and `NSPhotoLibraryUsageDescription` for photo library. The latter two is also needed if you use photo picker screens in your Primer experiences. ####In-App Purchases By default the SDK provides a basic, automatic handling of the user's purchases, and related events. However this might not fit more complex use-cases, when determining whether a product should be available for purchase is hard; like with consumables, or certain subscriptions. Because of this Primer provides a purchase delegate protocol, `PMRPurchaseDelegate`, that your class can conform to, and inform the SDK about product availability when asked. Usually the best place to do so is a class that manages your In-App Purchases. Once you have an instance of a conforming class you can set it as the purchase delegate. Note that the SDK only holds a weak reference to this object (as is the norm with the delegation pattern), so your app should manage it. [block:code] { "codes": [ { "code": "id <PMRPurchaseDelegate> storeManager = ...\n[Primer setPurchaseDelegate:storeManager];\n\n// Then, inside your conforming class implement this method:\n\n- (void)areProductsAvailableWithIdentifiers:(NSArray<NSString *> *)identifiers completion:(PMRProductsAvailabilityBlock)completion;", "language": "objectivec" }, { "code": "let storeManager: PMRPurchaseDelegate = ...\nPrimer.setPurchaseDelegate(storeManager)\n\n// Then, inside your conforming class implement this method:\n\nfunc areProductsAvailable(withIdentifiers identifiers: [String], completion: @escaping PMRProductsAvailabilityBlock)", "language": "swift" } ] } [/block] In the implementation of this delegate method you should verify that the products with the given identifiers are up for sale. Once done, call the mandatory completion block with the array of all unavailable identifiers. ####Accurate Install Tracking (New Integrations) If you integrate the SDK into an application that is already live, returning users will incorrectly count as installs by default. To accurately track those users as returning users, pass the related launch option to Primer on SDK start. [block:code] { "codes": [ { "code": "NSDictionary *launchOptions = {PMRLaunchOptionsIsFirstRunKey: @(NO)};\n[Primer startWithToken:@\"[[app:token]]\" options:launchOptions];", "language": "objectivec" }, { "code": "let launchOptions = [PMRLaunchOptionsIsFirstRunKey: false]\nPrimer.start(withToken: \"[[app:token]]\", options: launchOptions)", "language": "swift" } ] } [/block] It is recommended you get the actual first run boolean dynamically, based on your app's existing state. Also, if you have a user already logged in, tell the SDK as described in [State Management](#section-state-management).