{"id":40,"date":"2015-06-20T20:11:02","date_gmt":"2015-06-20T20:11:02","guid":{"rendered":"http:\/\/thibaultklein.com\/ios\/?p=40"},"modified":"2016-01-24T01:55:51","modified_gmt":"2016-01-24T01:55:51","slug":"tutorial-use-touch-id-in-your-swift-app","status":"publish","type":"post","link":"https:\/\/thibaultklein.com\/ios\/tutorial-use-touch-id-in-your-swift-app\/","title":{"rendered":"Use Touch ID In Your Swift App"},"content":{"rendered":"<h1>WHAT IS TOUCH ID?<\/h1>\n<p>With iOS 7 and the iPhone 5S release, Apple introduced\u00a0<strong>Touch ID<\/strong>, a new way for users to authenticate by using their fingerprints to unlock their phones or purchases on the App Store. Now, in iOS 8, Apple provides an SDK for developers to use Touch ID in their apps, and, as you will see in this blog post, it\u2019s actually very simple to add this feature to your app. Remember that Touch ID is only available for iPhone 5S and newer, iPad Air 2 and iPad Mini 3. That\u2019s something to consider when you implement it in your app.<\/p>\n<p>In this blog post, I will walk you through all the steps to implement Touch ID in your app \u2014 and of course, because we are curious developers, everything in this post will be coded in Swift. If you are not familiar with Swift yet, it\u2019s probably a good time to read the\u00a0<a href=\"https:\/\/itunes.apple.com\/us\/book\/swift-programming-language\/id881256329?mt=11\">iBook provided by Apple<\/a>\u00a0before reading this article.<\/p>\n<p><a href=\"https:\/\/github.com\/prolificinteractive\/TouchIDBlogPost\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/i0.wp.com\/prolificinteractive.com\/blog\/wp-content\/uploads\/2014\/04\/GitHub_Logo.png?resize=166%2C69\" alt=\"\" width=\"166\" height=\"69\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h1>DESCRIPTION OF THE FRAMEWORK<\/h1>\n<p>&nbsp;<\/p>\n<p>Apple implemented a framework called\u00a0<strong>Local Authentication<\/strong>\u00a0that you can use with a security policy to authenticate a user. This framework is based on one method:<\/p>\n<pre>func evaluatePolicy(policy: LAPolicy, localizedReason localizedReason: String!, \r\nreply: ((Bool, NSError!) -&gt; Void)!)\r\n<\/pre>\n<p>This method will check the user identity for you. You can find more details in the\u00a0<a href=\"https:\/\/developer.apple.com\/library\/prerelease\/ios\/documentation\/LocalAuthentication\/Reference\/LocalAuthentication_Framework\/index.html\">Apple documentation<\/a>\u00a0or in the WWDC 2014 session\u00a0<a href=\"https:\/\/developer.apple.com\/videos\/wwdc\/2014\/?include=711#711\">Keychain and Authentication with Touch ID<\/a>\u00a0if you want to understand how it works exactly. The goal of this blog post is to focus on the framework implementation and the best practices when using Touch ID.<\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/i0.wp.com\/prolificinteractive.com\/blog\/wp-content\/uploads\/2015\/01\/touchID.png?resize=200%2C200\" alt=\"\" width=\"200\" height=\"200\" \/><\/p>\n<p>In this framework, one of the most important things is the different errors that you have to handle. Like I have mentioned, Touch ID is not available on all devices. Also, the technology is still new, so it may not recognize every user fingerprint correctly. The system can also cancel the fingerprint recognition in some situations (when you receive a phone call, for example). With all these possibilities, error management is crucial when working with Touch ID.<\/p>\n<p>Below you can find the list of all the different errors. In your code, you will have to handle all of them (with custom error messaging, if possible) to enhance the user experience.<\/p>\n<pre>enum LAError : Int {\r\n    case AuthenticationFailed\r\n    case UserCancel\r\n    case UserFallback\r\n    case SystemCancel\r\n    case PasscodeNotSet\r\n    case TouchIDNotAvailable\r\n    case TouchIDNotEnrolled\r\n}\r\n<\/pre>\n<h3>CONSTANTS:<\/h3>\n<ul>\n<li><strong>AuthenticationFailed<\/strong><br \/>\nAuthentication was not successful because the user failed to provide valid credentials.<\/li>\n<li><strong>UserCancel<\/strong><br \/>\nAuthentication was canceled by the user\u2014for example, the user tapped Cancel in the dialog.<\/li>\n<li><strong>UserFallback<\/strong><br \/>\nAuthentication was canceled because the user tapped the fallback button (Enter Password).<\/li>\n<li><strong>SystemCancel<\/strong><br \/>\nAuthentication was canceled by system\u2014for example, if another application came to foreground while the authentication dialog was up.<\/li>\n<li><strong>PasscodeNotSet<\/strong><br \/>\nAuthentication could not start because the passcode is not set on the device.<\/li>\n<li><strong>TouchIDNotAvailable<\/strong><br \/>\nAuthentication could not start because Touch ID is not available on the device.<\/li>\n<li><strong>TouchIDNotEnrolled<\/strong><br \/>\nAuthentication could not start because Touch ID has no enrolled fingers.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h1>DEMO APP<\/h1>\n<p>&nbsp;<\/p>\n<p>Ready to build an app using Touch ID? Let\u2019s start!<\/p>\n<h4>STEP 0: SET UP THE PROJECT AND THE STORYBOARDS, IMPORT THE FRAMEWORK, CREATE NECESSARY CLASSES<\/h4>\n<p>The first thing is to\u00a0<strong>create a Swift project<\/strong>. Create a\u00a0<strong>single view application<\/strong>and select Swift as the main project language.<\/p>\n<p>Next, link\u00a0<strong>LocalAuthentication.framework<\/strong>\u00a0with your target.<\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/i0.wp.com\/prolificinteractive.com\/blog\/wp-content\/uploads\/2015\/01\/load_framework.png?resize=614%2C140\" alt=\"\" width=\"614\" height=\"140\" \/><\/p>\n<p>Then, import the framework at the top of your view controller:<\/p>\n<pre>import LocalAuthentication<\/pre>\n<p>&nbsp;<\/p>\n<h4>STEP 1: CREATE AUTHENTICATE METHOD<\/h4>\n<p>In the\u00a0<span id=\"crayon-5585c7ccc98fe232627474\" class=\"crayon-syntax crayon-syntax-inline crayon-theme-familiar-copy crayon-theme-familiar-copy-inline crayon-font-monaco\"><span class=\"crayon-pre crayon-code\"><span class=\"crayon-v\">ViewController<\/span><\/span><\/span>\u00a0file, create a method to authenticate the user. This method will be responsible for initiating and handling Touch ID authentication.<\/p>\n<pre>func authenticateUser() {}<\/pre>\n<p>&nbsp;<\/p>\n<h4>STEP 2: GET THE CURRENT CONTEXT<\/h4>\n<p>In this method, you need to get the device current authentication context:<\/p>\n<pre>func authenticateUser() {\r\n    let context : LAContext = LAContext()\r\n}\r\n<\/pre>\n<p>You\u2019ll need this context object to ask for TouchID authentication.<\/p>\n<div>Note: You don\u2019t have to specify the type\u00a0<strong>LAContext<\/strong>\u00a0in Swift, but I prefer to do it to make the code easier to read.<\/div>\n<h4>STEP 3: DECLARE THE ERROR AND REASON STRING VARIABLES<\/h4>\n<p>You need an\u00a0<strong>NSError<\/strong>\u00a0to handle error management, and an\u00a0<strong>NSString<\/strong>\u00a0because Apple recommends that you display a quick explanation of why you are trying to authenticate the user using Touch ID. Put these inside\u00a0<strong>authenticateUser<\/strong>:<\/p>\n<pre>var error : NSError?\r\nvar myLocalizedReasonString : NSString = \"Authentication is required\"\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h4>STEP 4: CHECK IF THE DEVICE IS COMPATIBLE WITH TOUCH ID<\/h4>\n<p>Now, check if the device is actually compatible with Touch ID. Ask the current authentication context if the policy can be evaluated by pasting this into\u00a0<strong>authenticateUser<\/strong>:<\/p>\n<pre>if context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &amp;error) {}\r\n<\/pre>\n<p>Note that we are asking for the biometrics policy type here<\/p>\n<pre>DeviceOwnerAuthenticationWithBiometrics<\/pre>\n<p>This method takes two parameters:<\/p>\n<ul>\n<li><strong>policy:<\/strong>\u00a0the policy to evaluate, which is the object you created earlier.<\/li>\n<li><strong>error:<\/strong>\u00a0a pointer to an error object, that you will use to inform the user if an error occurs.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h4>STEP 5: EVALUATE THE POLICY<\/h4>\n<p>If the current context can evaluate the biometrics policy, it means you can finally call the evaluation method within the innermost brackets:<\/p>\n<pre>context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, \r\nlocalizedReason: myLocalizedReasonString, \r\nreply: { (success : Bool, evaluationError : NSError?) -&gt; Void in })\r\n<\/pre>\n<p>This method takes three parameters:<\/p>\n<ul>\n<li><strong>policy:<\/strong>\u00a0the policy to evaluate.<\/li>\n<li><strong>localizedReason:<\/strong>\u00a0the string to explain the request for user authentication.<\/li>\n<li><strong>reply:<\/strong>\u00a0reply block that is executed when authentication is complete.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h4>STEP 6: IMPLEMENT TOUCH ID SUCCESS AND FAILURE CODE<\/h4>\n<p>If the authentication succeeded, you can update your UI. To do that, create the following method. You can customize it to do whatever action you need when Touch ID authenticates the user successfully.<\/p>\n<pre>func loadData() {\r\n    \/\/ Do whatever you want\r\n    println(\"Load data\")\r\n}\r\n<\/pre>\n<p>Now call it when Touch ID worked (within the\u00a0<strong>reply<\/strong>\u00a0block)<\/p>\n<pre>if success {\r\n    NSOperationQueue.mainQueue().addOperationWithBlock({ () -&gt; Void in\r\n        self.loadData()\r\n    })\r\n}\r\n<\/pre>\n<p>If the authentication failed with the biometrics policy, you need to handle the error correctly. In this demo app, implement a method to display an alert view with a password field to let the user authenticate with a password if something happen. Keep it empty for now:<\/p>\n<pre>func showPasswordAlert() {}<\/pre>\n<p>And because the new switch\/case implementation is pretty nice in Swift, use it here.<\/p>\n<pre>if success {\r\n...\r\n}\r\nelse {\r\n    \/\/ Authentification failed\r\n    println(evaluationError?.localizedDescription)\r\n \r\n    switch evaluationError!.code {\r\n        case LAError.SystemCancel.rawValue:\r\n            println(\"Authentication cancelled by the system\")\r\n         case LAError.UserCancel.rawValue:\r\n            println(\"Authentication cancelled by the user\")\r\n         case LAError.UserFallback.rawValue:\r\n            println(\"User wants to use a password\")\r\n            \/\/ We show the alert view in the main thread (always update the UI in the main thread)\r\n            NSOperationQueue.mainQueue().addOperationWithBlock({ () -&gt; Void in\r\n                self.showPasswordAlert()\r\n                })\r\n          default:\r\n              println(\"Authentication failed\")\r\n                  NSOperationQueue.mainQueue().addOperationWithBlock({ () -&gt; Void in\r\n                      self.showPasswordAlert()\r\n                      })\r\n          }\r\n}\r\n<\/pre>\n<p>Here is the list of errors to handle:<\/p>\n<ul>\n<li>System cancel<\/li>\n<li>User cancel<\/li>\n<li>User wants to use a password instead<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h4>STEP 7: IMPLEMENT ERROR MANAGEMENT FOR POLICY EVALUATION<\/h4>\n<p>Same thing for the policy error management. The possibilities are:<\/p>\n<ul>\n<li>TouchID not available<\/li>\n<li>Passcode not set<\/li>\n<\/ul>\n<pre>if context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &amp;error) {\r\n...\r\n    } else {\r\n        switch error!.code {\r\n            case LAError.TouchIDNotEnrolled.rawValue:\r\n                println(\"TouchID not enrolled\")\r\n            case LAError.PasscodeNotSet.rawValue:\r\n                println(\"Passcode not set\")\r\n            default:\r\n                println(\"TouchID not available\")\r\n        }\r\n    self.showPasswordAlert()\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h4>STEP 8: CALL THE METHOD IN\u00a0VIEWDIDAPPEAR<\/h4>\n<p>Now that the method is ready, you can make the call in\u00a0<strong>viewDidAppear<\/strong>.<\/p>\n<div class=\"note\">Note: Why not\u00a0viewDidLoad? Because you want to make sure the view hierarchy is set up before you present an alert view.<\/div>\n<pre>override func viewDidAppear(animated: Bool) {\r\n    super.viewDidAppear(animated)\r\n    authenticateUser()\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h4>STEP 9: IMPLEMENT A PASSWORD ALERT VIEW WHEN TOUCH ID IS NOT AVAILABLE<\/h4>\n<p>It\u2019s time to update the password alert view method. With iOS 8, Apple released a new framework to display alert messages to the user:\u00a0<a href=\"https:\/\/developer.apple.com\/library\/prerelease\/ios\/documentation\/UIKit\/Reference\/UIAlertController_class\/index.html\">UIAlertController<\/a>. This class replaces both\u00a0<strong>UIActionSheet<\/strong>\u00a0and\u00a0<strong>UIAlertView<\/strong>.<\/p>\n<p>But first things first. Implement a login method that will check if the password is correct. This method takes a\u00a0<strong>String<\/strong>\u00a0as parameter and either dismiss the alert or present the login alert again if the password is incorrect.<\/p>\n<pre>func login(password: String) {\r\n    if password == \"weloveprolific\" {\r\n        self.loadData()\r\n    } else {\r\n        self.showPasswordAlert()\r\n    }\r\n}\r\n<\/pre>\n<p>Back to your show password method. Implement a\u00a0<strong>UIAlertController<\/strong>\u00a0with a title, message and a type.<\/p>\n<pre>func showPasswordAlert() {\r\n    \/\/ New way to present an alert view using UIAlertController\r\n    let alertController : UIAlertController = \r\nUIAlertController(title:\"TouchID Demo\" , message: \"Please enter password\", preferredStyle: .Alert)\r\n}\r\n<\/pre>\n<p>You also need to create two\u00a0<strong>UIAlertActions<\/strong>\u00a0(Cancel and Done actions). These objects will be passed to the\u00a0<strong>UIAlertController<\/strong>. A\u00a0<strong>UIAlertAction<\/strong>\u00a0object needs a title and a type (here\u00a0<strong>Cancel<\/strong>\u00a0and\u00a0<strong>Default<\/strong>).<\/p>\n<p>Paste this at the bottom of\u00a0<strong>showPasswordAlert<\/strong>:<\/p>\n<pre>\/\/ We define the actions to add to the alert controller\r\nlet cancelAction : UIAlertAction = UIAlertAction(title: \"Cancel\", style: .Cancel) { (action) -&gt; Void in\r\n    println(action)\r\n}\r\nlet doneAction : UIAlertAction = UIAlertAction(title: \"Done\", style: .Default) { (action) -&gt; Void in\r\n    let passwordTextField = alertController.textFields![0] as UITextField\r\n    self.login(passwordTextField.text)\r\n}\r\ndoneAction.enabled = false\r\n<\/pre>\n<p>In the\u00a0<strong>action<\/strong>\u00a0block, you defined the action for a button tap. For the cancel action, there is nothing specific to do. But for the done action, you login the user with the text inside the textfield.<\/p>\n<div class=\"note\">Note: The done action is disabled by default because the textfield is empty at the beginning.<\/div>\n<p>The next step is to add an input text field to the controller. To do so, use the method\u00a0<strong>addTextFieldWithConfigurationHandler<\/strong>, and customize the textfield inside the block as a secure entry field. Also, add a notification that fires when the user changes the text inside the field, so you can update the done button.<\/p>\n<p>Do this all at the bottom of\u00a0<strong>showPasswordAlert<\/strong>\u00a0with this code:<\/p>\n<pre>\/\/ We are customizing the text field using a configuration handler\r\nalertController.addTextFieldWithConfigurationHandler { (textField) -&gt; Void in\r\n    textField.placeholder = \"Password\"\r\n    textField.secureTextEntry = true\r\n \r\n    NSNotificationCenter.defaultCenter().addObserverForName(UITextFieldTextDidChangeNotification, \r\nobject: textField, queue: NSOperationQueue.mainQueue(), usingBlock: { (notification) -&gt; Void in\r\n        doneAction.enabled = textField.text != \"\"\r\n    })\r\n}\r\n<\/pre>\n<p>Finally, add your two actions to the controller and present it by pasting this at the bottom of\u00a0<strong>showPasswordAlert<\/strong>:<\/p>\n<pre>alertController.addAction(cancelAction)\r\nalertController.addAction(doneAction)\r\nself.presentViewController(alertController, animated: true) {\r\n    \/\/ Nothing to do here\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h4>BUILD AND RUN!<\/h4>\n<p>Now your app is ready! Build and Run, and you can test out Touch ID with a password fallback!<\/p>\n<h1>CONCLUSION<\/h1>\n<p>In this tutorial, you implemented the evaluation method to authenticate with user fingerprints with Touch ID. You also reviewed some Swift basic knowledge and the new\u00a0<strong>UIAlertController<\/strong>\u00a0implementation released with iOS 8. As you can see, it\u2019s very simple to add Touch ID to your projects, as the Local Authentication framework is doing all the work for you. The only thing you have to handle correctly is error management.<\/p>\n<p>In the\u00a0<a href=\"https:\/\/github.com\/prolificinteractive\/TouchIDBlogPost\">sample project<\/a>, I use a Touch ID manager class (both in Swift and Objective-C) that you can directly reuse in your projects. This method is doing the work for you. All you need to do is call it, then put your code in the success and failure blocks.<\/p>\n<p>As you can see, Touch ID is a cool feature, and really easy to implement. It should be considered every time you want to authenticate a user and let them access a sensitive part of your app. People love Touch ID, and will be happy to use it.<\/p>\n<p>&nbsp;<\/p>\n<h3>SUGGESTED FURTHER READING<\/h3>\n<ul>\n<li><a href=\"http:\/\/www.appcoda.com\/touch-id-api-ios8\/\">Appcoda: Working with Touch ID API in iOS 8 SDK<\/a><\/li>\n<li><a href=\"http:\/\/nshipster.com\/uialertcontroller\/\">NSHipster: UIAlertController<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>WHAT IS TOUCH ID? With iOS 7 and the iPhone 5S release, Apple introduced\u00a0Touch ID, a new way for users to authenticate by using their fingerprints to unlock their phones or purchases on the App Store. Now, in iOS 8, Apple provides an SDK for developers to use Touch ID in their apps, and, as&hellip; <a class=\"more-link\" href=\"https:\/\/thibaultklein.com\/ios\/tutorial-use-touch-id-in-your-swift-app\/\">Continue reading <span class=\"screen-reader-text\">Use Touch ID In Your Swift App<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3],"tags":[5],"class_list":["post-40","post","type-post","status-publish","format-standard","hentry","category-ios","tag-swift","entry"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p6mZvu-E","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/thibaultklein.com\/ios\/wp-json\/wp\/v2\/posts\/40","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thibaultklein.com\/ios\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thibaultklein.com\/ios\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thibaultklein.com\/ios\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/thibaultklein.com\/ios\/wp-json\/wp\/v2\/comments?post=40"}],"version-history":[{"count":2,"href":"https:\/\/thibaultklein.com\/ios\/wp-json\/wp\/v2\/posts\/40\/revisions"}],"predecessor-version":[{"id":124,"href":"https:\/\/thibaultklein.com\/ios\/wp-json\/wp\/v2\/posts\/40\/revisions\/124"}],"wp:attachment":[{"href":"https:\/\/thibaultklein.com\/ios\/wp-json\/wp\/v2\/media?parent=40"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thibaultklein.com\/ios\/wp-json\/wp\/v2\/categories?post=40"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thibaultklein.com\/ios\/wp-json\/wp\/v2\/tags?post=40"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}