Search code examples
c++swiftinterop

Cpp-Swift Interop fails with conformance to NSObject


I have a project where I m making direct swift calls from cpp as introduced in swift5.9. Below is my swift class whose method is being invoked on cpp.

import Foundation

public class MySwiftClass
{
   public static func testInterop () -> Void
   {
     NSLog("----------- hey --------")
   }
}

I m able to successfully invoke 'testInterop()' in cpp with the above class, however if I add conformance to NSObject in the 'MySwiftClass' class, then the swift call in the below cpp code fails with the error

No member named 'MySwiftClass' in namespace 'CoreModule'

where CoreModule is my swift target. Below is my Cpp code to invoke swift method:

#include "temp.hpp"
#include "CoreModule-Swift.h"

void
TempLogger::DisplayTempError ()
{
printf("\nthis is a temporary logger\n");

    CoreModule::MySwiftClass::testInterop ();
}

I m not able to identify why is adding the NSObject Conformance generating this error. Any help?


Solution

  • A few thoughts here:

    1. if you want to use Objective-C (sub)classes in your C++ code, you'll need to use Objective-C++ files, so you'll need to change the file extension to .mm
    2. Once you enter the Objective-C realm, there are no more namespaces, as Objective-C doesn't have support for them, so it's just MySwiftClass instead of CoreModule::MySwiftClass
    3. Objective-C classes use a different method dispatch mechanism, which is named message sending, and which has a different syntax: [MySwiftClass testInterop]
    4. In order to make the Swift functions available to Objective-C++, you'll need to either decorate them with @objc, or you can decorate the class with @objcMembers

    Assembling all the above, this is how your .mm file could look:

    #include "temp.hpp"
    #include "CoreModule-Swift.h"
    
    void
    TempLogger::DisplayTempError ()
    {
    printf("\nthis is a temporary logger\n");
    
        [MySwiftClass testInterop];
    }