I've defined a protocol with a protocol extension to simplify working with NSError
.
protocol NSErrorConvertible: RawRepresentable {
var domain: String { get }
var localizedDescription: String { get }
}
extension NSErrorConvertible where RawValue == Int {
func generateError(parameters parameters: [String] = []) -> NSError {
let error = self.generateError(format: self.localizedDescription, parameters: parameters)
return error
}
func generateError(format format: String, parameters: [String] = []) -> NSError {
let description = String(format: format, arguments: parameters) // <-- BREAK
let error = NSError(domain: self.domain, code: self.rawValue, localizedDescription: description)
return error
}
}
extension NSError {
convenience init(domain: String, code: Int, localizedDescription: String) {
let userInfo = [NSLocalizedDescriptionKey : localizedDescription]
self.init(domain: domain, code: code, userInfo: userInfo)
}
}
Here's how the protocol is used:
enum DefaultEngineErrors: Int, NSErrorConvertible {
case ImagesNotSupported
case FooDoesNotHaveABar
case NilBar
var domain: String { return "DefaultEngineErrors" }
var localizedDescription: String {
switch self {
case .ImagesNotSupported: return "%s: Images are not supported."
case .FooDoesNotHaveABar: return "%s: Foo does not have a bar."
case .NilBar: return "%s: The bar is nil."
}
}
}
And here is how the protocol extension methods are called:
let error = DefaultEngineErrors.FooDoesNotHaveABar.generateError(parameters: ["\(foo.id)"])
When this code is run, the debugger breaks on the line that builds the description in the second generateError
extension function and the following message is displayed in the debugger console:
fatal error: can't unsafeBitCast between types of different sizes
Note that if I replace the call to String(format:)
with just format
, everything works fine.
Q: What is wrong with what I've done here?
In addition to this, I can't examine the parameters in the protocol extension. The following message is displayed when I try:
(lldb) po format
error: <EXPR>:1:1: error: non-nominal type '$__lldb_context' (aka 'Self') cannot be extended
extension $__lldb_context {
^ ~~~~~~~~~~~~~~~
<EXPR>:15:5: error: value of type 'DefaultEngineErrors' has no member '$__lldb_wrapped_expr_54'
$__lldb_injected_self.$__lldb_wrapped_expr_54(
^~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
Swift string Array is not compatible with CVarArgType... or [CVarArgType]
try using.
Check this