iOS Swift framework from ObjC framework without modulemap - ios

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.

Related

How to use Obj-C Framework code in Swift Framework?

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.

Could not build Objective-C module, when using swift in objective-c module

In an iOS application I have a subproject (not cocoapods) in which I have included a swift file and ObjC file (that is used by the swift file). XCode automatically created a bridging file but could not build it because apparantly bridging is not allowed in a framework. The workaround that I used was to add the objective-c header to the umbrella file and it worked. Now I need to use a swift class from ObjC. I have define module to set to YES, the generated file Framework-Swift.h . But when I try to import it in objective-c i get
Could not build Objective-C module
The closest I got after some googleing was this answer:
Ah gotcha. It looks like you're building a mixed Swift & Objective-C
pod - if that's the case, Xcode will try to import
within the generated -Swift.h header.
You'll need to create the header manually and add imports for the
Objective-C classes that you want to expose to Swift.
CocoaPods generates an umbrella header automatically and imports it
within the .modulemap, but Xcode doesn't use that when generating the
-Swift.h header
But I am unsure what header needs to be created manually.
Any ideeas or pointer about using swift in an objective-c framework ? In both ways ?
I also had similar issue when using Swift pods in my Swift project containing several targets. No Objective-C code at all. I tried to clear build folder, pods cache, derived data - nothing worked.
Solution:
Open the Build Settings for a target that contains your module code. Set the "Install Objective-C Compatibility Header" to "No"
There's a great and simple article that wraps up this case:
DEFINES_MODULE=YES
To use ObjC classes in Swift, create a bridging header and specify path to it in the build settings
To use Swift classes in ObjC, #import <ModuleName/ModuleName-Swift.h> in your *.m file (use #class SwiftClass; forward declaration in *.h file, if needed)
For swift classes and their members to be visible to objc
inherit your class from NSObject
prepend it with #objcMembers
make both the class and its members public

iOS Swift framework: How to import Objective C code into swift framework properly?

I have an umbrella header called
MyApp-Swift.h
I've imported the following class "AFHTTPSessionManager.h" in the umbrella header.
I made the umbrella header public in build phases and I also made sure to set Define modules to yes.
However, in my swift framework I am still getting the following error
Use of undeclared type 'AFHTTPSessionManager'
I don't know why this is continuing. I thought swift would automatically pick up my Objective-C import. Any tips or suggestions are appreciated.
I tried following this source
https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-XID_82
,but it didn't work for me. This is very fusterating.
This is the swift code that causes the error.
import Foundation
class MyApp {
private var manager: AFHTTPSessionManager?
}
The thing is, brigding header doesn't work for Framework targets. Solution is to create module map target to build module map for needed ObjC framework.
Here is example for CommonCrypto: https://stackoverflow.com/a/42852743/1840136; in your case difference should be that script line
header "${SDKROOT}/usr/include/CommonCrypto/CommonCrypto.h"
will be replaced with path to AFNetworking headers (I'm not sure if you're placing 3rd party libraries just within project or getting from pods, so check by yourself).

How to call Objective-C libraries in dynamic framework Swift?

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/

Adding Objective C framework inside Swift Framework

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.

Resources