Skip to content

Instantly share code, notes, and snippets.

@bgromov
Last active September 30, 2023 15:35
Show Gist options
  • Save bgromov/f4327343ad67a5f7216262ccbe99c376 to your computer and use it in GitHub Desktop.
Save bgromov/f4327343ad67a5f7216262ccbe99c376 to your computer and use it in GitHub Desktop.
Compiling Swift framework with mixed-in Objective-C code

Problem

You can't use bridging headers within a framework.

Solution 1 (umbrella header):

Xcode will automatically create umbrella header for you Cocoa Framework project. That will be the file named <FrameworkName>.h in the <FrameworkName> group/folder (where the rest of your sources are).

  1. To include the required Obj-C header you need to set it as Public: select it in the project explorer (left pane) and change the property Target Membership (left—Inspectors—pane) from Project to Public.

  2. Open umbrella header (<FrameworkName>.h) and import the required header as:

    #import <FrameworkName/objc-header.h>

This effectively makes this header public and available to both your own framework and anyone who uses it.

Note: If you import the header as a local file, i.e. in quotes, e.g. #import "objc-header.h", you likely to hit the compiler error telling you are trying to include a non-modular header.

Solution 2 (module map):

  1. Create a file named module.modulemap in the root of your project with the following contents:

    framework module FrameworkName {
        umbrella header "FrameworkName.h"
    
        header "objc-header.h"
    
        export *
        module * { export * }
    }

    In case you want to keep the definitions from objc-header.h private from the users of your framework you can add private qualifier like so:

        // ...
        private header "objc-header.h"
        // ...
  2. In Build Setting set Module Map File to module.modulemap

  3. Clean the build directory (⇧⌘K) and build the project (⌘B)


Note: There are options in the Build Settings of the project to specify the Module Map File and Module Private File, but I couldn't manage to make them work—the compiler was spitting something like: Redifinition of <FrameworkName> module.

@RanaSaleh
Copy link

I followed the second solution , but it is not working if i don't convert the classes to public, so the users of my framework can still access the files. any suggestion plz.
Regards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment