I'm trying to store an Integer and retrieve it using KeyChain.
This is how I save it:
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)
}
This is how I try to retrieve it:
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
}
I'm getting the following error:
Could not cast value of type '__NSCFNumber' to 'NSString'
I tried playing with the variables but without success.
You are storing a number, not a string, so you are getting back an NSNumber, not a string. The exception is pretty clear - you can't downcast an NSNumber to a String - you can use
stringValue()
to get the string representation of an NSNumberI've update Eric's version for Swift 3:
Example usage:
Roi Mulia's answer works very well, here's a version with a few minimal adjustments for Swift 2:
Example usage:
This is Sazzad Hissain Khan's answer rewritten for iOS without non-Swifty NS-prefixed attributes and a cleaner code.
Well, I just used out source etc and made my self nice helper : Enjoy!