当我尝试获取我的keyChain值时,它返回一个包含以下内容的字符串:
Optional("[thing in the KeyChain]")
因此,我尝试使用循环删除“可选”:
var str = KeychainService.loadToken() for(var i = 0; i < 9 ; i++) { str[i] = "" }
但我得到一个错误:NSString没有名为“下标”的成员
KeychainService类:
import Foundation import Security let serviceIdentifier = "MySerivice" let userAccount = "authenticatedUser" let accessGroup = "MySerivice" // Arguments for the keychain queries let kSecClassValue = kSecClass.takeRetainedValue() as NSString let kSecAttrAccountValue = kSecAttrAccount.takeRetainedValue() as NSString let kSecValueDataValue = kSecValueData.takeRetainedValue() as NSString let kSecClassGenericPasswordValue = kSecClassGenericPassword.takeRetainedValue() as NSString let kSecAttrServiceValue = kSecAttrService.takeRetainedValue() as NSString let kSecMatchLimitValue = kSecMatchLimit.takeRetainedValue() as NSString let kSecReturnDataValue = kSecReturnData.takeRetainedValue() as NSString let kSecMatchLimitOneValue = kSecMatchLimitOne.takeRetainedValue() as NSString class KeychainService: NSObject { /** * Exposed methods to perform queries. * Note: feel free to play around with the arguments * for these if you want to be able to customise the * service identifier, user accounts, access groups, etc. */ internal class func saveToken(token: NSString) { self.save(serviceIdentifier, data: token) } internal class func loadToken() -> NSString? { var token = self.load(serviceIdentifier) return token } /** * Internal methods for querying the keychain. */ private class func save(service: NSString, data: NSString) { var dataFromString: NSData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) // Instantiate a new default keychain query var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPasswordValue, service, userAccount, dataFromString], forKeys: [kSecClassValue, kSecAttrServiceValue, kSecAttrAccountValue, kSecValueDataValue]) // Delete any existing items SecItemDelete(keychainQuery as CFDictionaryRef) // Add the new keychain item var status: OSStatus = SecItemAdd(keychainQuery as CFDictionaryRef, nil) } private class func load(service: NSString) -> String? { // Instantiate a new default keychain query // Tell the query to return a result // Limit our results to one item var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPasswordValue, service, userAccount, kCFBooleanTrue, kSecMatchLimitOneValue], forKeys: [kSecClassValue, kSecAttrServiceValue, kSecAttrAccountValue, kSecReturnDataValue, kSecMatchLimitValue]) var dataTypeRef :Unmanaged<AnyObject>? // Search for the keychain items let status: OSStatus = SecItemCopyMatching(keychainQuery, &dataTypeRef) let opaque = dataTypeRef?.toOpaque() var contentsOfKeychain: String? if let op = opaque? { let retrievedData = Unmanaged<NSData>.fromOpaque(op).takeUnretainedValue() // Convert the data retrieved from the keychain into a string contentsOfKeychain = NSString(data: retrievedData, encoding: NSUTF8StringEncoding) } else { println("Nothing was retrieved from the keychain. Status code \(status)") } return contentsOfKeychain } }
我只是不想删除str周围的Optional东西,还是有更好的方法呢?
我从以下代码中获取了代码:
http://matthewpalmer.net/blog/2014/06/21/example-ios-keychain-swift-save- query/
Optional("")之所以得到,是因为未解开可选值。您需要!在对象后面放一个,您将再也不会得到它Optional("")了。我会向您显示代码,但您没有向我们显示该print()语句。我在下面做了一些示例,尽管我没有尝试过,但我认为可以重现此问题。
Optional("")
!
print()
var value:String? value = "Hello, World" print("The Value Is \(value)") // Prints "The Value Is Optional(Hello, World)" print("The Value Is \(value!)")// Prints "The Value Is Hello, World"
我希望这能回答您的问题,或者至少可以为您指明正确的方向,只是问您是否需要更多信息或更好的例子。