I am creating a cocoapod (framework) in swift that needs to import a 3rd party objective-c framework. However, when adding #import <ThirdPartyFramework/ThirdPartyFramework.h> to the umbrella file of my cocoapod, I get the following error:
Include of non-modular header inside framework module 'MyCocoapod'
I tried setting Allow non-modular includes in framework modules to YES but that did not resolve the error.
The ThirdPartyFramework.h header just has a bunch of imports of other headers:
#import <ThirdPartyFramework/Header1.h>
#import <ThirdPartyFramework/Header2.h>
...
I can't really edit this framework since it's from a 3rd party. Is there anything I can do to use this 3rd party framework in my swift cocoapod? Can I not modularize the header that I need to import?
I've read here that the library owner needs to move the imports into a .m file, but I am not the library owner. Also, I'm using swift and the library is in objective-c so I don't really have .m files, which is why I have to import it in my umbrella file.
Using XCode 7.3
Related
As I explained in image I want to create Pod lib in swift which have another Pod lib dependency written in Objective-c.
Now I know that to use objective-c code in swift we need bridge file and I created it too.
but When I set it into Pod's build phase I got this error<unknown>:0: error: using bridging headers with framework targets is unsupported
I got hint in internet that I should put .h file into pod-umbrella.h file, But that also gave me error Include of non-modular header inside framework module 'DemoPod'
Please help me if you had similar issue in past and resolved it.
Some hint/suggestions are also welcome.
Here is my demopod project for you if you want to play around.
Demo Pod Project
EDIT
As per Ashsis suggestion I added below code into DemoPod.modulemap
framework module AdaptiveCard {
umbrella header "/Users/jageen.shukla/Documents/Project/ai answer/DemoPod/Example/Pods/AdaptiveCards/AdaptiveCards.framework/Headers/ACFramework.h"
requires ios
export *
}
But still I can not build project because it give me error in target project that can not find module "AdaptiveCard".
I change code in DemoPod.modulemap
framework module DemoPod {
umbrella header "DemoPod-umbrella.h"
// Solution 2
framework module AdaptiveCard {
umbrella header "/Users/jageen.shukla/Downloads/DemoPod/Example/Pods/AdaptiveCards/AdaptiveCards.framework/Headers/ACFramework.h"
export *
module * { export * }
}
// ----
export *
module * { export * }
}
Now I am able to compile my project. but I am not sure what I am doing is good practice or not? Plus I am also not know why I have to mention `absolute path` of adaptive card's header file.
Latest code : [Demo_2][4]
https://drive.google.com/file/d/1Xve0DUAy4bQ7sx4d3H8WLbJJwTqlJnCt/view?usp=sharing
Bridging header is only recommended at App Target and App Test target to access objective c and CPP files in swift. You should use modulemap to expose the Objc and CPP functionality to swift library when it comes to static library or framework. Please check the code implementation how to use modulemap here: https://github.com/ashislaha/Swift-ObjectiveC-Interoperability
As the error says, bridging headers aren't allowed in frameworks, only in applications.
The detailed documentation is here
The Swift code will be able to access everything from objc that is included in the public umbrella header for your framework where it says
// In this header, you should import all the public headers of your framework using statements like #import <YourFramework/PublicHeader.h>
You'll need to remove the bridging header from where you added it in the Build Settings, in order to get your framework to compile.
what should you do now ?
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 ([Name].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.
I currently making a Swift framework, and my Swift framework depend on other oc framework and static library.
So i need to import them with modulemap.
But modulemap can only writen in abosuled path, this is very unfriendly for a team work.
I have tried to use aggregate target and write the script in build phases(script can use relative path to build module), but this cause another problem. The Swift framework product generate two modulemap, and when my project using this framework, xcode says it couldnt find the module that it generate by the aggregate target!
What can i do?
Finally, i find a way to solve all the problem.
Cause Swift need modulemap to use the third party framework, i make an umbrella framework to wrap all the .a and .framework files, and make them public. Then make all .h file written in the umbrella file.
I have a framework binary built with Swift that I'm trying to incorporate into an Objective-C project. However the class in the framework isn't available.
In the swift framework, the class is defined like this:
#objcMembers
#objc public final class Messaging: NSObject, UINavigationControllerDelegate, LogsManagerDelegate {
...
}
I drag the archived and exported framework directly into the project to use and make sure the Defines Module is set to Yes in the Build Settings.
In the Objective-C I try to use the framework:
#import ContactAtOnceMessaging;
#implementation MessagingExperience
Messaging *messaging; // Unknown type name 'Messaging'
...
#end
If I drag the code for the framework directly into the project, Messaging is a known class so I know the Swift is okay.
I also tried changing the import to the following, but that didn't work.
#import "ContactAtOnceMessaging/ContactAtOnceMessaging-Swift.h"
I also tried using CocoaPods to import the framework and that hasn't helped.
What am I doing wrong?
I can confirm that I experienced the same problem as you. I was also able to resolve it. I'm not sure if the original problem was caused by an anomaly somewhere in my configuration. I did, however, test the following procedure and found it to work reliably with Xcode 9.3.
I first made a test Swift framework named Dynamic-Framework-Tester, in an Xcode project, and set it to be copied to an absolute path on every build.
I then performed the following steps to setup my Objective-C project:
Made a new project with Objective-C as the language.
Dragged the framework from its absolute path into the project without choosing "Copy items if needed".
Deleted the framework from Linked Frameworks and Libraries because it will get added automatically in step (4).
Added the framework to Embedded Binaries.
In build settings, set Always Embed Swift Standard Libraries to Yes.
Added my custom framework path to the Framework Search Paths setting in the build settings.
In the Objective-C project, I imported the framework using
#import Dynamic_Framework_Tester;
and called a method exposed in the framework from Objective-C.
Using a simulator, I was able to update the framework and have the changes applied on subsequent runs of the app.
I have no debugging values in my console for my swift + obj-c app, and I get a really unhelpful message that explains why the debugger isn't working: "warning: Swift error in module XXX.". XXX is the name of my module, not a 3rd party that I include.
My app has been around since before Swift. I used the bridging header to start using Swift, and I recently used the Xcode tool to migrate all the Swift 2 files to Swift 3. (but I still have obj-c legacy in there). I use cocoapods, which may be contributing to the problem.
(lldb) po self
warning: Swift error in module XXX.
Debug info from this module will be unavailable in the debugger.
I tried following the second answer to this post and a couple others
I have found that suggest the same thing: remove duplicate imports.
I tried removing duplicate imports from my swift project. In fact if I run find . -name "*swift" | xargs grep "import" I get no results. So I went to the extreme of removing all imports from all of my swift files (and commenting out code to get it to compile) just to see if I can get my debugger to come back.
So...
Is there another solution to this problem?
Is there a way to get a more detailed error message?
Is it a problem to have duplicate headers in the my bridging header? For example, a lot of my obj-c files import UIKit, and I include a few of those files in the bridging header.
Just now I have encountered this problem.
This is my solution:
If you import 3rd repo by Cocoapods, and the repo is written by Objective-C, you need to import it by this way:
// System
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
// Directly add - Objective-C
#import "EaseUI.h"
// Cocoapods - Objcetive-C
#import MJRefresh;
You can refer to this issue in Github and this question.
I am building a framework in which I need to import some objective-c frameworks for now I need to import "Beaconstac.framework" but as we can not add a bridging header in a swift framework project so my question is how can I use this framework in my project this is not directly accessible in my project I tried
import Beaconstac
but its giving error "No Such Module"
is there any alternative to do this?
Steps to include an existing Obj C framework in a swift framework project
Say we are creating an “SwiftProj.framework" project in swift which internally has to use an Objective C “ObjC.framework”
Place the ObjC.framework in Frameworks folder, Link to Swift framework project via Linked Frameworks and Libraries, and create a module.modulemap file at the same level.
In module.modulemap
module ObjC{
header "ObjC.framework/Headers/ClassA.h"
export *
}
Create xcconfig file (File->New->iOS->Other->Configuration Settings file)
In xcconfig file
SWIFT_INCLUDE_PATHS = $(SRCROOT)/
MODULEMAP_PRIVATE_FILE = $(SRCROOT)/module.modulemap
Now you can access ObjC.ClassA in SwiftProj.framework
Create a file called module.modulemap and include the following contents:
module ObjCFrameworkName {
header "ObjCFrameworkName.framework/Headers/ObjCFrameworkNameUmbrellaHeader.h"
export *
}
Be aware that you need to have the correct path to your Obj-C framework's umbrella header which may differ slightly with what's listed in the example above.
If you are still stuck, I would strongly suggest taking a look at this project.
You need to import the Beaconstac framework in your umbrella header. That is, if you'd ordinarily use, e.g., #import <Beaconstac/Beaconstac.h> in an Obj-C bridging header, for a framework you need to put that in the umbrella header.
See this chapter in Apple's documentation for more info:
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-ID130