摆脱这些可选值
Get rid of these Optional values
使用 Xcode 7 测试版,Swift 2.0
我正在将凭据保存并加载到钥匙串,加载时不知何故我得到了 "Optional(value)",看起来这确实是字符串的一部分,因为它在文本框中或发送到时也显示为这样API
这就是我现在保存和加载凭据的方式,如您所见,我已经做了很多额外的 nil 检查以确保它不是 nil 或 Optional,这确实是对解释标记的过度使用...
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 时,这是我的方法,它也需要一个非可选字符串。此方法在登录时有效,从文本字段中获取字符串,但在来自钥匙串时不会过滤掉 Optional。
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..
}
我怀疑和keychain的保存和加载有关,为了兴趣,this是我用来保存和从keychain加载的
我想摆脱它们,因为当应用程序启动时,它会加载凭据并尝试登录我的 API。当然,我得到一个错误,用户名不是有效的电子邮件,因为它是 Optional(email@adress.com)
您过度使用 !
。你不需要它们。尝试了解更多关于隐式解包的可选值,可选值,......你的代码一团糟(没有冒犯,每个人都在学习)。
回到你的可选问题,它是由这一行引起的:
let username : String! = String(NSString(data: NsDataUsername!, encoding: NSUTF8StringEncoding))
convenience init?(data: NSData, encoding: UInt)
- 内部使用可失败初始化器,因此,NSString?
是结果。然后用可选的 NSString?
初始化 String
也会产生可选的。但是,这样做完全没有意义。
第一部分 - 删除可选
利用新 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
is not implicitly convertible to String
; did you mean to
use 'as' to explicitly convert?
稍微改变一下,现在你就完成了:
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"
使用 Xcode 7 测试版,Swift 2.0
我正在将凭据保存并加载到钥匙串,加载时不知何故我得到了 "Optional(value)",看起来这确实是字符串的一部分,因为它在文本框中或发送到时也显示为这样API
这就是我现在保存和加载凭据的方式,如您所见,我已经做了很多额外的 nil 检查以确保它不是 nil 或 Optional,这确实是对解释标记的过度使用...
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 时,这是我的方法,它也需要一个非可选字符串。此方法在登录时有效,从文本字段中获取字符串,但在来自钥匙串时不会过滤掉 Optional。
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..
}
我怀疑和keychain的保存和加载有关,为了兴趣,this是我用来保存和从keychain加载的
我想摆脱它们,因为当应用程序启动时,它会加载凭据并尝试登录我的 API。当然,我得到一个错误,用户名不是有效的电子邮件,因为它是 Optional(email@adress.com)
您过度使用 !
。你不需要它们。尝试了解更多关于隐式解包的可选值,可选值,......你的代码一团糟(没有冒犯,每个人都在学习)。
回到你的可选问题,它是由这一行引起的:
let username : String! = String(NSString(data: NsDataUsername!, encoding: NSUTF8StringEncoding))
convenience init?(data: NSData, encoding: UInt)
- 内部使用可失败初始化器,因此,NSString?
是结果。然后用可选的 NSString?
初始化 String
也会产生可选的。但是,这样做完全没有意义。
第一部分 - 删除可选
利用新 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
is not implicitly convertible toString
; did you mean to use 'as' to explicitly convert?
稍微改变一下,现在你就完成了:
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"