let alicePass = UserPass(context: viewContext)
alicePass.companyID = companyA.companyID
alicePass.userName = "[email protected]"
alicePass.userPassword = "AliceSecretPass"
try viewContext.save()
// → Saved to Alice's Private Store → Alice's Private Database
let bobPass = UserPass(context: viewContext)
bobPass.companyID = companyA.companyID // Same company!
bobPass.userName = "[email protected]"
bobPass.userPassword = "BobSecretPass"
try viewContext.save()
// → Saved to Bob's Private Store → Bob's Private Database
import Security
func saveToKeychain(password: String, for account: String, service: String) {
let data = password.data(using: .utf8)!
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: account,
kSecAttrService as String: service,
kSecValueData as String: data,
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
SecItemDelete(query as CFDictionary) // Remove old
SecItemAdd(query as CFDictionary, nil) // Add new
}
func retrieveFromKeychain(for account: String, service: String) -> String? {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: account,
kSecAttrService as String: service,
kSecReturnData as String: true
]
var result: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &result)
guard status == errSecSuccess,
let data = result as? Data,
let password = String(data: data, encoding: .utf8) else {
return nil
}
return password
}
// Save UserPass entity without password
let userPass = UserPass(context: viewContext)
userPass.companyID = company.companyID
userPass.userName = "[email protected]"
// Don't set userPass.userPassword
// Store password in Keychain
saveToKeychain(
password: actualPassword,
for: "[email protected]",
service: "TheCompanyApp-\(company.companyID)"
)