Last active
October 5, 2016 15:54
-
-
Save orj/582521aaa56d74d60f7b31f774816f9e to your computer and use it in GitHub Desktop.
A protocol that can be adopted by ErrorType, RawRepresentable conforming types that provides a mechanism for providing NSError userInfo values.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// A protocol that can be adopted by ErrorType, RawRepresentable conforming types that | |
/// provides a mechanism for providing NSError userInfo values. | |
/// | |
/// There are nil returning default implementations of all of the members of this protocol. | |
protocol NSErrorUserInfoValueProviding { | |
var localizedDescription: String? { get } | |
var localizedFailureReason: String? { get } | |
var localizedRecoverySuggestion: String? { get } | |
var localizedRecoveryOptions: [String]? { get } | |
/// The returned object should conform to NSErrorRecoveryAttempting informal protocol. | |
var recoveryAttempter: AnyObject? { get } | |
var helpAnchor: String? { get } | |
} | |
// Default implementation through protocol extension. | |
extension NSErrorUserInfoValueProviding { | |
var localizedDescription: String? { | |
return nil | |
} | |
var localizedFailureReason: String? { | |
return nil | |
} | |
var localizedRecoverySuggestion: String? { | |
return nil | |
} | |
var localizedRecoveryOptions: [String]? { | |
return nil | |
} | |
var recoveryAttempter: AnyObject? { | |
return nil | |
} | |
var helpAnchor: String? { | |
return nil | |
} | |
} | |
private extension NSErrorUserInfoValueProviding { | |
func userInfoValue(forKey key: String) -> AnyObject? { | |
switch key { | |
case NSLocalizedDescriptionKey: return self.localizedDescription | |
case NSLocalizedFailureReasonErrorKey: return self.localizedFailureReason | |
case NSLocalizedRecoverySuggestionErrorKey: return self.localizedRecoverySuggestion | |
case NSLocalizedRecoveryOptionsErrorKey: return self.localizedRecoveryOptions | |
case NSRecoveryAttempterErrorKey: return self.recoveryAttempter | |
case NSHelpAnchorErrorKey: return self.helpAnchor | |
default: return nil | |
} | |
} | |
} | |
extension NSError { | |
/// Register a user info value providing error type. | |
static func registerUserInfoValueProvidingErrorType<T: protocol<RawRepresentable, | |
NSErrorUserInfoValueProviding, ErrorType> where T.RawValue == Int>(providerType: T.Type) { | |
self.setUserInfoValueProviderForDomain(String(reflecting: providerType)) { | |
(nsError, key) -> AnyObject? in | |
let error = providerType.init(rawValue: nsError.code) | |
return error?.userInfoValue(forKey: key) | |
} | |
} | |
} | |
/// A custom ErrorType that adopts the NSErrorUserInfoValueProviding protocol to | |
/// provide a failure reason and recovery suggestion. | |
/// | |
/// It is important that this ErrorType be marked as being exposed to Objective-C | |
/// via the @objc() attribute so that it is bridged through to NSError fully. | |
@objc(IBAMyCustomError) | |
enum MyCustomError : Int, ErrorType, NSErrorUserInfoValueProviding { | |
case ServersUnreachable = 1000 | |
case EverythingIsFullOfWoe = 1001 | |
var localizedFailureReason: String? { | |
switch self { | |
case .ServersUnreachable: | |
return NSLocalizedString("Servers are unreachable.", comment: "Servers unreachable failure reason.") | |
case .EverythingIsFullOfWoe: | |
return NSLocalizedString("Woe woe woe.", comment: "Full of woe error message.") | |
} | |
} | |
var localizedRecoverySuggestion: String? { | |
switch self { | |
case .ServersUnreachable: | |
return NSLocalizedString("Ensure you have Internet connectivity.", comment: "Pipes are clogged.") | |
case .EverythingIsFullOfWoe: | |
return NSLocalizedString("😩 😭.", comment: "Cry a bunch.") | |
} | |
} | |
} | |
// Register the ErrorType with NSError elsewhere in the codebase (eg, in the AppDelegate) | |
NSError.registerUserInfoValueProvidingErrorType(MyCustomError.self) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment