Using static binaries with C++ interoperability

Hi there,
I am trying to remove the Qt + ObjC++ layer from our app, which was bridging to a pure C++ codebase. This pure C++ codebase already an Xcode project, which generates a static library (.a) file and the respective headers. Unfortunately, the codebase in this C++ layer is really messy, and I have quite limited C++ knowledge.

My ultimate goal would be to use that static library in our iOS codebase.
What I was thinking that for me it seems that the preferred way to add a static library would be via XCFramework and package it into a Swift Package (Distributing binary frameworks as Swift packages | Apple Developer Documentation). I managed to build an XCFramework, but I got stuck on the Package description, since the binary target has no swiftSettings parameters, where the interoperabilty mode can be defined. I was also thinking to add another target and product into the same Swift Package, where I might be able to create a simple Swift bridge file to expose the binary framework APIs.

I am not sure if I am heading to the right directon, or even this configuration is available at the moment under the C++ interop scope?

I would really appreciate any help on the topic.

If I'm not mistaken, you can just set the interoperability mode at the place where you're importing the XCFramework and that would be it.

However, I do recommend abstracting away the C++ code base completely:

  1. Create an XCFramework from the C++ code base. This can be done without using Swift-related tools whatsoever, allowing one to use any build system necessary.
  2. Create a Swift package with a library target that depends on that XCFramework, uses C++ interoperability mode, and does a @_exported import MyCppLib.
  3. Optionally, add custom Swift code there to augment the C++ code with custom wrappers and adapters to make the imported C++ code more idiomatic in Swift.
  4. Use this new package as a dependency for your app instead of the original XCFramework. All the responsibility for interfacing with C++ is now abstracted away in the new package, so no need to handle it in a special way.

Hope this helps!

1 Like

Thanks @technogen! Indeed, just figured out that in my case the Swift Package is really the messenger, so it doesn't know about the internals and use of the binary and the headers. The magic happens in the Xcode project, which is using now the C++ interop Build setting, so it can understand well the header files.

Thanks for the abstraction idea as well. I would segregate the library at any cost and creating a boundary/abstraction layer around it, but having such guideline is absolutely precious. Thanks again!

1 Like