简体   繁体   English

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

[英]What is the process to translate optional binding into error handling in Swift?

I'm working through an OAuth tutorial that uses the Locksmith framework to store tokens. 我正在研究使用Locksmith框架存储令牌的OAuth教程。 The tutorial is written in an older version of Swift and also with an older version of the Locksmith framework. 本教程使用Swift的较早版本以及Locksmith框架的较旧版本编写。 While recreating the example in Swift 4, I noticed Locksmith 4.0 uses error handling with do try catch blocks. 在Swift 4中重新创建示例时,我注意到Locksmith 4.0将错误处理与try try catch块一起使用。 I'm attempting to translate the tutorial's optional binding into using the framework's error handling approach. 我试图将本教程的可选绑定转换为使用框架的错误处理方法。 I first tried it on my own but I'm having trouble making the mental connection of why the tutorial uses optional binding. 我首先自己尝试了一下,但是我很难理解为什么本教程使用了可选绑定。

Here the excerpt from the tutorial: 这里是本教程的摘录:

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
  }
}

Here is what I have. 这就是我所拥有的。 I believe I'm misusing the catch statement in correlation to optional binding: 我相信我滥用了与可选绑定相关的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
        }
    }

I think the main issue here is that the original code did not handle any error states of Locksmith.deleteDataForUserAccount . 我认为这里的主要问题是原始代码没有处理Locksmith.deleteDataForUserAccount任何错误状态。 Locksmith.deleteDataForUserAccount is getting called twice, and this computed property is getting rather complex. Locksmith.deleteDataForUserAccount被调用两次,并且此计算属性变得相当复杂。 If the error handling for both of those function calls is the same, I would recommend extracting it into a helper function. 如果两个函数调用的错误处理相同,则建议将其提取到帮助函数中。

Here's my first stab at it: 这是我的第一个方法:

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
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM