Jhonsore
Jhonsore

Reputation: 1857

How to pass an Objective-C with callback to a Swift method?

I really don't know how to ask this question, but:

  1. I have a bridge between Objective-C and Swift

  2. In my Obj-C class I invoke my Swift class

IAPbridge = [[IAPBridge alloc] init];
[IAPbridge requestProducts];
  1. I have a swift class
public func requestProducts ()  {

}
  1. My Obj-C class should have a block to receive some data from the Swift class

  2. It should be something like this (this code is wrong, but something like what I think it should be)

Obj-C

[IAPbridge requestProducts:^(id *products) {
    NSLog(@"Response:%@", products);
}];

Swift

public typealias ProductsRequestCompletionHandler = (_ products: [SKProduct]?) -> Void
private var productsRequestCompletionHandler: ProductsRequestCompletionHandler?    

public func requestProducts (completionHandler)  {
    productsRequestCompletionHandler = completionHandler
    productsRequestCompletionHandler?(true, products)
}

So, any help?

Upvotes: 0

Views: 2064

Answers (1)

matt
matt

Reputation: 534925

This part is impossible as your spec stands:

productsRequestCompletionHandler?(true, products)

You cannot hand back two values if a ProductsRequestCompletionHandler takes only one value. So you will have to revise your definition of a ProductsRequestCompletionHandler.

We may then imagine that on the Swift side we have a class like this:

@objc class IAPBridge : NSObject {
    public typealias ProductsRequestCompletionHandler = (Bool, [SKProduct]?) -> Void
    @objc func requestProducts(_ ch:ProductsRequestCompletionHandler) {
        let products : [SKProduct]? = // whatever
        ch(true, products)
    }
}

Over on the Objective-C side, your class's .m file must import the implicitly generated bridging header:

#import "MyApp-Swift.h" // or whatever it is called

In the eyes of your Objective-C class, an IAPBridge has this method:

- (void)requestProducts:(SWIFT_NOESCAPE void (^ _Nonnull)(BOOL, NSArray<SKProduct *> * _Nullable))ch;

So now you just call it:

IAPBridge* b = [[IAPBridge alloc] init];
[b requestProducts:^(BOOL success, NSArray<SKProduct *> * products) {
    if (success) {
        NSLog(@"Thank you for the products! They are %@", products);
    } else {
        NSLog(@"%@", @"Darn, something went wrong");
    }
}];

Upvotes: 2

Related Questions