0

I'm using a library exposing the following objective-c method:

- (void)signIn:(NSString *)username  password:(NSString *)password completion:(void (^)(User *user, NSError *error))completion;

I'd like to call the method from swift 3 like this:

sign(in: "abc",  password: "def") { (user: User?, error: NSError?) -> Void in
    // ...
}

The compiler raises the following error:

Cannot convert value of type '(User?, NSError?) -> Void' to expected argument type '((User?, Error?) -> Void)!'

What am I missing in this example?

2 Answers 2

2

When you're viewing the library's header in Xcode, hit the Related Items popup menu (the four-squares icon at the top left above the editor) and choose Generated Interface. That'll show you what the Swift interface to your ObjC code looks like, including the type signature for that closure parameter.

Most likely, it's something like @escaping (user: User?, error: Error?) -> Void. But that's just my guess from looking at it — read the generated interface be sure.

Note that:

  • Imported closures are assumed to be @escaping. (You don't have to write that at the use site when you create a closure to pass to your function, though.)
  • NSError pointers are generally translated to Error protocol references.
  • Whether the parameter types import as optional or non-optional depends on the nullability (or NS_ASSUME_NONNULL) annotations in the ObjC file.
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the hint with the generated interface. Unfortunately, it still doesn't solve the problem. Here is the output: open func log(in username: String!, password: String!, completion: (@escaping (User?, Error?) -> Swift.Void)!)
0

Xcode's autocomplete can help you a lot. Select the function from the popup menu, hit Tab to get the function signature, hit a few more Tabs until you arrive at the completion parameter then hit Enter. Here's what XCode give me:

instance.sign(in: String!, password: String!) { (User?, Error?) in
    // code
}

So you closure syntax would be something like:

instance.sign(in: String!, password: String!) { user, error in
    // code
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.