0

I can't seem to figure out how to call an Objective-C block from Swift!

I have the following Objective-C method:

- (void)myMethod:(NSDictionary *)selection success:(MyBlock)success;

Where MyBlock is:

typedef void(^MyBlock)(BOOL success, NSDictionary* options);

It either complains it can't cast:

"Cannot convert value of type '(Bool, Dictionary<AnyHashable, Any>) -> ()' to expected argument type 'MyBlock!' (aka 'ImplicitlyUnwrappedOptional<(Bool, Optional<Dictionary<AnyHashable, Any>>) -> ()>')"

or I'm getting a SIGABRT when I try to call the method from Swift using any of the following:

myInstance.myMethod(myOptions) { (success, options) in
    ...
}

myInstance.myMethod(myOptions) { (success: Bool, options: Dictionary<AnyHashable, Any>?) in
    ...
}

myInstance.myMethod(myOptions) { (success: Bool!, options: [AnyHashable: Any]?) in
    ...
}

myInstance.myMethod(myOptions, success: { (success, options) in
    ...
})

myInstance.myMethod(myOptions, success: { (success, options) in
    ...
} as MyBlock)

myInstance.myMethod(myOptions, success: { (success: Bool, options: Dictionary<AnyHashable, Any>?) in
    ...
})

myInstance.myMethod(myOptions, success: { (success: Bool!, options: Dictionary<AnyHashable, Any>?) in
    ...
})

myInstance.myMethod(myOptions, success: { (success: Bool!, options: Dictionary<AnyHashable, Any>?) in
        ...
} as MyBlock)

myInstance.myMethod(myOptions, success: { (success: Bool!, options: [AnyHashable: Any]?) in
    ...
})

myInstance.myMethod(myOptions, success: { (success: Bool, options: [AnyHashable: Any]?) in
    ...
})

What do I do?

Chris Allinson
  • 1,837
  • 2
  • 26
  • 39
  • Could you please provide a minimal example project that lets us easily test and try things? – Alexander Jan 09 '18 at 00:01
  • I've uploaded a simple demo app to: https://github.com/ChrisAllinson/IosBridgeExample ... but it seems to work :| ... perhaps the issue with my other app is with the casting/assigning, as it does complain stating it's trying to cast to an "ImplicitlyUnwrappedOptional" ... thoughts? – Chris Allinson Jan 09 '18 at 01:17
  • What version of Swift are you running? This compiled just fine under Swift 3.2, the minimum version my version of Xcode supports – Alexander Jan 09 '18 at 02:32
  • Right, this simple demo app does work ... but another app I'm working on does not. I'm very puzzled, and am wondering why it thinks it is an "ImplicitlyUnwrappedOptional" ... anyone familiar with that? (Thanks for the help)! – Chris Allinson Jan 09 '18 at 02:42
  • Ohhh seems to work", didn't see that. What version of Swift is your original app using? `ImplicitluunwrappedOptional` was a type that existence [before Swift 3](https://github.com/apple/swift-evolution/blob/master/proposals/0054-abolish-iuo.md) – Alexander Jan 09 '18 at 02:55
  • The app is using Swift 3.2 ... spoke with someone else on my team and was advised to not use our old ApiManager, though that doesn't explain what it is expecting in "ImplicitlyUnwrappedOptional" – Chris Allinson Jan 09 '18 at 14:18
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/162830/discussion-between-alexander-and-chris-allinson). – Alexander Jan 09 '18 at 16:22

1 Answers1

0

The equivalent swift code of your MyBlock :

typedef void(^MyBlock)(BOOL success, NSDictionary* options)

- (void)myMethod:(NSDictionary *)selection success:(MyBlock)success;

is as follows:

public typealias MyBlock = (Bool, [String : Any]) -> (Void)

func myMethod(selection: [String : Any], success: MyBlock)

so when you use myMethod for example:

self.myMethod(selection: yourDictionary) { (success, options) -> (Void) in
     //handle here
}
Donal Lafferty
  • 5,807
  • 7
  • 43
  • 60
Ace Rivera
  • 620
  • 4
  • 14