5

The documentation that Apple has provided for TouchID implementation for iOS 8 is in Objective-C.

Is there a Swift version of it?

Objective-C:

- (IBAction)touchIDAvailable:(UIButton *)touchIDAvailableButton {
    LAContext *context = [[LAContext alloc] init];
    __block  NSString *msg;
    [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:NSLocalizedString(@"Place your finger on the sensor", nil) reply: ^(BOOL success, NSError *authenticationError) {
         if (success) {
         }
    }
}

Swift:

@IBAction func touchidbutton(sender: AnyObject) {
    authContext.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: "Place your finger on the sensor"?, reply: ((success : Bool, NSError!) -> Void)?){
        if (success) {
        }
    }
}

7 Answers 7

6

Here is my view controller that does these checks in Swift. While working on this I found the completion block/closure syntax in Swift to be very confusing.

Notice that some of the options changed in Beta 2 in order to give you more control over the Touch ID dialog such as disabling the fallback option or the cancel button.

// Imports
import UIKit
import LocalAuthentication

// Class Implementation
class FirstViewController: UIViewController {

// Class Properties
@IBOutlet var statusLabel : UILabel
@IBOutlet var headerString: UILabel
var authError : NSError?
var authContext = LAContext()
var statusText = ""
var alert = UIAlertController(title: "", message: "", preferredStyle: UIAlertControllerStyle.Alert)


// Class Methods
@IBAction func swiftButtonPress(sender : AnyObject) {

    statusLabel.text = "Authenticating"

    //Can we use local auth?
    if authContext.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &authError) {

        authContext.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics,
            localizedReason: "I need to see if it's really you",
            reply: {(success: Bool, error: NSError!) -> Void in

                if success {
                    self.statusText = "Touch ID success!"
                    self.alert.title = "Success"
                    self.alert.message = "I knew it was you!"
                } else {
                    self.statusText = "Touch ID failed!"
                    self.alert.title = "Failure"

                    switch error!.code {
                    case LAError.AuthenticationFailed.toRaw():
                        self.alert.message = "Authentication Failed"
                    case LAError.UserCancel.toRaw():
                        self.alert.message = "User canceled!"
                    case LAError.SystemCancel.toRaw():
                        self.alert.message = "The system canceled!"
                    case LAError.UserFallback.toRaw():
                        self.alert.message = "User request to enter passcode"
                    default:
                        self.alert.message = "Something else went wrong"
                    }
                }
                self.presentViewController(self.alert, animated: true, completion:{self.statusLabel.text = self.statusText})
            })
    } else {
        self.statusText = "No local authentication"
        alert.title = "Uh oh!"

        switch authError!.code {
        case LAError.TouchIDNotAvailable.toRaw():
            alert.message = "No Touch ID on device"
        case LAError.TouchIDNotEnrolled.toRaw():
            alert.message = "No fingers enrolled"
        case LAError.PasscodeNotSet.toRaw():
            alert.message = "No passcode set"
        default:
            alert.message = "Something went wrong getting local auth"
        }
        self.presentViewController(self.alert, animated: true, completion: {self.statusLabel.text = self.statusText})
    }
    resetTouchID()
}

// Reset the system so we can go again
func resetTouchID() {
    authContext = LAContext()
    alert = UIAlertController(title: "", message: "", preferredStyle: UIAlertControllerStyle.Alert)
    alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Cancel, handler: nil))
    let passcodeDetector = SwiftPasscodeDetector()
    if passcodeDetector.checkForPasscode() {
        headerString.text = "Passcode Set on Device"
    } else {
        headerString.text = "No Passcode Set"
    }

}

