如何使用 RecoverableError 重试?

How to use RecoverableError to retry?

在Swift 3中,引入了RecoverableError protocol,但是关于如何使用它的文档很少。

这听起来像是为失败的进程提供重试功能的本机方式,这可能非常有用。如何使用它的示例是什么?

您可以利用 RecoverableError 的一件事是适用于 macOS 的基于文档的应用程序。

  1. 创建一个新项目,macOS > Cocoa,检查"Create Document-Based Application"。

  2. 自定义符合RecoverableError.

    的错误类型
    enum MyError {
        case documentSavingError
        //...
    }
    extension MyError: RecoverableError {
        var recoveryOptions: [String] {
            return [
                "Retry", "Ignore"
            ]
        }
    
        func attemptRecovery(optionIndex recoveryOptionIndex: Int) -> Bool {
            if recoveryOptionIndex == 0 {//for "Retry"
                var result = false
                switch self {
                case .documentSavingError:
                    //Attempt "Retry" recovery for the failed operation, and return the result
                    //...
                    print("assume recovery attempt successfully finished...")
                    result = true
                //...
                }
                return result
            } else if recoveryOptionIndex == 1 {//for "Ignore"
                return true
            }
            fatalError("something wrong...")
        }
    }
    
  3. 将Document.swift中的data(ofType:)方法修改为抛出错误

    override func data(ofType typeName: String) throws -> Data {
        //throw RecoverableError
        throw MyError.documentSavingError
    }
    
  4. 在当前基于文档的应用程序中,您还需要一招...

    创建一个新的 swift 代码到 subclass NSApplication.

    import AppKit
    
    @objc(Application)
    class Application: NSApplication {
        override func presentError(_ error: Error, modalFor window: NSWindow, delegate: Any?, didPresent didPresentSelector: Selector?, contextInfo: UnsafeMutableRawPointer?) {
            //print(error)
            let underlyingError = (error as NSError).userInfo[NSUnderlyingErrorKey] as? Error ?? error
            //print(underlyingError)
            super.presentError(underlyingError, modalFor: window, delegate: delegate, didPresent: didPresentSelector, contextInfo: contextInfo)
        }
    }
    

    当前基于文档的应用程序将抛出的 RecoverableError 包装在通常的 NSError 中,因此,如果没有这个,自动生成的 NSDocumentErrorRecoveryAttempter 将无法正常工作。

    不要忘记修改 Info.plist 以将此 class 指定为其主体 class。

  5. 构建和 运行 应用程序,然后在出现文档 window 时,文件 > 保存...,然后在保存 sheet 中单击保存.

    您可能会发现 RecoverableError 的工作方式...


因此,当您的应用已经实现 Error Handling Programming Guide 中描述的标准恢复功能时,RecoverableError 很有用。它的介绍说得很清楚:

Important: The NSError class is available on both OS X and iOS. However, the error-responder and error-recovery APIs and mechanisms are available only in the Application Kit (OS X).