如何将 NSError.code 与 Swift 中的#defined 错误编号进行比较 5

How to compare NSError.code to #defined error number in Swift 5

我已经在 Objective-C 工作了几年,但我对 Swift 还是很陌生。

目前我正在努力将一些新的基于 Swift 5 的代码添加到现有的 Objective-C 项目中,该项目使用定义的错误代码常量和 NSError 对象来传播错误。

如何在 Swift 中使用 NSError.code

Objective-C 代码:

#define someStrangeError_Code   1000
typedef void(^CompletionHandler)(BOOL success, NSError *error);

...

- (void)doSomethingAsync:(CompletionHandler)completion {
    // ... do something

    if (errorOccured) {
        completion(false, [NSError errorWithDomain:@"MyErrorDomain" code:someStrangeError_Code userInfo:nil])
    } else {
        completion(true, nil)
    }

    ...
}    

[someObjc doSomethingAsync:^(BOOL success, NSError *error) {
    if (error != nil && error.code == someStrangeError_Code) {
        ....
    }
}];

Swift代码:

someObjc.doSomethingAsync(completion: { (success, error) in 
    if ((error as NSError?)?.code == someStrangeError_Code) {
        // ERROR
        // Binary operator '==' cannot be applied to operands of type 'Int?' and 'Int32'
    }
})

我知道 Swift 使用 Error 协议而不是 NSError。但是,NSError 符合 Error,因此使用 NSError 应该不是问题,对吗?

将一个简单的错误代码与一个常量进行比较应该不难,但我无法解决这个问题。

那么什么是正确的"Swift way"检查错误代码并避免

Binary operator '==' cannot be applied to operands of type 'Int?' and 'Int32'

C 整数作为 Int32 导入到 Swift,不能直接与可选的 Int? 进行比较。转换有帮助:

if ((error as NSError?)?.code == Int(someStrangeError_Code)) {
    // some strange error
}

或者,首先解包可选错误:

if let error = error {
    if (error as NSError).code == someStrangeError_Code {
        // some strange error
    } else {
        // some other error
    }
} else {
    // no error
}

另一种选择是将 (Objective-)C 定义更改为

#define someStrangeError_Code   1000L

用于 long int 常量,它作为 Int 导入到 Swift。然后您的原始 Swift 代码将再次编译。