Have you tried explicitly casting the value to NSError when you pass it to Objective-C? I think it should work then.

    let myError: MyError = ...
    myObjCFunc(myError as NSError)

On 02/03/2017 17:29, Ronak via swift-users wrote:
Hi everyone,

It looks like I’m still having issues exposing a CustomNSError to
Objective-C. I am generating errors of this type in Swift and then
trying to bridge them in one direction over to Objective-C.
From Objective-C, this Error type is being exposed as a _SwiftValue.

Do I have to mark this error as @objc and switch to using a raw enum? If
so, I fail to see the benefit of using CustomNSError or any of the new
error related protocols from Swift -> Objective-C.

Here’s my implementation:

publicenumMyError: CustomNSError, Equatable{

  caseone([String: Any])

  casetwo([String: Any])

  casethree([String: Any])

  /// The domain of the error.
  publicstaticvarerrorDomain: String{
    return“MyError"
  }

  /// The error code within the given domain.
  publicvarerrorCode: Int{
    switchself{
    case.one:
      return50000
    case.two:
      return50001
    case.three:
      return50002
    }
  }

  /// The user-info dictionary.
  publicvarerrorUserInfo: [String: Any] {
    varuserInfo = [String: Any]()
    ifcaselet.one(info) = self{
      userInfo = info
    } elseifcaselet.two(info) = self{
      userInfo = info
    } elseifcaselet.three(info) = self{
      userInfo = info
    }

    returnuserInfo
  }
}

Thanks

Ronak

On Sep 29, 2016, at 5:46 PM, Ronak via swift-users
<swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

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
<mailto: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:

externNSString*constMyErrorDomain NS_REFINED_FOR_SWIFT;
externNSString*constMyErrorUserInfoStringKey NS_REFINED_FOR_SWIFT;

typedefNS_ENUM(NSInteger, MyErrorCode) {
    MyErrorCodeOne,
    MyErrorCodeTwo,
    MyErrorCodeThree,
} NS_REFINED_FOR_SWIFT;

enumMyError: CustomNSError{

    caseone(String)
    casetwo
    casethree

    staticvarerrorDomain: String{
        return__MyErrorDomain
    }

    varerrorCode: Int{
        switchself{
        case.one:
            return__MyErrorCode.one.rawValue
        case.two:
            return__MyErrorCode.two.rawValue
        case.three:
            return__MyErrorCode.three.rawValue
        }
    }

    varerrorUserInfo: [String: Any] {
        varuserInfo = [String: Any]()
        ifcaselet.one(string) = self{
            userInfo[__MyErrorUserInfoStringKey] = string
        }
        returnuserInfo
    }

}

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
 completely
and came up with this implementation:


/// The enumeration of the possible error codes in the Foundation
error domain
@objcpublicclassFoundationError: NSObject, CustomNSError{

    /// The underlying error code
    privateletcode: FoundationError.Code

    /// The type of an error code.
    @objcpublicenumCode: Int{

        /// An ARCOperationCondition failed during evaluation
        caseoperationConditionFailed = 10000

        /// An ARCOperation failed during execution
        caseoperationExecutionFailed = 10001
    }

    /// The domain of the error.
    publicstaticvarerrorDomain: String{
        return"FoundationError"
    }

    /// The error code within the given domain.
    publicvarerrorCode: Int{
        returncode.rawValue
    }

    /// The user-info dictionary.
    publicleterrorUserInfo: [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
    publicconvenienceinit(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
    publicinit(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
    publicoverridefuncisEqual(_object: Any?) -> Bool{
        guardletobject = object as? FoundationErrorelse{ returnfalse}

        returnerrorCode == 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
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to