Reputation: 286
I defined a variable as a closure in Swift Class. My code works fine when variable is called from Swift class. But variable is not accessible from Objective C class. Other functions I am able to call though.
@objc class IAPHelper: NSObject {
static let shared = IAPHelper()
var purchaseStatusBlock: ((IAPHelperAlertType) -> Void)?
}
called from a swift class
IAPHelper.shared.purchaseStatusBlock = {[weak self] (type) in
guard let strongSelf = self else{ return }
if type == .purchased {
// show an alert
}
}
I tried to call variable purchaseStatusBlock from Objective C class
IAPHelper.shared.purchaseStatusBlock ,
Compiler Error :Property 'purchaseStatusBlock' not found on object of type 'IAPHelper *'
Here is my Objective C code:
#import "VMedu-Swift.h"
@interface FreeSubscriptionController ()
{
}
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *restoreBtn = [VMEduUtil roundBtnWithFrame:CGRectMake(hmBtn.frame.origin.x-20, hmBtn.frame.origin.y+10, 70, searchImg.size.height) title:@"Restore" cornerRadius:3 backgroundColor:[UIColor clearColor] target:IAPHelper.shared action:@selector(restorePurchase)];
restoreBtn.tintColor = [UIColor whiteColor];
[topBarView addSubview:restoreBtn];
IAPHelper.shared.purchaseStatusBlock ..... shows me error
}
@end
Another Swift Class PurchaseSubscriptionController which uses same closure variable purchaseStatusBlock works well. Here is my code
override func viewDidLoad() {
super.viewDidLoad()
IAPHelper.shared.fetchAvailableProducts()
IAPHelper.shared.purchaseStatusBlock = {[weak self] (type) in
guard let strongSelf = self else{ return }
if type == .purchased {
let alertView = UIAlertController(title: "", message: type.message(), preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .default, handler: { (alert) in
print("product purchased")
})
alertView.addAction(action)
strongSelf.present(alertView, animated: true, completion: nil)
}
}
}
Upvotes: 1
Views: 2696
Reputation: 47896
Seems you just need to explicitly annotate some properties and types with @objc
:
@objc public enum IAPHelperAlertType: Int {
case disabled
case restored
case purchased
func message() -> String{
switch self {
case .disabled:
return "Purchases are disabled in your device!"
case .restored:
return "You've successfully restored your purchase!"
case .purchased:
return "You've successfully bought this purchase!"
}
}
}
(Added :Int
as suggested by Xcode.)
class IAPHelper: NSObject {
@objc static let shared = IAPHelper()
@objc var purchaseStatusBlock: (@convention(block) (IAPHelperAlertType) -> Void)?
}
(Added two @objc
and @convention(block)
. @convention(block)
makes the closure type compatible with Objective-C blocks.)
With these changes above, you can write something like this in your Objective-C code:
IAPHelper.shared.purchaseStatusBlock(IAPHelperAlertTypeDisabled)
Upvotes: 3
Reputation: 20804
You are using wrong Objective-C
Code
add a @objc
in your enum declaration
@objc
enum IAPHelperAlertType : Int{
case aaaa
case bbbb
}
Replace this
IAPHelper.shared.purchaseStatusBlock ..... shows me error
with this
[[IAPHelper shared] setPurchaseStatusBlock:^(NSInteger inte) {
NSLog(@"test");
}];
Upvotes: 4