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

标签 ios swift alamofire keychain

我有一个网络服务可以返回一些数据,例如 nameloginauth_token。到目前为止,我在 NSUserDefaults 中保存了 namelogin。现在我也想安全地存储 auth_token,所以我决定把它放在钥匙串(keychain)中。为此,我决定使用 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 保存在钥匙串(keychain)中?

最佳答案

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

在您的代码中,您正在调用 try,这需要将封闭闭包/函数标记为 throws,或者您必须将代码包装在 中执行捕获

所以 swift 编译器正在做的是推断您正在编写的闭包将 throws 作为其定义的一部分。这显然与应传递给 func 响应 的闭包定义不匹配,因此它会尝试它能找到的其他 响应 ,属性(property)。然后它就完全失败了,因为你不能尝试“调用”可选类型。

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

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

至于要捕获哪个错误,只要浏览一下 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
            }

        }
}

关于ios - 为什么我不能将收到的(通过 alamofire 调用) token 放入我的 swift 应用程序的钥匙串(keychain)中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36800602/

相关文章:

ios - 我如何从 UITableViewCell 获取信息?

ios - 使用自定义呈现 Controller 时保留原始状态栏外观

ios - Xcode (Swift) 文档说将属性设置为 YES,但仅在设置为 true 时有效?

ios - 根据另一个数组的顺序对数组进行高效排序

ios - 在 Hapijs 后端处理 Alamofire 在 Swift 中发送的多部分/表单数据请求

XCode Playground 卡在异步代码上

ios - Objective-C解析Json并检查响应是否是对象数组中的单个对象

ios - 将标签栏添加到导航 Controller

ios - UIActivityViewController UIActivityViewControllerCompletionWithItemsHandler

swift - Alamofire、ObjectMapper、Realm --> 在 Realm 中保存响应数据