Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling Objective-C from Swift class causing linker errors

I'm trying to use RFDuino Objective-C library in Swift. It all sounds simple, I have called Objective-C from Swift classes before, no problem. This time however I hit the brick wall.

Created header file. Added header files to it. Swift can see the classes no problem. Project compiles fine.

The problem during build appears just after I try to call any of Objective classes

for example:

    override func viewDidLoad() {
         super.viewDidLoad()

        let rfDuinoManager: RFduinoManager = RFduinoManager.sharedRFduinoManager()

}

Undefined symbols for architecture x86_64: "_OBJC_CLASS_$_RFduinoManager", referenced from: __TMaCSo14RFduinoManager in ViewController.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

enter image description here

Im not sure what Im missing here. Link to the project here. https://www.dropbox.com/s/rza1ce01g4q5lp6/SmartHomeHub-stackoverflow.zip?dl=0

Thanks in advance for help. Honestly loosing hope now and considering rewrite whole library to Swift

like image 824
Greg Lukosek Avatar asked Jul 25 '15 16:07

Greg Lukosek


People also ask

Can we use Swift class in Objective-C?

You can work with types declared in Swift from within the Objective-C code in your project by importing an Xcode-generated header file. This file is an Objective-C header that declares the Swift interfaces in your target, and you can think of it as an umbrella header for your Swift code.

Can you call Swift from Objective-C?

Call Swift from Objective-CThe Swift library cannot be directly called from Objective-C, since it is missing the required annotations in the code, and in many cases, modules do not inherit from NSObject, rather they use the native Swift data types.

Is Swift interoperability with Objective-C?

You can use all Objective-C code in Swift, and you can even use Swift in Objective-C. It's very crucial to be able to use the Cocoa framework. All of the code that is written in Objective-C is available for use in Swift, both Apple frameworks and third-party libraries as well.


2 Answers

The problem is how the rfduino folder was added to the project. So

  1. Remove rfduino folder (selecting rfduino folder in the project navigator panel on left and hit delete button, but when it asks to move it to the trash or just remove references, choose "remove references".

    enter image description here

  2. Your bridging header has an absolute path reference, I'd suggest removing that altogether by selecting it in build settings and hitting delete button:

    enter image description here

  3. Re-add rfduino files back to the project, this time, under "added folders" option, choose "create groups" rather than "create folder references". If you want it to prompt to create proper bridging header for you, don't select folder, but select the individual files:

    enter image description here

    Also make sure that SmartHomeHub is checked below.

  4. If you do that properly it will ask you to create bridging header automatically:

    enter image description here

  5. Go to this new bridging header and add your import lines again:

    enter image description here

like image 89
Rob Avatar answered Oct 31 '22 03:10

Rob


This is a linker error, not a compiler error. Are you sure the RFduino class (source or library) is included in your project (open the project membership panel on the right in Xcode and make sure the box is checked to include the library in your target).

If it is included, make sure it has x86_64 code compiled into it. It might be an iOS library and is just compiled for ARM. You can check by finding the binary and running lipo on it from the command line.

lipo -info [name of RFduinolibrary.a(dylib,whatever)]

it should show x86_64 as an architecture, ala:

Architectures in the file are: i386 x86_64

like image 31
par Avatar answered Oct 31 '22 05:10

par