Did anybody have any luck with using LocalAuthentication from inside an iMessage extension?
In my case I'm trying to verify TouchID before showing details of a custom message in the expanded presenation style.
Here is what I do:
override func willBecomeActive(with conversation: MSConversation) {
guard let _ = conversation.selectedMessage else {
// no selected message show compose
presentViewController(for: conversation, with: presentationStyle)
return
}
// we need to show details of a selected message
self.authenticate { (error) in
guard error == nil else {
print(error)
return
}
self.presentViewController(for: conversation, with: .expanded)
}
}
func authenticate(completion: (NSError?)->()) {
let myContext = LAContext()
let myLocalizedReasonString = "Use TouchID to view details"
var authError: NSError? = nil
if myContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &authError) {
myContext.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: myLocalizedReasonString) { (success, evaluateError) in
if (success) {
completion(nil)
} else {
completion(evaluateError)
}
}
} else {
completion(authError)
}
}
When selecting a message to show details, the expanded mode appears before willBecomeActive() is called. Then the TouchID alert is presented but this causes the empty expanded message view to disappear. The completion block of authenticate() is not called regardless of if TouchID was successful or not.
When the user selects another message, the extension calls the completion handler from the previous try before calling authenticate() again. Unsurprisingly this causes a lot to break. Only way to get out of this loop is to kill Messages.app and restart.
Any ideas? Am I doing something wrong or is this intended functionality?