[英]Why I cannot put the received (by the alamofire call) token in the keychain in my swift app?
I have a webservice that returns me some data like name
, login
and auth_token
. 我有一个Web服务,可以向我返回一些数据,例如
name
, login
和auth_token
。 So far I was saving name
and login
in the NSUserDefaults. 到目前为止,我已经保存了
name
并login
了NSUserDefaults。 Now I want to store safely also auth_token
, so I've decided to put it in the keychain. 现在,我还想安全地存储
auth_token
,因此我决定将其放入钥匙串中。 For that purpose I've decided to use https://github.com/matthewpalmer/Locksmith this plugin. 为此,我决定使用https://github.com/matthewpalmer/Locksmith这个插件。
So far my code looked like this: 到目前为止,我的代码如下所示:
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
}
}
}
but when I added this line: 但是当我添加这一行时:
try Locksmith.saveData(["auth_token": json["auth_token"]], forUserAccount: "my_auth_token")
right after this: 之后:
let defaults = NSUserDefaults.standardUserDefaults()
then I'm getting error on Alamofire.request
saying: 然后我在
Alamofire.request
上Alamofire.request
:
Cannot call value of non-function type 'NSHTTPURLResponse?'
So my question is - how can I save my auth_token
that comes from the webservice in the keychain? 所以我的问题是-如何将来自Web服务的
auth_token
保存在钥匙串中?
What you're running into is a type mismatch, and the unfortunate fact that the AlamoFire Request
class has both a function called response
, and a property called response
(of type NSHTTPURLResponse?
, look familiar =)) 您遇到的是类型不匹配,并且不幸的事实是AlamoFire
Request
类同时具有一个名为response
的函数和一个名为response
的属性(类型为NSHTTPURLResponse?
,看起来很熟悉=))
In your code you're calling try
, which requires the enclosing closure/function to be marked throws
, or you have to wrap your code in a do-catch
在您的代码中,您正在调用
try
,这需要将封闭的闭包/函数标记为throws
,或者您必须将代码包装在do-catch
So what the swift compiler is doing is inferring that the closure you are writing has throws
as part of its definition. 因此,swift编译器的工作是推断您正在编写的闭包已作为其定义的一部分
throws
。 This obviously doesn't match the definition of the closure that should be passed to the func response
, so it tries the other response
it can find, the property. 显然,这与应该传递给
func response
的闭包的定义不匹配,因此它将尝试找到的另一个 response
,即属性。 Then it just completely fails because you cannot try to 'call' an optional type. 然后它就完全失败了,因为您不能尝试“调用”可选类型。
You should add a do-catch inside your closure to handle the possible errors that Locksmith may throw. 您应该在闭包内部添加一个do-catch来处理Locksmith可能引发的错误。
Edit: In response to your comment. 编辑:回应您的评论。 You just need to wrap that call in a do catch to properly handle errors.
您只需要将该调用包装在do catch中即可正确处理错误。 See https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html for details on Swifts error handling model.
有关Swifts错误处理模型的详细信息,请参见https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html 。
As for which error to catch, just glancing through the Locksmith API, it can throw errors that it receives from the Keychain API. 至于要捕获的错误,只需浏览一下Locksmith API,它就会抛出从Keychain API接收到的错误。 Luckily they have defined the errors they throw here: https://github.com/matthewpalmer/Locksmith/blob/master/Source/LocksmithError.swift
幸运的是,他们已经在此处定义了抛出的错误: https : //github.com/matthewpalmer/Locksmith/blob/master/Source/LocksmithError.swift
As an example of what to write, it would just be something like this 作为写东西的一个例子,就是这样
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
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.