问题
My App supports opening documents like images, pdfs from other apps. Tocuh Id is implemented as shown below, it is requested when app comes to foreground
NotificationCenter.default.addObserver(forName: .UIApplicationWillEnterForeground, object: nil, queue: .main) { (notification) in
LAContext().evaluatePolicy( .deviceOwnerAuthenticationWithBiometrics, localizedReason: "Request Touch ID", reply: { [unowned self] (success, error) -> Void in
if (success) {
} else {
}
})
Now requesting for Touch Id works fine when user opens the app from Background or relaunches. The issue occurs when the app is opened from other app like tapping on app URL, sharing documents from external app using "Copy to MyApp" option, where the AppDelegate's open url method is called as shown below
public func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
//validate and save url
return true
}
The issue is when the app is launched from external app, the above open url method is invoked and also the UIApplicationWillEnterForeground observer is also called as expected. But in that UIApplicationWillEnterForeground observer, LAContext().evaluatePolicy fails abruptly with an error "Caller moved to background."
Note, issue can be seen on iOS 11.0.3, 11.3 whereas it is not reproducible with iOS 11.4 or <11
回答1:
You need to add this when app is applicationDidBecomeActive
NotificationCenter.default.addObserver(forName: .UIApplicationDidBecomeActive, object: nil, queue: .main) { (notification) in
let context = LAContext()
var error: NSError?
if context.canEvaluatePolicy(
LAPolicy.deviceOwnerAuthenticationWithBiometrics,
error: &error) {
// Device can use biometric authentication
context.evaluatePolicy(
LAPolicy.deviceOwnerAuthenticationWithBiometrics,
localizedReason: "Access requires authentication",
reply: {(success, error) in
DispatchQueue.main.async {
if let err = error {
switch err._code {
case LAError.Code.systemCancel.rawValue:
self.notifyUser("Session cancelled",
err: err.localizedDescription)
case LAError.Code.userCancel.rawValue:
self.notifyUser("Please try again",
err: err.localizedDescription)
case LAError.Code.userFallback.rawValue:
self.notifyUser("Authentication",
err: "Password option selected")
// Custom code to obtain password here
default:
self.notifyUser("Authentication failed",
err: err.localizedDescription)
}
} else {
self.notifyUser("Authentication Successful",
err: "You now have full access")
}
}
})
}
})
来源:https://stackoverflow.com/questions/52379360/ios-touch-id-is-not-shown-when-appdelegates-open-url-is-invoked