I have to use Objective C framework in my capacitor plugin. I added the framework in the podspec file also added the bridging header right where the plugin swift files are (ios/Sources/Plugin/…). And I wrote the code to use objective c framework in the swift file. However, it isn’t working. I managed to use swift framework but not objective c framework there.
Can you share any code that you’ve written so far? It’s impossible for us to know what could be happening from just reading your description
Using Objective C Framework in Capacitor plugin in Swift
- Created the plugin
- Added the objective C framework in Project/ios/Sources/Frameworks/
- Defined bridging header and module map
- Added the framework path, framework header path, and modulemap path in the swift packagemanager - the Package.swift file -
Package.swift
import PackageDescription
let package = Package(
name: "UnityLoader",
platforms: [.iOS(.v13)],
products: [
.library(
name: "UnityLoader",
targets: ["UnityLoaderPlugin"])
],
dependencies: [
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", branch: "main")
],
targets: [
.binaryTarget(
name: "UnityFramework",
path: "ios/Sources/Frameworks/UnityFramework.framework"
),
.target(
name: "UnityLoaderPlugin",
dependencies: [
.product(name: "Capacitor", package: "capacitor-swift-pm"),
.product(name: "Cordova", package: "capacitor-swift-pm"),
"UnityFramework"
],
path: "ios/Sources/UnityLoaderPlugin",
publicHeadersPath: "ios/Sources/Frameworks/UnityFramework.framework/Headers",
cSettings: [
.headerSearchPath("ios/Sources/Frameworks/UnityFramework.framework/Headers"),
.define("FRAMEWORK_SEARCH_PATHS", to: "ios/Sources/Frameworks/UnityFramework.framework"),
.define("MODULEMAP_FILE", to: "ios/Sources/Frameworks/UnityFramework.framework/Modules/module.modulemap")
]
),
.testTarget(
name: "UnityLoaderTests",
dependencies: ["UnityLoaderPlugin"],
path: "ios/Tests/UnityLoaderPluginTests")
]
)
- in the swift code used used this code to load the framework
UnityLoader.swift file
@objc public func echo(_ value: String) -> String {
print(value)
var ufw: UnityFramework?
if ufw == nil {
let unityPath = Bundle.main.bundlePath + "/Frameworks/UnityFramework.framework"
let bundle = Bundle(path: unityPath)
bundle!.load()
ufw = bundle!.principalClass?.getInstance()
ufw?.setDataBundleId("com.unity3d.framework")
ufw?.runEmbedded(withArgc: CommandLine.argc, argv: CommandLine.unsafeArgv, appLaunchOpts: nil)
ufw?.showUnityWindow()
return value
}
- built the plugin
However, it doesn’t work it says cannot find unityframework headers or it says that could not build objective c framework. I even tried the same thing with Bridging Headers - basically made a bridging header file and added its path in the Package.swift but that didn’t work either.
Objective C framework in Capacitor plugin using Objective C
I have tried this with objective C as well but this doesn’t work either - it says cannot find an exported struct although it is there in the UnityFramework.h file
UnityFramework.h
typedef struct mach_header_64 MachHeader;
extern const struct mach_header_64 _mh_execute_header;
Things I did:
1. I created a new plugin project
2. Deleted the swift files and added objective c files with their header files
3. Added the objective c framework in the project director
6. Added the reference to the objective c framework in the podspec file
7. In the source file for the plugin, I added the code to import stuff from UnityFramework and using
to load the unity instance.
UnityLoader.podspec
require 'json'
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
Pod::Spec.new do |s|
s.name = ‘UnityLoader’
s.version = package['version']
s.summary = package['description']
s.license = package['license']
s.homepage = 'https://capacitorjs.com'
s.author = package['author']
s.source = { :git => 'https://github.com/ionic-team/capacitor-plugins.git', :tag => package['name'] + '@' + package['version'] }
` s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}', ‘./**/*.{swift,h,m,c,cc,mm,cpp}'`
s.ios.deployment_target = '13.0'
s.dependency 'Capacitor'
s.swift_version = '5.1'
s.public_header_files = 'UnityFramework.framework/Headers/*.h'
s.dependency 'UnityFramework'
s.xcconfig = {
'FRAMEWORK_SEARCH_PATHS' => '"$(PODS_ROOT)/"'
}
s.vendored_frameworks = 'UnityFramework.framework'
end
UnityLoader.m
#include <UnityFramework/Unityframework.h>
UnityFramework* UnityFrameworkLoad(void) {
NSString* bundlePath = NULL;
bundlePath = [[NSBundle mainBundle] bundlePath];
bundlePath = [bundlePath stringByAppendingString:@"/Frameworks/UnityFramework.framework"];
NSBundle* bundle = [NSBundle bundleWithPath:bundlePath];
if (![bundle isLoaded]) [bundle load];
UnityFramework* ufw = [bundle.principalClass getInstance];
if (![ufw appController]) {
// Unity is not initialized
[ufw setExecuteHeader:&_mh_execute_header];
}
return ufw;
}
Then built the framework and imported it in ionic app but still it didn’t work.
I have also tried putting the framework in podspec and swift package manager both in both cases and it doesn’t work either. It says linking error coudn’t find basically that _mh_execute_header doesn’t exist here linking problem and stuff like that.