Swift错误处理 - Struct / Class vs Enum

时间:2015-12-17 14:10:08

标签: ios swift struct error-handling enums

我正在尝试模拟我正在消耗的API可能返回的错误以及可能的网络错误。

我正在努力弄清楚是否应该使用Struct/Class方法,其中每种类型的错误都建模为Struct/ClassEnum方法。

以下是需要考虑的一些注意事项:

  1. 根据出现的问题,相同的API调用可以使用不同的media-types(因此不同的JSON)返回不同的错误。所以我的错误有不同的属性。我不想将请求响应公开为简单的JSON对象/字典。
  2. 我希望客户端/服务器问题导致的错误也具有httpStatusCode属性(对于与无连接相关的错误,它将为nil)
  3. 我希望出现一个错误,指出正确的本地化消息存在连接问题。
  4. 我想对sync次调用(用于throws)和async调用(用作完成块中的参数)使用相同的错误
  5. 主要是因为第一个要求,很难弄清楚如何沿着Enum方向前进。但也许我错过了一些东西,也许仍有一些力量存在于我不知道的Enum类型中。

    任何建议都将受到高度赞赏。

2 个答案:

答案 0 :(得分:0)

根据您的最终目标(我有点不清楚),您可以对Struct / ClassEnum进行组合。

E.g。您可以创建一个包含您信息的Struct,然后创建一个Enum,其值为Struct。另外,如果需要,您可以在Enum中创建功能。 Swift中的Enums中有很多功能。

如果您愿意,还可以根据其他Enum制作具体的Enum值,甚至更改每个值所依赖的Struct / Class

有关Enums的更多信息,请查看apples documentation

答案 1 :(得分:0)

通常 enum 是处理 Swift 错误的最佳方法。要提供不同的类型,您可以使用关联值,对于本地化描述,您可以为枚举实现 LocalizedError 协议,例如:

enum NetworkError : Error, LocalizedError {
    case noInternet
    case httpStatus(Int)
    case unknown(Error)
    
    public var errorDescription: String? {
        switch self {
            case .noInternet:
                return "No Internet"
                
            case .httpStatus(let code):
                return "HTTP status code: \(code)"
                
            case .unknown(let error):
                return "Error: \(error)"
        }
    }
}

let err1 = NetworkError.noInternet
print(err1.localizedDescription)

let err2 = NetworkError.httpStatus(404)
print(err2.localizedDescription)

let err3 = NetworkError.unknown(error)
print(err3.localizedDescription)

/*
Prints:

No Internet
HTTP status code: 404
Error: error
*/

但如果您有错误的公共数据,您应该实现 struct 以保存您的错误类型所需的属性:

struct ResponseError: Error {
    enum ErrorType {
        case badStatusCode
        case noJson
        case invalidJson(Error)
    }

    let type: ErrorType
    let statusCode: Int
}

let err = ResponseError(type: .badStatusCode, statusCode: 404)

从文档中阅读更多关于:https://developer.apple.com/documentation/swift/error