{"_id":"5ab565f112d249007472429e","category":{"_id":"5ab565f112d2490074724299","version":"5ab565f112d2490074724298","project":"57c88b374434350e00509d7f","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-09-18T01:38:20.281Z","from_sync":false,"order":0,"slug":"getting-started","title":"Getting Started"},"project":"57c88b374434350e00509d7f","parentDoc":null,"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-27T09:00:53.421Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":1,"body":"Follow these easy few steps to get Account Authentication up and running:\n\n1. [Conform to the Protocol](#1-conform-to-the-protocol)\n2. [Hook up Signup](#2-hook-up-signup)\n3. [Hook up Login](#3-hook-up-login)\n4. [Hook up Logout](#4-hook-up-logout)\n5. [Hook up Password Recovery](#5-hook-up-password-recovery)\n6. [Hook up Optional Validation](#6-hook-up-optional-validation)\n\nIf you want to add Facebook Login functionality:\n\n7. [Hook up Facebook Login](#7-hook-up-facebook-login)\n\nNeed help or have questions? Contact us at <a href=\"mailto:success:::at:::goprimer.com\">success@goprimer.com</a>\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"1. Conform to the Protocol\"\n}\n[/block]\nTo be able to support account authentication you need a class that's responsible for user management which conforms to the `PMRExperienceDelegate` protocol, and implements the following delegate methods. You'll also need to register it with the SDK. The SDK conforms to the delegation pattern, and as such, only holds a weak reference to your object. You can read more about delegation patterns <a href=\"https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html\" target=\"_blank\">here</a>.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"id <PMRExperienceDelegate> userManager = ...\\n[Primer setExperienceDelegate:userManager];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"let userManager: PMRExperienceDelegate = ...\\nPrimer.setExperienceDelegate(userManager)\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"2. Hook up Signup\"\n}\n[/block]\nWhen a signup flow is submitted, the delegate calls the `-signUpWithFields:completion:` method. The dictionary contains all fields of the flow. Note that the non-sensitive fields get added as user properties after a successful validation.\n\nIn this method you should validate that a new user with the given fields can be created, and if so you should save it to your user system. If this succeeds pass the user identifier as the second parameter of the completion block. If the process fails, pass an invalidated result as the first parameter.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"- (void)signUpWithFields:(NSDictionary<NSString *, id> *)fields completion:(PMRUserValidationBlock)completion {\\n        \\n    [self asyncSignupWithFields:fields completion:^(BOOL success, NSString *userID) {\\n        if (success) {\\n            completion(nil, userID);\\n        } else {\\n            PMRValidationResult *result = [PMRValidationResult new];\\n            [result invalidateWithErrorMessage:@\\\"There was an issue signing up.\\\"];\\n            completion(result, nil);\\n        }\\n    }];\\n}\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"func signUp(withFields fields: [String : Any], completion: @escaping PMRUserValidationBlock) {\\n\\n    asyncSignup(withFields: fields) { (success: Bool, userID: String) in\\n        if success {\\n            completion(nil, userID)\\n        } else {\\n            let result = PMRValidationResult()\\n            result.invalidateWithErrorMessage(\\\"There was an issue signing up.\\\")\\n            completion(result, nil)\\n        }\\n    }\\n}\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"3. Hook up Login\"\n}\n[/block]\nWhen a login flow is submitted the `-logInWithFields:completion:` method gets called by the delegate. The dictionary contains all fields of the flow. Note that the non-sensitive fields get added as user properties after a successful validation.\n\nIn this method you should validate that a user can be logged in with the given fields, and if so you should save that state to your user system. Handle validation similarly like in the signup method.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"4. Hook up Logout\"\n}\n[/block]\nIf your app supports logging out there's also a way to let the SDK know about the change, just call `+logOutUser`. Doing so resets all state information, user properties, and Facebook sessions. Afterwards present your app's built-in logged out experience as usual.\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\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"5. Hook up Password Recovery\"\n}\n[/block]\nWhen a recover password flow is submitted the delegate calls the `-recoverPasswordWithFields:completion:` method. The dictionary contains all fields of the flow.\n\nIn this method you should try to send out a password recovery email to the user. If this succeeds pass in `nil` (or a new, valid result instance) as the parameter of the completion block. If the process fails, pass an invalidated result as the parameter.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"- (void)recoverPasswordWithFields:(NSDictionary<NSString *,id> *)fields completion:(PMRValidationBlock)completion {\\n    \\n    [self asyncRecoverPasswordWithFields:fields completion:^(BOOL success) {\\n        if (success) {\\n            completion(nil);\\n        } else {\\n            PMRValidationResult *result = [PMRValidationResult new];\\n            [result invalidateWithErrorMessage:@\\\"There was an issue recovering your password.\\\"];\\n            completion(result);\\n        }\\n    }];\\n}\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"func recoverPassword(withFields fields: [String : Any], completion: @escaping PMRValidationBlock) {\\n\\n    asyncRecoverPassword(withFields: fields) { (success: Bool) in\\n        if success {\\n            completion(nil)\\n        } else {\\n            let result = PMRValidationResult()\\n            result.invalidateWithErrorMessage(\\\"There was an issue recovering your password.\\\")\\n            completion(result)\\n        }\\n    }\\n}\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"You're done\"\n}\n[/block]\nCongratulations, this is all you need for basic account authentication.\n\nIf you'd also like to set up **Uniqueness Validation** or **Facebook Login**, read on!\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"6. Hook up Optional Validation\"\n}\n[/block]\nTo validate any input fields on a screen implement the `-validateFields:completion:` method. It gets called after a screen is submitted with any inputs on it. The dictionary contains all fields of the screen.\n\nHandle the process similrly like in the recover password scenario, if it succeeds pass in `nil` (or a new, valid result instance) as the parameter of the completion block. If the process fails, pass an invalidated result as the parameter.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"7. Hook up Facebook Login\"\n}\n[/block]\nIf your application has the v4+ version of the Facebook iOS SDK integrated and you'd like to set Facebook Login up as part of the Primer onboarding experience, it's easy to do so.\n\nIn case you don't have their SDK integrated yet, just follow their <a href=\"https://developers.facebook.com/docs/ios/getting-started\" target=\"_blank\">Getting Started</a> guide.\n\nTo properly load all necessary classes please go to the `Build Settings` tab of your app target's settings in Xcode, and search for `Other Linker Flags`. Then add `-ObjC` to the list of flags.\n\nIf you'd like to get notified about a Facebook authentication, or if you want to verify the process, just implement the `-validateFacebookUserWithFields:completion:` method of the delegate. The dictionary contains all requested Graph API fields that Facebook returned to the SDK. Note that these fields get added as user properties after a successful validation.\n\nIn this method you should validate that a new user with the given fields can be created, and if so you should save it to your user system. If this succeeds pass the user identifier as the second parameter of the completion block. If the process fails, pass an invalidated result as the first parameter. The third parameter lets our SDK know whether this is a new user or not (so it can be properly tracked as a signup or a login).\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"- (void)validateFacebookUserWithFields:(NSDictionary<NSString *, id> *)fields completion:(PMRFacebookUserValidationBlock)completion {\\n\\n    [self asyncSignupWithFields:fields completion:^(BOOL success, NSString *userID, BOOL isNewUser) {\\n        if (success) {\\n            completion(nil, userID, isNewUser);\\n        } else {\\n            PMRValidationResult *result = [PMRValidationResult new];\\n            [result invalidateWithErrorMessage:@\\\"There was an issue signing up.\\\"];\\n            completion(result, nil, NO);\\n        }\\n    }];\\n}\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"func validateFacebookUser(withFields fields: [String : Any], completion: @escaping PMRFacebookUserValidationBlock) {\\n\\n    asyncSignup(withFields: fields) { (success: Bool, userID: String, isNewUser: Bool) in\\n        if success {\\n            completion(nil, userID, isNewUser)\\n        } else {\\n            let result = PMRValidationResult()\\n            result.invalidateWithErrorMessage(\\\"There was an issue signing up.\\\")\\n            completion(result, nil, false)\\n        }\\n    }\\n}\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]","excerpt":"","slug":"quick-authentication-guide","type":"basic","title":"Quick Authentication Guide"}

Quick Authentication Guide


Follow these easy few steps to get Account Authentication up and running: 1. [Conform to the Protocol](#1-conform-to-the-protocol) 2. [Hook up Signup](#2-hook-up-signup) 3. [Hook up Login](#3-hook-up-login) 4. [Hook up Logout](#4-hook-up-logout) 5. [Hook up Password Recovery](#5-hook-up-password-recovery) 6. [Hook up Optional Validation](#6-hook-up-optional-validation) If you want to add Facebook Login functionality: 7. [Hook up Facebook Login](#7-hook-up-facebook-login) Need help or have questions? Contact us at <a href="mailto:success@goprimer.com">success@goprimer.com</a> [block:api-header] { "type": "basic", "title": "1. Conform to the Protocol" } [/block] To be able to support account authentication you need a class that's responsible for user management which conforms to the `PMRExperienceDelegate` protocol, and implements the following delegate methods. You'll also need to register it with the SDK. The SDK conforms to the delegation pattern, and as such, only holds a weak reference to your object. You can read more about delegation patterns <a href="https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html" target="_blank">here</a>. [block:code] { "codes": [ { "code": "id <PMRExperienceDelegate> userManager = ...\n[Primer setExperienceDelegate:userManager];", "language": "objectivec" }, { "code": "let userManager: PMRExperienceDelegate = ...\nPrimer.setExperienceDelegate(userManager)", "language": "swift" } ] } [/block] [block:api-header] { "type": "basic", "title": "2. Hook up Signup" } [/block] When a signup flow is submitted, the delegate calls the `-signUpWithFields:completion:` method. The dictionary contains all fields of the flow. Note that the non-sensitive fields get added as user properties after a successful validation. In this method you should validate that a new user with the given fields can be created, and if so you should save it to your user system. If this succeeds pass the user identifier as the second parameter of the completion block. If the process fails, pass an invalidated result as the first parameter. [block:code] { "codes": [ { "code": "- (void)signUpWithFields:(NSDictionary<NSString *, id> *)fields completion:(PMRUserValidationBlock)completion {\n \n [self asyncSignupWithFields:fields completion:^(BOOL success, NSString *userID) {\n if (success) {\n completion(nil, userID);\n } else {\n PMRValidationResult *result = [PMRValidationResult new];\n [result invalidateWithErrorMessage:@\"There was an issue signing up.\"];\n completion(result, nil);\n }\n }];\n}", "language": "objectivec" }, { "code": "func signUp(withFields fields: [String : Any], completion: @escaping PMRUserValidationBlock) {\n\n asyncSignup(withFields: fields) { (success: Bool, userID: String) in\n if success {\n completion(nil, userID)\n } else {\n let result = PMRValidationResult()\n result.invalidateWithErrorMessage(\"There was an issue signing up.\")\n completion(result, nil)\n }\n }\n}", "language": "swift" } ] } [/block] [block:api-header] { "type": "basic", "title": "3. Hook up Login" } [/block] When a login flow is submitted the `-logInWithFields:completion:` method gets called by the delegate. The dictionary contains all fields of the flow. Note that the non-sensitive fields get added as user properties after a successful validation. In this method you should validate that a user can be logged in with the given fields, and if so you should save that state to your user system. Handle validation similarly like in the signup method. [block:api-header] { "type": "basic", "title": "4. Hook up Logout" } [/block] If your app supports logging out there's also a way to let the SDK know about the change, just call `+logOutUser`. Doing so resets all state information, user properties, and Facebook sessions. Afterwards present your app's built-in logged out experience as usual. [block:code] { "codes": [ { "code": "[Primer logOutUser];", "language": "objectivec" }, { "code": "Primer.logOutUser()", "language": "swift" } ] } [/block] [block:api-header] { "type": "basic", "title": "5. Hook up Password Recovery" } [/block] When a recover password flow is submitted the delegate calls the `-recoverPasswordWithFields:completion:` method. The dictionary contains all fields of the flow. In this method you should try to send out a password recovery email to the user. If this succeeds pass in `nil` (or a new, valid result instance) as the parameter of the completion block. If the process fails, pass an invalidated result as the parameter. [block:code] { "codes": [ { "code": "- (void)recoverPasswordWithFields:(NSDictionary<NSString *,id> *)fields completion:(PMRValidationBlock)completion {\n \n [self asyncRecoverPasswordWithFields:fields completion:^(BOOL success) {\n if (success) {\n completion(nil);\n } else {\n PMRValidationResult *result = [PMRValidationResult new];\n [result invalidateWithErrorMessage:@\"There was an issue recovering your password.\"];\n completion(result);\n }\n }];\n}", "language": "objectivec" }, { "code": "func recoverPassword(withFields fields: [String : Any], completion: @escaping PMRValidationBlock) {\n\n asyncRecoverPassword(withFields: fields) { (success: Bool) in\n if success {\n completion(nil)\n } else {\n let result = PMRValidationResult()\n result.invalidateWithErrorMessage(\"There was an issue recovering your password.\")\n completion(result)\n }\n }\n}", "language": "swift" } ] } [/block] [block:api-header] { "type": "basic", "title": "You're done" } [/block] Congratulations, this is all you need for basic account authentication. If you'd also like to set up **Uniqueness Validation** or **Facebook Login**, read on! [block:api-header] { "type": "basic", "title": "6. Hook up Optional Validation" } [/block] To validate any input fields on a screen implement the `-validateFields:completion:` method. It gets called after a screen is submitted with any inputs on it. The dictionary contains all fields of the screen. Handle the process similrly like in the recover password scenario, if it succeeds pass in `nil` (or a new, valid result instance) as the parameter of the completion block. If the process fails, pass an invalidated result as the parameter. [block:api-header] { "type": "basic", "title": "7. Hook up Facebook Login" } [/block] If your application has the v4+ version of the Facebook iOS SDK integrated and you'd like to set Facebook Login up as part of the Primer onboarding experience, it's easy to do so. In case you don't have their SDK integrated yet, just follow their <a href="https://developers.facebook.com/docs/ios/getting-started" target="_blank">Getting Started</a> guide. To properly load all necessary classes please go to the `Build Settings` tab of your app target's settings in Xcode, and search for `Other Linker Flags`. Then add `-ObjC` to the list of flags. If you'd like to get notified about a Facebook authentication, or if you want to verify the process, just implement the `-validateFacebookUserWithFields:completion:` method of the delegate. The dictionary contains all requested Graph API fields that Facebook returned to the SDK. Note that these fields get added as user properties after a successful validation. In this method you should validate that a new user with the given fields can be created, and if so you should save it to your user system. If this succeeds pass the user identifier as the second parameter of the completion block. If the process fails, pass an invalidated result as the first parameter. The third parameter lets our SDK know whether this is a new user or not (so it can be properly tracked as a signup or a login). [block:code] { "codes": [ { "code": "- (void)validateFacebookUserWithFields:(NSDictionary<NSString *, id> *)fields completion:(PMRFacebookUserValidationBlock)completion {\n\n [self asyncSignupWithFields:fields completion:^(BOOL success, NSString *userID, BOOL isNewUser) {\n if (success) {\n completion(nil, userID, isNewUser);\n } else {\n PMRValidationResult *result = [PMRValidationResult new];\n [result invalidateWithErrorMessage:@\"There was an issue signing up.\"];\n completion(result, nil, NO);\n }\n }];\n}", "language": "objectivec" }, { "code": "func validateFacebookUser(withFields fields: [String : Any], completion: @escaping PMRFacebookUserValidationBlock) {\n\n asyncSignup(withFields: fields) { (success: Bool, userID: String, isNewUser: Bool) in\n if success {\n completion(nil, userID, isNewUser)\n } else {\n let result = PMRValidationResult()\n result.invalidateWithErrorMessage(\"There was an issue signing up.\")\n completion(result, nil, false)\n }\n }\n}", "language": "swift" } ] } [/block]