摆脱这些可选值

时间:2015-07-13 12:37:52

标签: string swift nsstring optional swift2

使用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)

1 个答案:

答案 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关于桥接,...如果您可以NSStringString自由交换,您可以认为自己已经完成了:

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"