I am writing a Cocoa Framework for iOS in Swift language. I need to add a third party framework (written in Objective-C) inside this framework. I have added headers to the bridging file. But when i build the project i get the following error:
"using bridging headers with framework targets is unsupported"
You should use import ObjcFrameworkName instead of using bridging header.
To make this possible objc framework must contain .modulemap file with exported module name and umbrella header for all public headers of this framework.
Related
I'm working on Swift framework implementation and trying to use the closed source Objective-C framework (let us call it 'InternalObjectiveC.framework') provided by vendor
in Swift framework( let us call it 'ExternalSwift.framework').
The problem:
The 'InternalObjectiveC.framework' doesn't have modulemap or SwiftModule.
When I try to use the Objective-C classes (declared in 'InternalObjectiveC.framework') from Swift code (of 'ExternalSwift.framework') the Xcode cannot find them
I've tried to use Bridging Header, but faced with issue
"error: using bridging headers with framework targets is unsupported"
Also I've tried to make umbrella framework to expose the headers - it works.
My question is:
Is there a better way to make interoperability between Swift framework and the Objective-C framework(which doesn't have modulemap)?
Already checked other answers:
iOS mixed dynamic framework - bridge objc headers with private module,
Embedded Frameworks in Swift/iOS: Cocoapods-Packager dependency ModuleMap error (.modulemap' not found / underlying Objective-C module not found),
Objective-C Bridging Header for frameworks
In my case, i didn't need 'InternalObjectiveC.framework' modulemap. But i created modulemap for Swift framework. Something like this:
module InternalObjectiveC {
header "Pods/InternalObjectiveC/InternalObjectiveC.framework/Headers/InternalObjectiveC.h"
export *
}
Then in Build Settings, i searched for 'Import Path' and provide it new module.modulemap path. For example '$(SDKROOT)/ProjectModule'
Then i was able to compile all the things,
Hope this help.
How to use Obj-C Framework code in Swift Framework?
Is it possible or I need to mix them in a single Framework?
I have code for both Frameworks. I connect them manually without CocoaPods, Carthage or Swift Package Manager. Bridging header cannot be used inside of a Framework, only in App Target. Google says that I need to use modulemap file. In all examples I found they create their own modulemap files and put them near the Swift framework code. I tried to use both my own modulemap file and existing one inside ObjCFramework.framework/Modules. I use them by adding a path to the modulemap file to SWIFT_INCLUDE_PATHS build setting of my Swift Framework. I also tried to #import Obj-C Frameworks Ubrella Header to Swift Frameworks Ubrella Header with no luck. Of course I added the Obj-C Framework target to my Swift Framework target dependencies, the framework itself to Frameworks and Libraries and the path to it to Framework Search Paths. I didn't put anything to Header Search Paths to avoid "Include of non-modular header inside framework module", but that didn't help. CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES build setting doesn't help too. DEFINES_MODULE is set to YES.
Now I'm in endless loop of several errors:
Include of non-modular header inside framework module 'ObjCFramework': '/Users/bond/Library/Developer/Xcode/DerivedData/SwiftFramework-aqidpocynynsvdgtrqwukanwqkxf/Build/Products/Debug-iphoneos/ObjCFramework.framework/Headers/View.h'
Module 'ObjCFramework' was built in directory '/Users/bond/Library/Developer/Xcode/DerivedData/SwiftFramework-aqidpocynynsvdgtrqwukanwqkxf/Build/Products/Debug-iphoneos/ObjCFramework.framework' but now resides in directory '/Users/bond/Library/Developer/Xcode/DerivedData/SwiftFramework-aqidpocynynsvdgtrqwukanwqkxf/Build/Products/Debug-iphoneos/ObjCFramework.framework/Modules'
No such module ObjCFramework
underlying Objective-C module not found
In brief this is described here: https://developer.apple.com/documentation/swift/imported_c_and_objective-c_apis/importing_objective-c_into_swift, "Import Code Within a Framework Target" chapter.
If the Defines Module setting is turned on in your framework target, modern Xcode puts Modules folder in the framework, with Swift versions of all you ObjC public interfaces, making ObjC stuff available either for external Swift code that links your framework or Swift code of the framework itself.
This does not depend on whether your framework target contains any swift code.
Just add you ObjC header to framework target, mark it as Public in "Target membership", include in framework Umbrella header and build.
I have written a framework in Swift 2.3 that uses Cocoapods to utilize a few Objective-C projects such as AFNetworking and CocoaLumberjack. Since bridging headers cannot be used in frameworks I have defined module maps for each Objective-C project (as well as for a few objective-c utiltities I have written). For example, the module.modulemap for AFNetworkModule looks like:
module AFNetworkModule {
header "../../Pods/Headers/Public/AFNetworking/AFNetworkReachabilityManager.h"
export *
}
Also added the path to modulemaps in the Build Settings -> Import Paths.
This way I can import the modules in my framework swift code:
import AFNetworkModule
The setting Defines Module is set to Yes in the Build Settings for the framework.
Externally I can use the framework without any problems in my sample Swift app using import MyFramework when both the framework and the sample app are in the same workspace:
-- SampleAppProj
-- MyFrameworkProj
-- Pods
But I get "Cannot load underlying module for MyFramework" when trying to import the framework in a separate Swift project. The generated framework contains a Headers folder containing MyFramework-Swift.h and MyFramework.h (the umbrella file). I have not added any headers to the umbrella file as I am using modules to import objective-c internally in the swift framework.
I have created a dynamic framework with Swift language. In this framework I am using mailcore2-ios that was build by Objective-C code. So how can I use it in swift file of my framework?
I try "public" and add a header .h file to umbrella but it still not work, have so much error for other header file as the image what I attach.
Xcode does not allow the use of bridging headers in framework targets. You should use the methods described here : http://iosdeveloperzone.com/2014/10/03/using-commoncrypto-in-swift/
I have been looking everywhere and trying everything but I can't get this to work. I'm trying to create a Cocoa Touch Framework (in Swift) to share code between an iOS app I'm developing and its extension. All of the shared code relies on the NMSSH framework. I added the NMSSH framework to my framework, made sure it showed up in "Link Binary with Libraries" and that it was targeted at my framework. However, when I add #import <NMSSH/NMSSH.h> to my umbrella header, I get the error Include of non-modular header inside framework module 'MyFramework'.
In most of the places I have looked, they say the fix to this is to import the 3rd party framework in a .m file in my framework. The problem is that my framework is in Swift and thus doesn't have any .m files. I tried adding import NMSSH to my .swift file, but that just results in No such module 'NMSSH'.
There must be a way to actually get this to work without rewriting all of my code in Objective-C.