Xcode 6 / Beta 4: using bridging headers with framework targets is unsupported
XcodeFrameworksBetaXcode Problem Overview
I just upgraded to Xcode 6 Beta 4 and have a framework that I created for Live Views in Beta 2. Due to another swift bug, I needed to use some Obj-C code. When upgrading though, I get the following error:
> error: using bridging headers with framework targets is unsupported
I have not seen anything in the release notes, or found any other migration path. Has anyone else seen this and arrived at a solution?
I realize that Beta 3 eliminated the need for frameworks for live views, but it makes sense in my case if I can get it to work. I can remove it though as a fallback, but would prefer to use a framework if they are not totally broken in Beta 4.
Xcode Solutions
Solution 1 - Xcode
As the error states, bridging headers are not allowed in Frameworks. The Importing Code from Within the Same Framework Target section of the Mix & Match apple documentation hints at this. As they say, you need to "In your umbrella header file, import every Objective-C header you want to expose to Swift".
However, I discovered that you may also need to make those specific headers public as well. This answer reviews why and how to do that: https://stackoverflow.com/questions/24103169/swift-compiler-error-non-modular-header-inside-framework-module.
So, do this:
- Remove your bridging header file.
- Remove references to the bridging header file in the build settings for the framework
- Add the necessary headers to your umbrella file ([ProductName].h)
- Make the included files public in the framework's "Headers" section of its "Build Phases".
- Clean and rebuild.
Note: The "umbrella header file" is a file (named [ProductName].h) that generally represents all public headers of a framework. It is usually just a list of #import statements to other headers contained in the framework. In Xcode, if you open UIKit.h, you will see a good example of an umbrella file.
Solution 2 - Xcode
There are two possibilities. Adding the necessary headers to the umbrella header file and making them public is one way. However, this is a problem if the headers should be available to Swift, but not public.
The second possibility which will make internal headers available to Swift is described in detail here. Essentially, a module map similar to the following needs to be created:
module AwesomeKitPrivate {
header "../InternalClass.h"
export *
}
This can then be included in XCode using the setting:
SWIFT_INCLUDE_PATHS = $(SRCROOT)/AwesomeKit/ProjectModule
Solution 3 - Xcode
See Importing Objective-C into Swift .
To import Objective-C code into Swift from the same framework
-
Under Build Settings, in Packaging, make sure the Defines Module setting for that framework target is set to “Yes".
-
In your umbrella header file, import every Objective-C header you want to expose to Swift. For example:
#import "XYZ/XYZCustomCell.h" #import "XYZ/XYZCustomView.h" #import "XYZ/XYZCustomViewController.h"
-
Make the included files public in the framework's "Headers" section of its "Build Phases".
-
Clean and rebuild.
Swift will see every header you expose publicly in your umbrella header. The contents of the Objective-C files in that framework will be available in any Swift file within that framework target automatically, without any import statements. Use your custom Objective-C code with the same Swift syntax you use with system classes.
let myOtherCell = XYZCustomCell()
myOtherCell.subtitle = "Another custom cell"
Important: the "umbrella header file" means the file {ModuleName}.h. BTW, the target name is {ModuleName}.framework.