Adding CommonCrypto to custom Swift framework

I’m building a Swift framework which seems relatively simple. Then I needed to import CommonCrypto.


In the framework’s .h file I added the line

#import <CommonCrypto/CommonCrypto.h>

and included `Security.framework` in `Link Binary with Libraries` for the framework’s target.

When I build I get the following build error:

Include of non-modular header inside framework module ‘MyKit'

I’ve tried changing the Allow Non-modular Includes In Framework Modules to YES and NO and tried every combination for both the framework target and the project with no luck.


The MyKit.h’s Target Membership is set to Public and is ticked for MyKit too.

Replies

My preferred way of solving this problem is to write a small Objective-C wrapper around the Common Crypto functionality that I need and then use that from my Swift code. The Objective-C should include

<CommonCrypto/CommonCrypto.h>
in its
.m
file so that the include is not seen by Xcode as it tries to construct the module interface to your framework.

This approach has a couple of advantages:

  • It fixes this problem.

  • It’s very straightforward, avoiding the need for any weird hackery.

  • It works the same way in both framework and non-framework code.

  • It’s easier to talk to Common Crypto from Objective-C than it is from Swift, so you can actually look at it as a win from a maintenance perspective.

We already have a bug on file about Common Crypto’s modular header problem (r. 18256932).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

This is an interesting solution, but I'm not sure how this solves the issue. In order to call Objective-C code from Swift, you need a bridging header. But you can't use bridging headers with framework targets. While your solution may work if you're just writing an app, I don't think it'll work with a framework.

Hi @eskimo I'm using the same solution as you mentioned, but in addition I had to add modulemap file which points to the headers of the Objective-C code so these clases are available in swift. After creating a swift framework and including it into the separate project all works perfectly but I came across a problem when trying to use this framework on some other computer. Also the same thing happens when I change the path of the original project where code of the frameworks is.


For example in modulemap I defined a module like this, where relative path to the header file is added:

module Crypto {
    header "../Library/Classes/ObjC/Crypto.h"
    export *
}


Then after framework is builded I try to use it on a different computer and I get this error:

Missig required modules: 'Crypto'


It looks like it's remembering the path of the source and when it's moved it can't be found. I can't find any solution how to properly configure the project to avoid this issue.


I also checked the arm64.swiftmodule file and I can find the trace of my original path in it.


Any help would be much appreciated.


Thanks!

Saso

One can add the needed headers to the umbrella header file for the framework. Or, one can create another framework to encapsulate the Objective-C code, if one doesn't want the framework to expose Objective-C code.