Search code examples
c++swiftobjective-cobjective-c++bridging-header

Import headers from c++ library in swift


I am learning how to communicate between swift and c++ for ios. As a first step I have looked on this example:

https://github.com/leetal/ios-cmake

There is an example-app that I have managed to compile and run. Took some time to get it to work. That is an objective-c project.

The next step is to create a new swift project and try and import the compiled library and use the headers in swift instead.

I have not managed to do that. I think the current problem is that I cannot include the header HelloWorldIOS.h.

import SwiftUI
import HelloWorldIOS.h <- No such module found

struct ContentView: View {
    var body: some View {
        Text(sayHello())
            .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

I have tried to create a bridging file example-Bridging-Header.h as suggested here: https://developer.apple.com/documentation/swift/importing-objective-c-into-swift

It looks like:

//
//  example-Bridging-Header.h
//  example-swift
//

#ifndef example_Bridging_Header_h
#define example_Bridging_Header_h

#import "HelloWorldIOS.h"

#endif /* example_Bridging_Header_h */

I have also added the path to the headers in Target - Build Settings - Header Search Paths

The Objective-C Bridging Header looks like example-swift/example-Bridging-Header.h.

Are there any good instructions for how to call c++ code from a compiled library? I hoped this example I found would be easy to get to work.

The comment below helped me plus that I had to link to libc++.tbd.


Solution

  • You don't import anything in your Swift code when Objective-C headers are imported in the bridging header. All public interfaces available from the imported files get available in the entire Swift module by default after that.


    Sample listing

    TDWObject.h

    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface TDWObject : NSObject
    
    - (void)someCPPCode;
    
    @end
    
    NS_ASSUME_NONNULL_END
    

    TDWObject.mm

    #include <iostream>
    
    #import "TDWObject.h"
    
    @implementation TDWObject
    
    - (void)someCPPCode {
        std::cout << "Hello from CPP cout" << std::endl;
    }
    
    @end
    

    Some-Bridging-Header.h

    #import "TDWObject.h"
    

    main.swift

    TDWObject().someCPPCode()
    

    Provided the main.swift file is the entry point of the program, it will print Hello from CPP cout.