Error types themselves shouldn’t generally cross into Objective-C, because you don’t get interop; for that, we have Error, which crosses the bridge as NSError.
If it’s instructive to think of it this way, both Objective-C and Swift should define errors in their best native way, and use NSError. That’s, at least, the use case for CustomNSError and LocalizedError. If you’re primarily exporting errors from Objective-C to be “seen” in Swift, you want to look into the ns_error_domain attribute on the C side. This generates a good deal of the enum Code: Int boilerplate coming in to Swift, but it’s obnoxious to create those errors from Swift. If you’re primarily exporting errors from Swift to Objective-C, you can make any Swift type implement Error and CustomNSError, which can then cross the bridge. The happy path of full error interop in both directions is a little more complicated. Generally you have to start with one of the above approach and “mirror” some values in the other language. Consider the following as a slightly over-wrought example of having your cake and eating it too: extern NSString *const MyErrorDomain NS_REFINED_FOR_SWIFT; extern NSString *const MyErrorUserInfoStringKey NS_REFINED_FOR_SWIFT; typedef NS_ENUM(NSInteger, MyErrorCode) { MyErrorCodeOne, MyErrorCodeTwo, MyErrorCodeThree, } NS_REFINED_FOR_SWIFT; enum MyError: CustomNSError { case one(String) case two case three static var errorDomain: String { return __MyErrorDomain } var errorCode: Int { switch self { case .one: return __MyErrorCode.one.rawValue case .two: return __MyErrorCode.two.rawValue case .three: return __MyErrorCode.three.rawValue } } var errorUserInfo: [String: Any] { var userInfo = [String: Any]() if case let .one(string) = self { userInfo[__MyErrorUserInfoStringKey] = string } return userInfo } } > On Sep 29, 2016, at 1:17 PM, Ronak via swift-users <swift-users@swift.org > <mailto:swift-users@swift.org>> wrote: > > Hello all, > > We are proceeding to update all of our Swift code to Swift 3 now and had a > few questions about the proper way to implement Errors. We need these > entities to be available in Objective-C and they are actively being used in > Swift classes marked as @objc. > > I read: > https://github.com/apple/swift-evolution/blob/master/proposals/0112-nserror-bridging.md > > <https://github.com/apple/swift-evolution/blob/master/proposals/0112-nserror-bridging.md> > completely and came up with this implementation: > > > /// The enumeration of the possible error codes in the Foundation error domain > @objc public class FoundationError: NSObject, CustomNSError { > > /// The underlying error code > private let code: FoundationError.Code > > /// The type of an error code. > @objc public enum Code: Int { > > /// An ARCOperationCondition failed during evaluation > case operationConditionFailed = 10000 > > /// An ARCOperation failed during execution > case operationExecutionFailed = 10001 > } > > /// The domain of the error. > public static var errorDomain: String { > return "FoundationError" > } > > /// The error code within the given domain. > public var errorCode: Int { > return code.rawValue > } > > /// The user-info dictionary. > public let errorUserInfo: [String : Any] > > /// Initializes a new FoundationError with an empty userInfo dictionary > /// > /// - parameter code: one of the available error codes > /// > /// - returns: a new instance of FoundationError > public convenience init(code: FoundationError.Code) { > self.init(code: code, userInfo: [:]) > } > > /// Initializes a new FoundationError with an userInfo dictionary > /// > /// - parameter code: one of the available error codes > /// - parameter userInfo: the user-info dictionary > /// > /// - returns: a new instance of FoundationError > public init(code: FoundationError.Code, userInfo: [String : Any]) { > self.code = code > errorUserInfo = userInfo > } > > /// Computes whether two FoundationErrors are equal > /// > /// - parameter object: a FoundationError > /// > /// - returns: true, if the two errors are equal > public override func isEqual(_ object: Any?) -> Bool { > guard let object = object as? FoundationError else { return false } > > return errorCode == object.errorCode && > errorUserInfo.keys.elementsEqual(object.errorUserInfo.keys) > } > } > > My question is whether this is the correct way to do this now; or is there > another solution we should be doing? We would like to follow Swift Best > Practices here, but unfortunately, the documentation is quite vague on this > subject. > > > Thanks for your help! > > Ronak Patel > _______________________________________________ > swift-users mailing list > swift-users@swift.org <mailto:swift-users@swift.org> > https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users