Roi*_*lia 14 keychain nskeyedarchiver ios swift
我正在尝试存储一个Integer并使用KeyChain检索它.
这是我保存它的方式:
func SaveNumberOfImagesTaken()
{
let key = "IMAGE_TAKEN"
var taken = 10
let data = NSKeyedArchiver.archivedDataWithRootObject(taken)
let query : [String:AnyObject] = [
kSecClass as String : kSecClassGenericPassword,
kSecAttrAccount as String : key,
kSecValueData as String : data
]
let status : OSStatus = SecItemAdd(query as CFDictionaryRef, nil)
}
Run Code Online (Sandbox Code Playgroud)
这是我尝试检索它的方式:
func CheckIfKeyChainValueExitss() -> AnyObject? {
var key = "IMAGE_TAKEN"
let query : [String:AnyObject] = [
kSecClass as String : kSecClassGenericPassword,
kSecAttrAccount as String : key,
kSecReturnData as String : kCFBooleanTrue,
kSecMatchLimit as String : kSecMatchLimitOne ]
var dataTypeRef :Unmanaged<AnyObject>?
let status: OSStatus = SecItemCopyMatching(query, &dataTypeRef)
if let op = dataTypeRef?.toOpaque() {
let data = Unmanaged<NSData>.fromOpaque(op).takeUnretainedValue()
if let string: AnyObject? = NSKeyedUnarchiver.unarchiveObjectWithData(data) as? AnyObject? {
if key == "IMAGE_TAKEN"
{
return string as! String!
}
else if string == nil
{
return nil
}
}
}
return nil
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
无法将"__NSCFNumber"类型的值转换为"NSString"
我试过玩变量但没有成功.
Kos*_*awa 27
我更新了Eric的Swift 3版本:
class KeyChain {
class func save(key: String, data: Data) -> OSStatus {
let query = [
kSecClass as String : kSecClassGenericPassword as String,
kSecAttrAccount as String : key,
kSecValueData as String : data ] as [String : Any]
SecItemDelete(query as CFDictionary)
return SecItemAdd(query as CFDictionary, nil)
}
class func load(key: String) -> Data? {
let query = [
kSecClass as String : kSecClassGenericPassword,
kSecAttrAccount as String : key,
kSecReturnData as String : kCFBooleanTrue!,
kSecMatchLimit as String : kSecMatchLimitOne ] as [String : Any]
var dataTypeRef: AnyObject? = nil
let status: OSStatus = SecItemCopyMatching(query as CFDictionary, &dataTypeRef)
if status == noErr {
return dataTypeRef as! Data?
} else {
return nil
}
}
class func createUniqueID() -> String {
let uuid: CFUUID = CFUUIDCreate(nil)
let cfStr: CFString = CFUUIDCreateString(nil, uuid)
let swiftString: String = cfStr as String
return swiftString
}
}
extension Data {
init<T>(from value: T) {
var value = value
self.init(buffer: UnsafeBufferPointer(start: &value, count: 1))
}
func to<T>(type: T.Type) -> T {
return self.withUnsafeBytes { $0.load(as: T.self) }
}
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
class KeyChain {
class func save(key: String, data: Data) -> OSStatus {
let query = [
kSecClass as String : kSecClassGenericPassword as String,
kSecAttrAccount as String : key,
kSecValueData as String : data ] as [String : Any]
SecItemDelete(query as CFDictionary)
return SecItemAdd(query as CFDictionary, nil)
}
class func load(key: String) -> Data? {
let query = [
kSecClass as String : kSecClassGenericPassword,
kSecAttrAccount as String : key,
kSecReturnData as String : kCFBooleanTrue,
kSecMatchLimit as String : kSecMatchLimitOne ] as [String : Any]
var dataTypeRef: AnyObject? = nil
let status: OSStatus = SecItemCopyMatching(query as CFDictionary, &dataTypeRef)
if status == noErr {
return dataTypeRef as! Data?
} else {
return nil
}
}
class func createUniqueID() -> String {
let uuid: CFUUID = CFUUIDCreate(nil)
let cfStr: CFString = CFUUIDCreateString(nil, uuid)
let swiftString: String = cfStr as String
return swiftString
}
}
extension Data {
init<T>(from value: T) {
var value = value
self.init(buffer: UnsafeBufferPointer(start: &value, count: 1))
}
func to<T>(type: T.Type) -> T {
return self.withUnsafeBytes { $0.pointee }
}
}
Run Code Online (Sandbox Code Playgroud)
好吧,我只是用掉了源代码等,让我自己成为了一个很好的帮手:享受吧!
class func save(key: String, data: NSData) {
let query = [
kSecClass as String : kSecClassGenericPassword as String,
kSecAttrAccount as String : key,
kSecValueData as String : data ]
SecItemDelete(query as CFDictionaryRef)
let status: OSStatus = SecItemAdd(query as CFDictionaryRef, nil)
}
class func load(key: String) -> NSData? {
let query = [
kSecClass as String : kSecClassGenericPassword,
kSecAttrAccount as String : key,
kSecReturnData as String : kCFBooleanTrue,
kSecMatchLimit as String : kSecMatchLimitOne ]
var dataTypeRef :Unmanaged<AnyObject>?
let status: OSStatus = SecItemCopyMatching(query, &dataTypeRef)
if status == noErr {
return (dataTypeRef!.takeRetainedValue() as! NSData)
} else {
return nil
}
}
class func stringToNSDATA(string : String)->NSData
{
let _Data = (string as NSString).dataUsingEncoding(NSUTF8StringEncoding)
return _Data!
}
class func NSDATAtoString(data: NSData)->String
{
var returned_string : String = NSString(data: data, encoding: NSUTF8StringEncoding)! as String
return returned_string
}
class func intToNSDATA(r_Integer : Int)->NSData
{
var SavedInt: Int = r_Integer
let _Data = NSData(bytes: &SavedInt, length: sizeof(Int))
return _Data
}
class func NSDATAtoInteger(_Data : NSData) -> Int
{
var RecievedValue : Int = 0
_Data.getBytes(&RecievedValue, length: sizeof(Int))
return RecievedValue
}
class func CreateUniqueID() -> String
{
var uuid: CFUUIDRef = CFUUIDCreate(nil)
var cfStr:CFString = CFUUIDCreateString(nil, uuid)
var nsTypeString = cfStr as NSString
var swiftString:String = nsTypeString as String
return swiftString
}
//EXAMPLES
//
// //Save And Parse Int
// var Int_Data = KeyChain.intToNSDATA(555)
// KeyChain.save("MAMA", data: Int_Data)
// var RecievedDataAfterSave = KeyChain.load("MAMA")
// var NSDataTooInt = KeyChain.NSDATAtoInteger(RecievedDataAfterSave!)
// println(NSDataTooInt)
//
//
// //Save And Parse String
// var string_Data = KeyChain.stringToNSDATA("MANIAK")
// KeyChain.save("ZAHAL", data: string_Data)
// var RecievedDataStringAfterSave = KeyChain.load("ZAHAL")
// var NSDATAtoString = KeyChain.NSDATAtoString(RecievedDataStringAfterSave!)
// println(NSDATAtoString)
Run Code Online (Sandbox Code Playgroud)
这是Sazzad Hissain Khan为 iOS 重写的答案,没有非 Swifty NS 前缀的属性和更清晰的代码。
import Security
class KeychainService {
class func updatePassword(service: String, account: String, data: String) {
guard let dataFromString = data.data(using: .utf8, allowLossyConversion: false) else {
return
}
let status = SecItemUpdate(modifierQuery(service: service, account: account), [kSecValueData: dataFromString] as CFDictionary)
checkError(status)
}
class func removePassword(service: String, account: String) {
let status = SecItemDelete(modifierQuery(service: service, account: account))
checkError(status)
}
class func savePassword(service: String, account: String, data: String) {
guard let dataFromString = data.data(using: .utf8, allowLossyConversion: false) else {
return
}
let keychainQuery: [CFString: Any] = [kSecClass: kSecClassGenericPassword,
kSecAttrService: service,
kSecAttrAccount: account,
kSecValueData: dataFromString]
let status = SecItemAdd(keychainQuery as CFDictionary, nil)
checkError(status)
}
class func loadPassword(service: String, account: String) -> String? {
var dataTypeRef: CFTypeRef?
let status = SecItemCopyMatching(modifierQuery(service: service, account: account), &dataTypeRef)
if status == errSecSuccess,
let retrievedData = dataTypeRef as? Data {
return String(data: retrievedData, encoding: .utf8)
} else {
checkError(status)
return nil
}
}
fileprivate static func modifierQuery(service: String, account: String) -> CFDictionary {
let keychainQuery: [CFString: Any] = [kSecClass: kSecClassGenericPassword,
kSecAttrService: service,
kSecAttrAccount: account,
kSecReturnData: kCFBooleanTrue]
return keychainQuery as CFDictionary
}
fileprivate static func checkError(_ status: OSStatus) {
if status != errSecSuccess {
if #available(iOS 11.3, *),
let err = SecCopyErrorMessageString(status, nil) {
print("Operation failed: \(err)")
} else {
print("Operation failed: \(status). Check the error message through https://osstatus.com.")
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Roi Mulia 的回答非常有效,这是一个对 Swift 2 进行了一些最小调整的版本:
class KeyChain {
class func save(key: String, data: NSData) -> OSStatus {
let query = [
kSecClass as String : kSecClassGenericPassword as String,
kSecAttrAccount as String : key,
kSecValueData as String : data ]
SecItemDelete(query as CFDictionaryRef)
return SecItemAdd(query as CFDictionaryRef, nil)
}
class func load(key: String) -> NSData? {
let query = [
kSecClass as String : kSecClassGenericPassword,
kSecAttrAccount as String : key,
kSecReturnData as String : kCFBooleanTrue,
kSecMatchLimit as String : kSecMatchLimitOne ]
var dataTypeRef:AnyObject? = nil
let status: OSStatus = SecItemCopyMatching(query, &dataTypeRef)
if status == noErr {
return (dataTypeRef! as! NSData)
} else {
return nil
}
}
class func stringToNSDATA(string : String)->NSData
{
let _Data = (string as NSString).dataUsingEncoding(NSUTF8StringEncoding)
return _Data!
}
class func NSDATAtoString(data: NSData)->String
{
let returned_string : String = NSString(data: data, encoding: NSUTF8StringEncoding)! as String
return returned_string
}
class func intToNSDATA(r_Integer : Int)->NSData
{
var SavedInt: Int = r_Integer
let _Data = NSData(bytes: &SavedInt, length: sizeof(Int))
return _Data
}
class func NSDATAtoInteger(_Data : NSData) -> Int
{
var RecievedValue : Int = 0
_Data.getBytes(&RecievedValue, length: sizeof(Int))
return RecievedValue
}
class func CreateUniqueID() -> String
{
let uuid: CFUUIDRef = CFUUIDCreate(nil)
let cfStr:CFString = CFUUIDCreateString(nil, uuid)
let nsTypeString = cfStr as NSString
let swiftString:String = nsTypeString as String
return swiftString
}
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
let data = KeyChain.intToNSDATA(555)
let status = KeyChain.save("MyNumber", data: data)
print(status)
if let receivedData = KeyChain.load("MyNumber") {
let result = KeyChain.NSDATAtoInteger(receivedData)
print(result)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
14224 次 |
最近记录: |