使用Xcode 7 beta,Swift 2.0
我正在保存并将凭据加载到钥匙串,不知何故在加载时我得到“可选(值)”,看起来这实际上是字符串的一部分,因为它也在文本框中或在发送到API时显示
这就是我现在保存和加载凭据的方式,因为你看我已经做了很多额外的nil检查以确保它不是nil或者可选,它确实是过度使用解释标记......
func SaveCredentials(credentials : [String : String!]!) -> Bool
{
if(credentials.count == 2)
{
//only proceed when we have two keys: username and password
let username = credentials["username"]
let password = credentials["password"]
if let usernameStr = username
{//also tried username!=nil && password != nil
if let passwordStr = password
{ //usernameStr and passwordStr is of type String!
let NsDataUsername = usernameStr!.dataUsingEncoding(NSUTF8StringEncoding)
let NsDataPassword = passwordStr!.dataUsingEncoding(NSUTF8StringEncoding)
if(NsDataUsername != nil && NsDataPassword != nil)
{
LocalStorage.saveToKeyChain("username", data: NsDataUsername!)
LocalStorage.saveToKeyChain("password", data: NsDataPassword!)
return true
}
}
}
}
return false
}
func LoadCredentials() -> [String : String!]?
{
let NsDataUsername = LocalStorage.loadFromKeyChain("username")
let NsDataPassword = LocalStorage.loadFromKeyChain("password")
if(NsDataUsername != nil && NsDataPassword != nil)
{
let username : String! = String(NSString(data: NsDataUsername!, encoding: NSUTF8StringEncoding))
let password : String! = String(NSString(data: NsDataPassword!, encoding: NSUTF8StringEncoding))
if let usernameStr = username
{
if let passwordStr = password
{ // password is of type String!, passwordStr is of type String
var credentials : [String: String!] = [String : String]()
credentials["username"] = usernameStr
credentials["password"] = passwordStr
return credentials
}
}
}
return nil
}
当我发送给Api时,这是我的方法,也需要一个非可选的字符串。登录时,此方法可以正常工作,从文本字段中获取字符串,但在来自钥匙串时不会过滤掉“可选”。
func LoginUser(email : String!, password : String!)
{
print("LoginUser(email : \(email), password: \(password))")
var parameters = [String : AnyObject]()
parameters["UserName"] = email
parameters["Password"] = password
......
我发送到SaveCredentials方法的字符串与用户登录的字符串相同:
func LoginLocalAccount(email : String!, password : String!)
{
databaseAPI.LoginUser(email!, password: password!) //login goes just fine
saveCredentials(email!, password: password!) //manages to get Optional in it..
}
我怀疑这与保存和加载钥匙串有关,对于兴趣,this是我用来保存和加载钥匙串。
我想摆脱它们,因为当应用程序启动时,它会加载凭据并尝试登录我的API。当然我收到一个错误,即用户名不是有效的电子邮件,因为它是可选的(email@adress.com)
答案 0 :(得分:3)
你过度使用!
。你不需要它们。尝试更多地了解隐式解包的选项,期权,...你的代码是一团糟(没有冒犯,每个人的学习)。
返回您的可选问题,这是由以下行引起的:
let username : String! = String(NSString(data: NsDataUsername!, encoding: NSUTF8StringEncoding))
convenience init?(data: NSData, encoding: UInt)
- 内部部分使用可用的初始值设定项,因此,NSString?
是结果。然后使用可选String
初始化NSString?
也会生成可选项。但是,以这种方式完全没有任何意义。
第一部分 - 删除可选
使用新的guard
:
guard let loadedPassword = NSString(data: passwordData, encoding: NSUTF8StringEncoding) else {
fatalError("Ooops")
}
loadedPassword
现在包含NSString
(不是NSString?
)。
第二部分 - NSString
- > String
强>
您可能已阅读(如果没有,请阅读)Strings and Characters关于桥接,...如果您可以NSString
与String
自由交换,您可以认为自己已经完成了:
var dict = [String:String]()
dict["password"] = loadedPassword
不。它产生以下错误:
NSString
无法隐式转换为String
;你的意思是 使用'as'显式转换?
稍作改动,现在你已经完成了:
var dict = [String:String]()
dict["password"] = loadedPassword as String
完整示例
let password = "Hallo"
guard let passwordData = password.dataUsingEncoding(NSUTF8StringEncoding) else {
fatalError("Ooops")
}
// save/load to/from keychain
guard let loadedPassword = NSString(data: passwordData, encoding: NSUTF8StringEncoding) else {
fatalError("Ooops")
}
var dict = [String:String]()
dict["password"] = loadedPassword as String
print(dict) // "[password: Hallo]\n"