Ahh..thanks for the reply Zach. I didn’t actually see your reply until now.

I’ll see how I can adjust my code.

Thanks for this!


> On Sep 29, 2016, at 4:38 PM, Zach Waldowski <z...@waldowski.me> wrote:
> 
> 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 
>> <https://lists.swift.org/mailman/listinfo/swift-users>
> 

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to