为什么我不能将收到的(通过alamofire调用)令牌放入我的swift应用程序中的钥匙串中?

时间:2016-04-22 18:06:25

标签: ios swift alamofire keychain

我有一个网络服务,它会返回一些数据,例如nameloginauth_token。到目前为止,我在NSUserDefaults中保存了namelogin。现在我想安全地存储auth_token,所以我决定把它放在钥匙串中。为此,我决定使用https://github.com/matthewpalmer/Locksmith这个插件。

到目前为止,我的代码看起来像这样:

Alamofire.request(.POST, "\(serverURL)/authorization", parameters: params)
    .validate()
    .response { (request, response, data, error) in
        if(error != nil){
            print("error = \(error)") 
        }else{

            let username = json["name"]
            let login = json["login"]
            let auth_token = json["auth_token"]

            let defaults =  NSUserDefaults.standardUserDefaults()

            defaults.setObject(login, forKey: "login")
            defaults.setObject(username, forKey: "username")

            defaults.synchronize() 

            let sb = UIStoryboard(name: "Main", bundle: nil)
            if let tabBarVC = sb.instantiateViewControllerWithIdentifier("TabController") as? TabController {
                self.window!.rootViewController = tabBarVC
            }

        }
}

但是当我添加这一行时:

 try Locksmith.saveData(["auth_token": json["auth_token"]], forUserAccount: "my_auth_token") 

在此之后:

 let defaults =  NSUserDefaults.standardUserDefaults()

然后我在Alamofire.request说错误:

Cannot call value of non-function type 'NSHTTPURLResponse?'

所以我的问题是 - 如何保存来自钥匙串中的网络服务的auth_token

1 个答案:

答案 0 :(得分:1)

您遇到的是类型不匹配,以及AlamoFire Request类同时具有名为response的函数和名为response的属性的不幸事实(类型NSHTTPURLResponse?,看起来很熟悉=))

在您的代码中,您需要调用try,这需要将封闭的闭包/函数标记为throws,或者您必须将代码包装在do-catch

所以swift编译器正在做的是推断你正在编写的闭包有throws作为其定义的一部分。这显然与应该传递给func response的闭包的定义不匹配,因此它会尝试它可以找到的其他 response属性。然后它完全失败,因为你不能试着打电话给#39;可选类型。

你应该在你的闭包中添加一个do-catch来处理Locksmith可能抛出的错误。

编辑:回复您的评论。您只需将该调用包装在do catch中以正确处理错误。有关Swifts错误处理模型的详细信息,请参阅https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html

至于要捕获的错误,只需浏览一下Locksmith API,它就会抛出从Keychain API收到的错误。幸运的是,他们已经定义了他们在这里抛出的错误:https://github.com/matthewpalmer/Locksmith/blob/master/Source/LocksmithError.swift

作为写什么的例子,它就像这样

Alamofire.request(.POST, "\(serverURL)/authorization", parameters: params)
    .validate()
    .response { (request, response, data, error) in
        if(error != nil){
            print("error = \(error)") 
        }else{

            let username = json["name"]
            let login = json["login"]
            let auth_token = json["auth_token"]

            let defaults =  NSUserDefaults.standardUserDefaults()
            do {
                try Locksmith.saveData(["auth_token": json["auth_token"]], forUserAccount: "my_auth_token")
            } catch {
                // Handle the error, however you best see fit
                print("Error trying to save to keychain \(error)")
            }

            defaults.setObject(login, forKey: "login")
            defaults.setObject(username, forKey: "username")

            defaults.synchronize() 

            let sb = UIStoryboard(name: "Main", bundle: nil)
            if let tabBarVC = sb.instantiateViewControllerWithIdentifier("TabController") as? TabController {
                self.window!.rootViewController = tabBarVC
            }

        }
}