// Inherited Methods
override func viewDidLoad() {
    super.viewDidLoad()
    resetTouchID()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

Sign up to request clarification or add additional context in comments.

4 Comments

When I try this code it gives me a error which is "The code below crashes with the error "Terminating app due to uncaught exception 'NSInvalidArgumentException'" Have you encounter this before with this code?
I've not hit that no. This is not a complete project but just one view controller code. You would need to adopt it to your needs. There are several full projects on GitHub too.
What is the equivalent of this LAError.UserFallback.toRaw() in Objc ?
I had a crash due to newer swift using just an Error? instead of the older NSError?
2

The API name is LAContext, and it's in the docs right here. It's pretty sparse, but it does its job. The method you probably want is

evaluatePolicy(_ policy: LAPolicy,
    localizedReason localizedReason: String!, 
    reply reply: ((Bool, NSError!) -> Void)!)

The string argument is a subheader to display to the user, the reply is simply a callback block, and the policy currently has to be LAPolicy.DeviceOwnerAuthenticationWithBiometrics, but it appears the framework is there for other types of authentication in the future. Interesting...

Hope that helps! I tried on my phone because I was curious and it works wonderfully. Just make sure to query for ability to evaluate policy before you try to use it, in case it's on an older device.

5 Comments

I've tried that but it is giving me compile errors. Can you give me your evaluatePolicy line code that works?
@user3785085 It would be better if you provided what you have tried that is causing the compile errors. Just asking for code from people isn't cool.
Agreed with @Abizern. We're not here to write your code for you. That being said, the other person seems to have written you their code, so there you go. It's probably the closure block syntax messing you up.
Reading from actual code is easier to learn for me. I saw the sample code but it is only in Objective-C. I’m trying to translate the Objective-C code to Swift which I've added above.
I know that getting the closure block caused me a lot of heartburn, so just posting a sample would have helped me immensely. That said it's not a standalone bit of code, so you still need to read it and then adapt to your own needs. If you want a full project there are several on GitHub that you can take a look at.
2

The LAContext reference has method signatures in both Obj-C and Swift. Furthermore, if you ⌘-click on the LAContext class in your Swift code, you should be able to view the generated "header" for it in Swift.

Comments

2

Updated to Swift 3

static func authorizeWithTouchIDIfPossible(){
        let authContext = LAContext()
        var authError : NSError?
        if authContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &authError) {
            authContext.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "I need to see this", reply: { (success, error) in
                if success {
                    print("Touch ID success!")
                    DispatchQueue.main.async {
                        //Do stuff here
                    }
                } else {
                    print("Touch ID failed!")
                }}
            );
        } else {
            print("No local authentication")
        }
    }

Comments

1

Found it!

The link below is from a user named Shmoopi from Github. Shmoopi made the app to test the TouchID programmed in Swift.

https://github.com/Shmoopi/Swift-Touch-ID

Comments

0

Swift 3.0 in:

import UIKit
import LocalAuthentication

class ViewController: UIViewController
{
    @IBAction func TouchBtn(_ sender: AnyObject)
    {
        let context:LAContext = LAContext()

        if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error:nil)
        {
            context.evaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, localizedReason:"We Need Your Id", reply:{
                (wasSuccessful,Error) in
                if wasSuccessful
                {
                    print("Was a Sucess")
                }
                else
                {
                    print("Not Logged In")
                }

            })
        }

    }
}

Comments

0

Swift 5 :

import LocalAuthentication

func authenticateUser() {
    let context = LAContext()
    var error: NSError?

    if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
        let reason = "Identify yourself!"

        context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) {
            [unowned self] success, authenticationError in

            DispatchQueue.main.async {
                if success {
                    print("Success!")
                } else {
                    let ac = UIAlertController(title: "Authentication failed", message: "Sorry!", preferredStyle: .alert)
                    ac.addAction(UIAlertAction(title: "OK", style: .default))
                    self.present(ac, animated: true)
                }
            }
        }
    } else {
        let ac = UIAlertController(title: "Touch ID not available", message: "Your device is not configured for Touch ID.", preferredStyle: .alert)
        ac.addAction(UIAlertAction(title: "OK", style: .default))
        present(ac, animated: true)
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.