KeychainHelper.m 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. //
  2. // KeychainHelper.m
  3. // VclustersGemini
  4. //
  5. // Created by xd h on 2025/9/22.
  6. // Copyright © 2025 APPLE. All rights reserved.
  7. //
  8. #import "KeychainHelper.h"
  9. #import <Security/Security.h>
  10. @implementation KeychainHelper
  11. + (NSMutableDictionary *)getKeychainQuery:(NSString *)key {
  12. return [NSMutableDictionary dictionaryWithObjectsAndKeys:
  13. (id)kSecClassGenericPassword, (id)kSecClass,
  14. key, (id)kSecAttrService,
  15. key, (id)kSecAttrAccount,
  16. (id)kSecAttrAccessibleAfterFirstUnlock, (id)kSecAttrAccessible,
  17. nil];
  18. }
  19. + (BOOL)saveString:(NSString *)string forKey:(NSString *)key {
  20. // 先删除已存在的项目
  21. [self deleteStringForKey:key];
  22. NSMutableDictionary *keychainQuery = [self getKeychainQuery:key];
  23. NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
  24. [keychainQuery setObject:data forKey:(id)kSecValueData];
  25. OSStatus status = SecItemAdd((CFDictionaryRef)keychainQuery, NULL);
  26. return status == errSecSuccess;
  27. }
  28. + (NSString *)getStringForKey:(NSString *)key {
  29. NSString *ret = nil;
  30. NSMutableDictionary *keychainQuery = [self getKeychainQuery:key];
  31. [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
  32. [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
  33. CFDataRef keyData = NULL;
  34. if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == errSecSuccess) {
  35. @try {
  36. ret = [[NSString alloc] initWithData:(__bridge NSData *)keyData encoding:NSUTF8StringEncoding];
  37. }
  38. @catch (NSException *e) {
  39. NSLog(@"Unarchive of %@ failed: %@", key, e);
  40. }
  41. @finally {}
  42. }
  43. if (keyData) CFRelease(keyData);
  44. return ret;
  45. }
  46. + (BOOL)deleteStringForKey:(NSString *)key {
  47. NSMutableDictionary *keychainQuery = [self getKeychainQuery:key];
  48. OSStatus status = SecItemDelete((CFDictionaryRef)keychainQuery);
  49. return status == errSecSuccess;
  50. }
  51. @end