Skip to content

Instantly share code, notes, and snippets.

@gatherheart
Forked from bgromov/readme.md
Created January 4, 2023 09:56
Show Gist options
  • Save gatherheart/357f8320bd14b7fcb0084d1c810c77ac to your computer and use it in GitHub Desktop.
Save gatherheart/357f8320bd14b7fcb0084d1c810c77ac 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.

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