Swift语言操作keyChain
首先是保存数据
func saveData(){ let key = "name1" let value = "liu" let valueData = value.data(using: String.Encoding.utf8,allowLossyConversion: false) let service = Bundle.main.bundleIdentifier! //kSecAttrService该键值通常表示为应用bundle标识符的字符串 //kSecAttrAccount表示存贮数据对象的键,一般是账号 //kSecValueData该值通常是 kSecAttrAccount对应的数值 print("valueData:\(valueData)") let secItem = [ kSecClass as NSString:kSecClassGenericPassword as String, kSecAttrService as String : service, kSecAttrAccount as String : key, kSecValueData as String : valueData! ] as NSDictionary var requestResult : AnyObject? let status = Int(SecItemAdd(secItem,&requestResult)) switch status { case Int(errSecSuccess): print("成功") case Int(errSecDuplicateItem): print("重复插入") default: print("error") } }
查找数据的方式:直接查找value
let keyToSearchFor = "name1" let service = Bundle.main.bundleIdentifier! let query = [ kSecClass as NSString:kSecClassGenericPassword as String, kSecAttrService as String : service, kSecAttrAccount as String : keyToSearchFor, kSecReturnData as String : kCFBooleanTrue, ] as NSDictionary var valueAttributes : AnyObject? let results = SecItemCopyMatching(query, &valueAttributes) if results == Int(errSecSuccess) { if let resultsData = valueAttributes as? Data{ let value = String(data: resultsData, encoding: String.Encoding.utf8) print("---------------------------- \(value)") } }
查找其他的数据
let keyToSearchFor = "name1" let service = Bundle.main.bundleIdentifier! let query = [ kSecClass as NSString:kSecClassGenericPassword as String, kSecAttrService as String : service, kSecAttrAccount as String : keyToSearchFor, kSecReturnAttributes as String : kCFBooleanTrue, ] as NSDictionary var valueAttributes : AnyObject? let results = SecItemCopyMatching(query, &valueAttributes) if results == Int(errSecSuccess) { if let resultsDic = valueAttributes as? NSDictionary{ let username = resultsDic[kSecAttrAccount as String] as? String//name1 let accesGroup = resultsDic[kSecAttrAccessGroup as String] as? String let createDate = resultsDic[kSecAttrCreationDate as String] as? Date//日期 let serviceVlue = resultsDic[kSecAttrService as String] as? String print("username:\(username) accesGroup:\(accesGroup) createDate:\(createDate) serviceVlue:\(serviceVlue)") } }
warn: kSecReturnAttributes如果需要获取置顶属性的值,Birkin创建日期和修改日期,则需要向自添加这个属性,如果获取要是串存储的值,则需要是使用kSecReturnData
数据更新:
let keyToSearchFor = "name1" let service = Bundle.main.bundleIdentifier! let query = [ kSecClass as NSString:kSecClassGenericPassword as String, kSecAttrService as String : service, kSecAttrAccount as String : keyToSearchFor, ] as NSDictionary var valueAttributes : AnyObject? let results = SecItemCopyMatching(query, &valueAttributes) if results == Int(errSecSuccess) { let newData = "newdata".data(using: String.Encoding.utf8,allowLossyConversion: false) let update = [ kSecValueData as String:newData! ] as NSDictionary let updateed = SecItemUpdate(query, update) print("---------------------???:\(updateed)") if updateed == Int(errSecSuccess){ print("更新成功") }else{ print("更新失败") } }else{ print("没有查询到") }
数据删除:
let keyToSearchFor = "name1" let service = Bundle.main.bundleIdentifier! let query = [ kSecClass as NSString:kSecClassGenericPassword as String, kSecAttrService as String : service, kSecAttrAccount as String : keyToSearchFor, ] as NSDictionary let results = SecItemDelete(query) if results == Int(errSecSuccess) { print("删除成功") }else{ print("删除失败") }
warn:如果想多个项目使用一个chain,可以使用kSecAttrAccessGroup,但是前提是多个项目在一个team里面,这个配置的team的名字,boundleid就需要使用写入数据应用的bundle id就不能是当前应用的bundle id了
kSecAttrAccessGroup as String:""
对iCloud中钥匙串的读写可以使用在添加查询的字典中加入
kSecAttrSynchronizable as String:kCFBooleanTrue