// // Environment+Authenticate.swift // LoopKitUI // // Created by Rick Pasetto on 8/3/20. // Copyright © 2020 LoopKit Authors. All rights reserved. // import LocalAuthentication import SwiftUI public typealias AuthenticationChallenge = (_ description: String, _ completion: @escaping (Result) -> Void) -> Void fileprivate struct UnknownError: Swift.Error { } public struct LocalAuthentication { public static let deviceOwnerCheck: AuthenticationChallenge = { authenticationChallengeDescription, completion in let context = LAContext() var error: NSError? if context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) { context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: authenticationChallengeDescription, reply: { (success, error) in DispatchQueue.main.async { assert(success || error != nil) completion(success ? .success(()) : .failure(error ?? UnknownError())) } }) } else { // The logic here is to not fail to execute completion just because there is no authentication set up on the iPhone completion(.success(())) } } } private struct AuthenticationChallengeKey: EnvironmentKey { static let defaultValue: AuthenticationChallenge = LocalAuthentication.deviceOwnerCheck } extension EnvironmentValues { public var authenticate: AuthenticationChallenge { get { self[AuthenticationChallengeKey.self] } set { self[AuthenticationChallengeKey.self] = newValue } } }