2

Say I have a class called ExampleClass.

Say I then write code like so:

@objc class ExampleClass: NSObject {}

With an ObjectiveC file header like so:

#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>

@interface RCT_EXTERN_MODULE(ExampleClass, NSObject)
@end

Which I then consume in my React Native app like so: console.log('exampleClass', React.NativeModules.ExampleClass);

Now compiling with react-native run-ios produces the following exceptions:

❌  Undefined symbols for architecture x86_64
> Symbol: `_OBJC_CLASS_$_ExampleClass`
> Referenced from: `l_OBJC_$_CATEGORY_ExampleClass_$_RCTExternModule in ExampleClass-2517576D7E90370.o



❌  ld: symbol(s) not found for architecture x86_64



❌  clang: error: linker command failed with exit code 1 (use -v to see invocation)


** BUILD FAILED **

While changing only the swift so that it reads:

@objc(ExampleClass)
class ExampleClass: NSObject {}

results in successful compilation. What is the difference between those two syntaxes? Why is the latter working while the former is not?

Abraham P
  • 15,029
  • 13
  • 58
  • 126
  • I think that `@objc(ExampleClass)` defines the class name to be `ExampleClass`, instead of the name mangled name wift would produce (e.g. `_OBJC_CLASS_$_ExampleClass`) – Alexander May 02 '18 at 17:46
  • Thanks! If you write that up as an answer I'll update/accept! – Abraham P May 02 '18 at 18:44

1 Answers1

2

The parameter to that @objc attribute specifies the name Swift will export to Objective C.

Configuring Swift Interfaces in Objective-C

In some cases, you need finer grained control over how your Swift API is exposed to Objective-C. You can use the @objc(name) attribute to change the name of a class, property, method, enumeration type, or enumeration case declaration in your interface as it’s exposed to Objective-C code.

For example, if the name of your Swift class contains a character that isn’t supported by Objective-C, you can provide an alternative name to use in Objective-C. If you provide an Objective-C name for a Swift function, use Objective-C selector syntax. Remember to add a colon (:) wherever a parameter follows a selector piece.

From Using Swift with Cocoa and Objective-C (Swift 4.1) > Swift Type Compatibility > Configuring Swift Interfaces in Objective-C

Alexander
  • 59,041
  • 12
  • 98
  • 151