KeychainUtil.swift 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. //
  2. // KeychanUtil.swift
  3. // CommonUtil
  4. //
  5. // Created by lijunjie on 15/11/12.
  6. // Copyright © 2015年 lijunjie. All rights reserved.
  7. //
  8. import Foundation
  9. public enum CommonUtilError: Error {
  10. case KeychainGetError
  11. case KeychainSaveError
  12. case KeychainDeleteError
  13. case KeychainUpdateError
  14. }
  15. public class KeychainUtil {
  16. static let share = KeychainUtil()
  17. private init () {}
  18. public func getBaseKeychainQueryWithAccount(account: String, service: String, accessGroup: String) -> [NSString : AnyObject] {
  19. var res = [NSString : AnyObject]()
  20. res[kSecClass] = kSecClassGenericPassword
  21. res[kSecAttrAccount] = account as AnyObject?
  22. res[kSecAttrService] = service as AnyObject?
  23. if !accessGroup.isEmpty {
  24. #if TARGET_IPHONE_SIMULATOR
  25. /*
  26. 如果在模拟器上运行,则忽略accessGroup
  27. 模拟器运行app没有签名, 所以这里没有accessGroup
  28. 在模拟器上运行时,所有的应用程序可以看到所有钥匙串项目
  29. 如果SecItem包含accessGroup,当SecItemAdd and SecItemUpdate时,将返回-25243 (errSecNoAccessForItem)
  30. */
  31. #else
  32. res[kSecAttrAccessGroup] = accessGroup as AnyObject?
  33. #endif
  34. }
  35. return res
  36. }
  37. public func getDataWithAccount(account: String, service: String, accessGroup: String) -> NSData? {
  38. var res: [NSString : AnyObject] = self.getBaseKeychainQueryWithAccount(account: account, service: service, accessGroup: accessGroup)
  39. res[kSecMatchCaseInsensitive] = kCFBooleanTrue
  40. res[kSecMatchLimit] = kSecMatchLimitOne
  41. res[kSecReturnData] = kCFBooleanTrue
  42. var queryErr: OSStatus = noErr
  43. var udidValue: NSData?
  44. var inTypeRef : AnyObject?
  45. queryErr = SecItemCopyMatching(res as CFDictionary, &inTypeRef)
  46. udidValue = inTypeRef as? NSData
  47. if (queryErr != errSecSuccess) {
  48. return nil
  49. }
  50. return udidValue
  51. }
  52. public func saveData(data: NSData, account: String, service:String, accessGroup: String) throws {
  53. var query : [NSString : AnyObject] = self.getBaseKeychainQueryWithAccount(account: account, service: service, accessGroup: accessGroup)
  54. query[kSecAttrLabel] = "" as AnyObject?
  55. query[kSecValueData] = data
  56. var writeErr: OSStatus = noErr
  57. writeErr = SecItemAdd(query as CFDictionary, nil)
  58. if writeErr != errSecSuccess {
  59. throw CommonUtilError.KeychainSaveError
  60. }
  61. }
  62. public func deleteDataWithAccount(account: String, service: String, accessGroup: String) throws {
  63. let dictForDelete: [NSString : AnyObject] = self.getBaseKeychainQueryWithAccount(account: account, service: service, accessGroup: accessGroup)
  64. var deleteErr: OSStatus = noErr
  65. deleteErr = SecItemDelete(dictForDelete as CFDictionary)
  66. if(deleteErr != errSecSuccess){
  67. throw CommonUtilError.KeychainDeleteError
  68. }
  69. }
  70. public func updateData(data: NSData, account:String, service:String, accessGroup:String) throws {
  71. var dictForQuery: [NSString : AnyObject] = self.getBaseKeychainQueryWithAccount(account: account, service: service, accessGroup: accessGroup)
  72. dictForQuery[kSecMatchCaseInsensitive] = kCFBooleanTrue
  73. dictForQuery[kSecMatchLimit] = kSecMatchLimitOne
  74. dictForQuery[kSecReturnData] = kCFBooleanTrue
  75. dictForQuery[kSecReturnAttributes] = kCFBooleanTrue
  76. var queryResultRef: AnyObject?
  77. SecItemCopyMatching(dictForQuery as CFDictionary, &queryResultRef)
  78. if queryResultRef != nil {
  79. var dictForUpdate: [NSString : AnyObject] = self.getBaseKeychainQueryWithAccount(account: account, service: service, accessGroup: accessGroup)
  80. dictForUpdate[kSecValueData] = data
  81. var updateErr: OSStatus = noErr
  82. updateErr = SecItemUpdate(dictForQuery as CFDictionary, dictForUpdate as CFDictionary)
  83. if (updateErr != errSecSuccess) {
  84. print("Update KeyChain Item Error!!! Error Code:%ld", updateErr)
  85. throw CommonUtilError.KeychainUpdateError
  86. }
  87. }
  88. }
  89. }
  90. public let SharedKeychanUtil: KeychainUtil = KeychainUtil.share