
У меня есть вход в систему, который использует распознавание лиц для аутентификации пользователя, и если пользователь аутентифицирован, он считывает его информацию для входа из связки ключей, если она сохранена.
По какой-то причине все эти функции не работает, я просмотрел некоторые другие потоки SO и не смог заставить его работать. Я думаю, что-то не так с функциями сохранения и чтения. Однако мне удалось заставить работать функцию аутентификации.
import SwiftUI
import LocalAuthentication
import AuthenticationServices
struct LogInView: View {
@State private var email = ""
@State private var password = ""
var body: some View {
ZStack(alignment: .top){
GeometryReader { geometry in
VStack {
HStack{
Button {
save(email: email, password: password)
} label: {
Text("Save password")
}
}.padding(.top, 10)
VStack(spacing: 15){
CustomTextField(imageName: "envelope", placeHolderText: "Email", text: $email)
CustomTextField(imageName: "lock", placeHolderText: "Password", isSecureField: true, text: $password)
}
}
}
}
.onAppear(perform: authenticate)
}
func save(email: String, password: String) {
let emailData = email.data(using: .utf8)!
let passwordData = password.data(using: .utf8)!
let query: [String: Any] = [
kSecClass as String: kSecClassInternetPassword,
kSecAttrService as String: "https://hustle.page",
kSecAttrAccount as String: emailData,
kSecValueData as String: passwordData
]
let saveStatus = SecItemAdd(query as CFDictionary, nil)
if saveStatus == errSecDuplicateItem {
update(email: email, password: password)
}
}
func update(email: String, password: String) {
let emailData = email.data(using: .utf8)!
let passwordData = password.data(using: .utf8)!
let query: [String: Any] = [
kSecClass as String: kSecClassInternetPassword,
kSecAttrService as String: "https://hustle.page",
kSecAttrAccount as String: emailData
]
let updatedData: [String: Any] = [
kSecValueData as String: passwordData
]
SecItemUpdate(query as CFDictionary, updatedData as CFDictionary)
}
func read(service: String) -> (String, String)? {
let query: [String: Any] = [
kSecClass as String: kSecClassInternetPassword,
kSecAttrService as String: service,
kSecReturnAttributes as String: true,
kSecReturnData as String: true,
kSecMatchLimit as String: kSecMatchLimitAll
]
var result: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &result)
if status == errSecSuccess, let items = result as? [[String: Any]], let item = items.first {
if let account = item[kSecAttrAccount as String] as? String,
let passwordData = item[kSecValueData as String] as? Data,
let password = String(data: passwordData, encoding: .utf8) {
return (account, password)
}
}
return nil
}
func authenticate() {
let context = LAContext()
var error: NSError?
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
let reason = "Secure Authentication."
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) { success, authenticationError in
if success {
if let loginInfo = read(service: "https://hustle.page") {
let (email, password) = loginInfo
}
}
}
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/766 ... -ios-swift
Мобильная версия