ios_app/Shared/Services/KeychainService.swift
2025-06-10 05:23:59 +03:00

114 lines
3.9 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Foundation
import Security
//let username = "user1"
// Сохраняем токены
//KeychainService.shared.save("access_token_value", forKey: "access_token", service: username)
//KeychainService.shared.save("refresh_token_value", forKey: "refresh_token", service: username)
// Получаем токены
//let accessToken = KeychainService.shared.get(forKey: "access_token", service: username)
//let refreshToken = KeychainService.shared.get(forKey: "refresh_token", service: username)
// получение всех пользователей
//let users = KeychainService.shared.getAllServices()
//print("Все пользователи: \(users)")
// Удаление всех пользователей
//KeychainService.shared.deleteAll()
// удаление по одному
//KeychainService.shared.delete(forKey: "access_token", service: username)
//KeychainService.shared.delete(forKey: "refresh_token", service: username)
class KeychainService {
static let shared = KeychainService()
private init() {}
func save(_ value: String, forKey key: String, service: String) {
guard let data = value.data(using: .utf8) else { return }
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service, // ключ группировки
kSecAttrAccount as String: key,
kSecValueData as String: data
]
SecItemDelete(query as CFDictionary)
let status = SecItemAdd(query as CFDictionary, nil)
if status != errSecSuccess {
print("Error saving to Keychain: \(status)")
}
}
func get(forKey key: String, service: String) -> String? {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: key,
kSecReturnData as String: true,
kSecMatchLimit as String: kSecMatchLimitOne
]
var dataTypeRef: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &dataTypeRef)
if status == errSecSuccess,
let data = dataTypeRef as? Data,
let value = String(data: data, encoding: .utf8) {
return value
}
return nil
}
func getAllServices() -> [String] {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecReturnAttributes as String: true,
kSecMatchLimit as String: kSecMatchLimitAll
]
var result: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &result)
guard status == errSecSuccess, let items = result as? [[String: Any]] else {
return []
}
// Собираем все уникальные service (username)
var services = Set<String>()
for item in items {
if let service = item[kSecAttrService as String] as? String {
services.insert(service)
}
}
return Array(services)
}
func delete(forKey key: String, service: String) {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: key
]
SecItemDelete(query as CFDictionary)
}
/// Удалить все записи Keychain, сохранённые этим приложением
func deleteAll() {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword
]
let status = SecItemDelete(query as CFDictionary)
if status != errSecSuccess && status != errSecItemNotFound {
print("Error deleting all Keychain items: \(status)")
}
}
}