I'm trying to centralize my commonly used Swift code into a framework, and part of that code uses Google Analytics. I brought in Google Analytics as a Cocoapod, but I can't access it from the new framework like I did from the original project because it's Objective-C and there's no bridging header support in frameworks [I'm using Swift 1.2].
The line of code I normally have in the bridging header that makes all of this work is:
#import <Google/Analytics.h>
Where exactly do I put this in my project to make this all work like it did before in the bridging header?
What I found in Apple's documentation about mixing Swift and Objective-C is this:
Importing Code from Within the Same Framework Target
If you’re writing a mixed-language framework, you may need to access your Objective-C code from Swift and your Swift code from Objective-C.
Importing Objective-C into Swift
To import a set of Objective-C files in the same framework target as your Swift code, you’ll need to import those files into the Objective-C umbrella header for the framework.
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: OBJECTIVE-C
import <XYZ/XYZCustomCell.h>
import <XYZ/XYZCustomView.h>
import <XYZ/XYZCustomViewController.h>
The phrase I take to be most relevant is where it says:
you’ll need to import those files into the Objective-C umbrella header for the framework
But what is this file and how to you create it?
Apple's documentation mentions earlier (in a table):
Objective-C code
Import into Swift
#import "Header.h"
Well, I tried just creating a file "Header.h" and importing it, but that doesn't work. I don't know what they're trying to say. I can't find an "umbrella" anything in the build settings.
So my question is, how can I import this file (#import <Google/Analytics.h>) in my Swift project so that it can see the Google Analytics cocoapod framework like I would normally do in the bridging header of a normal project?
Update:
I've come to believe that perhaps the objective-c bridging header is the .h file of the same name as the project. I've now tried adding the import statement there, and the error I get is:
! Include of non-modular header inside framework module 'JBS'
For those who have continued to ask if I had solved this problem, the following is how I accomplished this task importing the KochavaTracker SDK Cocoapod into a framework. That SDK is currently written in Objective-C. This answer is based on the answer provided by nuKs, with these specific steps.
1) Create a folder named KochavaTracker under your project folder, i.e. MyFramework/MyFramework/KochavaTracker.
2) Within that folder create a file named module.modulemap and insert the following content:
This effectively creates a module which is a wrapper for interface of the SDK, which Swift can later import like it does other Swift modules. Note that it relies on a relative path to the Pods folder.
3) As found in build settings, modify your SWIFT_INCLUDE_PATHS to include:
This makes it so that you will be able to import the module and it will locate it in/as the KochavaTracker folder which you created under it.
4) Add to your Swift code, where appropriate:
From there you should be able to reference the classes in the KochavaTracker module.
The bridging header file is a specific header file to use Objective-C file into a Swift framework.
You can find more about bridging in the Apple doc :
So the only thing you have to make is create that file manually by choosing
File > New > File > (iOS, watchOS, tvOS, or OS X) > Source > Header File.
If the name of your framework is ABC,then the name of the header file should be :
You can put it where you want in your framework project.
Hope this can help someone !
The solution is not as straightforward as for an app. We have to create a modulemap.
Have a look at this example repo.
The module map section of this article may also help you.
I followed the procedure in the article above and made it work for my need this way:
module Muse { header "Muse.framework/Headers/Muse.h" export * }
I removed the
[system]
lexon for safety (as it removes warning) and put the framework inside the same folder as the module.map file.Also, don't forget to include
libc++.tbd
and other required dependencies in your framework target (in theLinked Frameworks and Libraries
section of theGeneral
tab) if you need them.