iOS平台扩展@ohos接口
说明:
iOS平台上扩展@ohos接口,以testplugin.hello接口为例(假定@ohos.testplugin是OpenHarmony跨平台API)。
导入模块
// xxx.ets
import testplugin from '@ohos.testplugin';
接口
| 名称 | 参数 | 返回类型 | 描述 |
|---|---|---|---|
| hello | void | void | 在iOS侧打印日志"hello from ios" |
// xxx.ets
testplugin.hello();
步骤
为了调用iOS Objective-C(OC) API,本质是要实现JS调用OC的能力。跨平台推荐JS -> C/C++ -> OC的调用路径,实现JS调用iOS OC API。即在iOS侧实现OC接口,通过C/C++直接封装OC接口,再通过NAPI机制实现C/C++模块注册,供应用侧JS调用。
一、iOS侧实现hello方法
// plugins/test_plugin/ios/ios_test_plugin.m
@implementation iOSTestPlugin
+ (instancetype)shareinstance{
static dispatch_once_t onceToken;
static iOSTestPlugin *instance = nil;
dispatch_once(&onceToken, ^{
instance = [iOSTestPlugin new];
});
return instance;
}
// 实现hello模块
-(void)hello{
NSLog(@"TestPlugin: Hello from ios");
}
@end
二、C/C++调用OC hello方法
// plugins/test_plugin/ios/test_plugin_impl.mm
void TestPluginImpl::Hello()
{
PluginUtilsInner::RunTaskOnPlatform([]() {
// 直接调用OC hello方法
[[iOSTestPlugin shareinstance] hello];
});
}
三、通过NAPI机制暴露JS hello方法
1、实现testplugin.hello对应的C/C++模块。
// plugins/test_plugin/js_test_plugin.cpp
static napi_value JSTestPluginHello(napi_env env, napi_callback_info info)
{
// 创建TestPlugin实例
auto plugin = TestPlugin::Create();
// 调用C++接口,Hello函数最终会调用iOSTestPlugin的hello方法
plugin->Hello();
return nullptr;
}
// plugins/test_plugin/test_plugin.h
class TestPlugin {
public:
TestPlugin() = default;
virtual ~TestPlugin() = default;
static std::unique_ptr<TestPlugin> Create();
virtual void Hello() = 0;
};
// plugins/test_plugin/ios/test_plugin_impl.mm
std::unique_ptr<TestPlugin> TestPlugin::Create()
{
return std::make_unique<TestPluginImpl>();
}
2、实现模块导出入口函数
// plugins/test_plugin/js_test_plugin.cpp
static napi_value TestPluginExport(napi_env env, napi_value exports)
{
static napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("hello", JSTestPluginHello),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
return exports;
}
3、注册模块
// plugins/test_plugin/js_test_plugin.cpp
static napi_module testPluginModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = TestPluginExport,
.nm_modname = "testPlugin",
.nm_priv = ((void*)0),
.reserved = { 0 },
};
extern "C" __attribute__((constructor)) void TestPluginRegister()
{
// 注册testPlugin模块,供JS调用
napi_module_register(&testPluginModule);
}
附:GN配置
1、增加模块
// plugins/plugin_lib.gni
common_plugin_libs = [
"test_plugin",
]
2、编译js_test_plugin模块
// plugins/test_plugin/BUILD.gn
ohos_source_set(target_name) {
defines += invoker.defines
cflags_cc += invoker.cflags_cc
sources = [ "js_test_plugin.cpp" ]
deps = [
"//plugins/interfaces/native:ace_plugin_util_${platform}",
"//plugins/libs/napi:napi_${target_os}",
]
if (platform == "ios") {
deps += [ "ios:test_plugin_ios" ]
}
subsystem_name = "plugins"
part_name = "test_plugin"
}
3、编译iOS平台特有代码
// plugins/test_plugin/ios/BUILD.gn
import("//build/ohos.gni")
import("//foundation/arkui/ace_engine/ace_config.gni")
ohos_source_set("test_plugin_ios") {
sources = [
"ios_test_plugin.m",
"test_plugin_impl.mm",
]
defines = [ "IOS_PLATFORM" ]
if (target_cpu == "arm64") {
defines += [ "_ARM64_" ]
}
configs = [ "$ace_root:ace_config" ]
cflags_objc = [
"-fvisibility=default",
"-fobjc-weak",
]
cflags_objcc = cflags_objc
deps = [ "//plugins/interfaces/native:ace_plugin_util_ios" ]
subsystem_name = "plugins"
part_name = "test_plugin"
}