Reputation: 1551
I'm trying to bridge my React-Native 0.33 code to a super simple Swift method, following this guide but all I'm getting is show:(NSString *)name is not a recognized Objective-C method
.
Here's my code:
import Foundation
@objc(SwitchManager)
class SwitchManager: NSObject {
@objc func show(name: String) -> Void {
NSLog("%@", name);
}
}
#import "RCTBridgeModule.h"
@interface RCT_EXTERN_MODULE(SwitchManager, NSObject)
RCT_EXTERN_METHOD(show:(NSString *)name)
@end
#import "RCTBridgeModule.h"
Then on my index.ios.js
file I'm importing SwitchManager with import { SwitchManager } from 'NativeModules';
and calling SwitchManager.show('One');
. This is where the error happened.
Not sure what's wrong.
Upvotes: 44
Views: 18657
Reputation: 312
If you have multiple parameters you have these options:
Objective-C:
RCT_EXTERN_METHOD(
addEvent
:(NSDictionary *) event
:(RCTPromiseResolveBlock) resolve
:(RCTPromiseRejectBlock) reject
)
Swift Option 1:
@objc
func addEvent(
_ event: NSDictionary,
_ resolve: RCTPromiseResolveBlock,
_ reject: RCTPromiseRejectBlock
) {...}
Swift Option 2:
@objc(addEvent:::)
func addEvent(
event: NSDictionary,
resolve: RCTPromiseResolveBlock,
reject: RCTPromiseRejectBlock
) {...}
Objective-C:
RCT_EXTERN_METHOD(
addEvent
:(NSDictionary *) event
rejecter :(RCTPromiseResolveBlock) resolve
resolver :(RCTPromiseRejectBlock) reject
)
Swift:
@objc
func addEvent(
_ event: NSDictionary,
resolver resolve: RCTPromiseResolveBlock,
rejecter reject: RCTPromiseRejectBlock
) {...}
Coming from JavaScript, Java and now programming React Native Modules, I think these labels do more harm then good, especially that the first label can't be set. Now everybody learning Objective C will wonder and hard learn this. At least they are optional in Objective C, but if you combine it with Swift it gets crazy again. Because everything does not make sense, I've tested every possible variation in XCode 15. I've lost at least two days on this and I hope it helps someone.
Upvotes: 1
Reputation: 2780
I had the same error because I had forgotten to put the decorator @objc before the function declaration
Upvotes: 2
Reputation: 1311
This is a part of Swift 3's changes and can be solved by adding an underscore:
import Foundation
@objc(SwitchManager)
class SwitchManager: NSObject {
@objc func show(_ name: String) {
NSLog("%@", name);
}
}
See Swift 3's 0046 Proposal: Establish consistent label behavior across all parameters including first labels that is called out in the Swift.org migration guide under "Consistent first argument labels".
Basically, how Objective-C sees Swift methods has changed with Swift 3.
EDIT: This is still the case in Swift 4, see docs here under Omitting Argument Labels.
Upvotes: 82
Reputation: 449
this worked for me in xcode 8.0 and swift 3
@objc func openPresentedViewController(_ name: String,name1: String,name2: String){
}
add _
to non labelled members
RCT_EXTERN_METHOD(methodName:(NSString *)name name1:(NSString *)name1 name2:(NSString *)name2)
as you can see in the objective c method name is nonlabeled parameter add _
to it in the swift method
Upvotes: 23
Reputation: 67
I was fighting with this issue all day. Resolved by setting the Swift Compiler to use Legacy versions (XCode 8 is prefers Swift 3), so in:
Build Settings > Scroll down to 'Use Legacy Swift Language Version' set as Yes.
Upvotes: 3