在 Swift 中将可选绑定转换为错误处理的过程是什么?



我正在学习一个OAuth教程,该教程使用Locksmith框架来存储令牌。 本教程是用旧版本的 Swift 编写的,也是用旧版本的 Locksmith 框架编写的。 在 Swift 4 中重新创建示例时,我注意到 Locksmith 4.0 使用错误处理和 do try catch 块。 我正在尝试将本教程的可选绑定转换为使用框架的错误处理方法。 我首先自己尝试了它,但我无法在心理上联系为什么本教程使用可选绑定。

以下是教程的摘录:

var OAuthToken: String?
{
set
{
if let valueToSave = newValue
{
let error = Locksmith.saveData(["token": valueToSave], forUserAccount: "github")
if let errorReceived = error
{
Locksmith.deleteDataForUserAccount("github")
}
addSessionHeader("Authorization", value: "token (newValue)")      
}
else // they set it to nil, so delete it
{
Locksmith.deleteDataForUserAccount("github")
removeSessionHeaderIfExists("Authorization")
}
}
get
{
// try to load from keychain
let (dictionary, error) = Locksmith.loadDataForUserAccount("github")
if let token =  dictionary?["token"] as? String {
return token
}
removeSessionHeaderIfExists("Authorization")
return nil
}
}

这是我所拥有的。 我相信我滥用了与可选绑定相关的 catch 语句:

var OAuthTokenCompletionHandler: ((NSError?) -> Void)?
var authToken: String? {
set {
if let valueToSave = newValue{
do{
try Locksmith.saveData(data: ["token" : valueToSave], forUserAccount: "AzureMediaServices")
} catch {
//could not save the data into keychain
//handle the error somehow
try Locksmith.deleteDataForUserAccount(userAccount: "AzureMediaServices")
}
addSessionHeader("Authorization", value: "Bearer (valueToSave)")
} else {
//try to set it to nil
removeSessionHeaderIfExists("Authorization")
}
}
get {
//TODO: implement
}
}

我认为这里的主要问题是原始代码没有处理Locksmith.deleteDataForUserAccount的任何错误状态。Locksmith.deleteDataForUserAccount被调用了两次,并且此计算属性变得相当复杂。如果这两个函数调用的错误处理相同,我建议将其提取到帮助程序函数中。

这是我第一次尝试它:

var OAuthTokenCompletionHandler: ((NSError?) -> Void)?
var authToken: String? {
set {
guard let valueToSave = newValue else {
do {
try Locksmith.deleteDataForUserAccount(userAccount: "AzureMediaServices")
}
catch {
// handle the error somehow
}
removeSessionHeaderIfExists("Authorization")
return
}
do{
try Locksmith.saveData(data: ["token" : valueToSave], forUserAccount: "AzureMediaServices")
} catch {
do {
try Locksmith.deleteDataForUserAccount(userAccount: "AzureMediaServices")
}
catch {
// handle the error somehow
}
}
addSessionHeader("Authorization", value: "Bearer (valueToSave)")
}
get {
guard let token = Locksmith.loadDataForUserAccount("github")?["token"] as? String {
removeSessionHeaderIfExists("Authorization")
return nil
}
return token
}
}
var OAuthToken: String? {
set {
guard let newValue = newValue else {
let _ = try? Locksmith.deleteDataForUserAccount(userAccount: "github")
return
}
guard let _ = try? Locksmith.updateData(data: ["token": newValue],
forUserAccount: "github") else {
let _ = try? Locksmith.deleteDataForUserAccount(userAccount: "github")
return
}
}
get {
// try to load from keychain
let dictionary = Locksmith.loadDataForUserAccount(userAccount: "github")
return dictionary?["token"] as? String
}
}

最新更新