Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to import Objective C static library to Swift Framework?

I’m writing a dynamic Framework (Proto.framework) for OS X in Swift. I want to include code from a static library (libstat.a) which is written in Objective C. Here’s what I’ve got:

// Dynamic.swift in Proto.framework
class Dynamic {
    func doSomethingWithStat() {
        Stat().statThing()
    }
}

// Stat.h in libstat.a static library
@interface Stat : NSObject
- (void)statThing;
@end

// Stat.m
@implementation Stat
- (void)statThing {
    NSLog(@"OK");
}
@end

In my target for Proto.framework, I have linked it to libstat.a. When I try to build Proto, naturally it doesn’t compile because it can’t find the definition for Stat().statThing(). It doesn’t know the symbols for my static library. How do I tell it about that?

For applications, I’d use a bridging header and do #import <Stat/Stat.h>. But the compiler errors out and tells me Bridging headers aren’t allowed in frameworks. OK.

So I include it in my “umbrella header” (Proto.h) but that tells me error: include of non-modular header inside framework module. OK.

Making my Stat library target Defines module: YES doesn’t seem to change the error even after a clean build. So I’m not sure how to do this.

Can someone point me in the right direction?

like image 501
jbrennan Avatar asked Jul 31 '15 17:07

jbrennan


People also ask

How do I add Objective-C to Swift?

Add any Objective-C file to your Swift project by choosing File -> New -> New File -> Objective-C File. Upon saving, Xcode will ask if you want to add a bridging header. Choose 'Yes'.

How do I access Objective-C in Swift?

To import a set of Objective-C files into Swift code within the same app target, you rely on an Objective-C bridging header file to expose those files to Swift. Xcode offers to create this header when you add a Swift file to an existing Objective-C app, or an Objective-C file to an existing Swift app.

Does Swift support static libraries?

Question: Can we create static frameworks using Swift? Answer: Finally, YES! (Xcode 9). CocoaPods announced the support of Swift Static Frameworks in 1.5.


2 Answers

The easiest way to accomplish that is to use a module map file. Below I assume you have the Proto.framework in a separate project, which is called Proto.

  1. Create a module.modulemap file in your framework containing the following (substitute the path to the header file as needed):

_

framework module Proto {
    umbrella header "Proto.h"

    // Load a C header to be used in Swift - here /usr/include/sys/stat.h:
    header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/sys/stat.h"

    export *
    module * { export * }
}
  1. In your project build settings find Module Map File in section Packaging. Enter $(SRCROOT)/Proto/module.modulemap

That's it. From now on you should be able to use anything declared in stat.h in Swift.

like image 156
dtbow Avatar answered Oct 24 '22 00:10

dtbow


In your build settings for Proto.framework try setting the option Allow Non-modular Includes In Framework Modules to Yes.

Xcode Settings

like image 22
Jad Avatar answered Oct 24 '22 02:10

Jad