Swift/ObjC库桥接:在ArkTS中调用iOS库(272)
在鸿蒙 ArkTS 中调用 iOS 库(Objective-C/Swift),同样依赖于 ArkUI-X 提供的平台桥接(Bridge)机制。
1. 核心桥接原理
与 Android 类似,ArkTS 无法直接调用 Objective-C 或 Swift 代码。平台桥接在底层同样通过 C++ 作为中间层,构建了 ArkTS ↔ C++ ↔ Objective-C 的通信链路。这一底层交互对开发者是透明的,在实际开发中,你可以将其视为 ArkTS 和 iOS 原生代码在进行直接交互。
2. 主要应用场景
当应用需要复用现有的 iOS 平台代码,而 OpenHarmony 中缺少对应的跨平台 API(非 UI 相关)时,平台桥接非常适用。具体包括:
- 双向数据传递:在 ArkUI 与 iOS 平台之间传递 JSON 数据、图片等。
- 调用平台 API:在 ArkTS 侧调用 iOS 的原生 API(如获取设备状态),或直接复用 iOS 端的三方库。
- 平台回调 ArkTS:iOS 平台调用 ArkUI 侧的方法,例如复用 JavaScript 的三方库。
3. 数据类型映射
平台桥接支持通过 JSON 或二进制格式进行序列化编解码。在传递数据时,ArkTS 与 Objective-C 的数据类型存在严格的映射关系:
- 基础类型:
string对应NSString,boolean对应NSNumber numberWithBool。 - 数值类型:ArkTS 的
number根据精度可映射为NSNumber numberWithInt(32位)、NSNumber numberWithLong(64位)或NSNumber numberWithDouble。 - 集合类型:
Array对应NSArray,Record/Map对应NSDictionary。 - 二进制流:
ArrayBuffer对应NSData。 - 空值:
null对应NSNull。
4. 开发注意事项
- String 传输限制:通过平台桥接传递的 string 类型数据,最大传输大小限制为 2MB。
- Map 类型限制:Record(Map)类型仅支持 string 类型的 key,并且仅能用于方法的返回值。
- API 参考:在 ArkUI 侧的具体用法请参考 Bridge API,iOS 侧的插件实现请参考 iOS BridgePlugin。
一、 iOS 原生层:插件注册与双向通信
在 iOS 侧,通过继承 BridgePlugin 并实现相关协议,打通与 ArkTS 的底层通信。
// 1. BridgeClass.h:声明供 ArkTS 调用的原生方法及协议
#import <libarkui_ios/BridgePlugin.h>
NS_ASSUME_NONNULL_BEGIN
@interface BridgeClass : BridgePlugin
// 供 ArkTS 侧调用的原生方法
- (NSString*)getDeviceStatus;
@end
NS_ASSUME_NONNULL_END
// 2. BridgeClass.m:实现原生逻辑与消息监听
#import "BridgeClass.h"
@implementation BridgeClass
// ArkTS 侧调用 callMethod('getDeviceStatus') 时触发
- (NSString*)getDeviceStatus {
return @"iOS Battery: 85%";
}
// 监听 ArkTS 侧发来的消息(sendMessage)
- (NSString*)onMessage:(id)data {
NSLog(@"Received from ArkTS: %@", data);
return @"iOS onMessage success";
}
// 监听 ArkTS 侧方法注销,释放原生资源
- (void)onMethodCancel:(NSString *)methodName {
if ([methodName isEqualToString:@"startLocation"]) {
// 停止定位等耗时操作
}
}
@end
// 3. 在 AppDelegate 或 EntryAbility 中注册桥接插件
self.plugin = [[BridgeClass alloc] initBridgePlugin:@"Bridge"
bridgeManager:[mainView getBridgeManager]];
self.plugin.messageListener = self.plugin;
二、 ArkTS 架构层:接口抽象与条件编译
为了屏蔽 iOS、Android 和鸿蒙原生平台的差异,必须在 ArkTS 侧定义统一的接口层。
// 1. PlatformInterface.ets:定义跨平台统一接口
export interface IPlatformService {
getDeviceStatus(): Promise<string>;
sendMessageToNative(data: string): Promise<string>;
}
// 2. PlatformFactory.ets:根据运行环境动态注入实现
import { PlatformInfo } from './PlatformInfo';
import { ArkUIXService } from './ArkUIXService';
import { LocalHarmonyService } from './LocalHarmonyService';
export class PlatformFactory {
static createPlatformService(): IPlatformService {
if (PlatformInfo.isHarmony()) {
return new LocalHarmonyService(); // 鸿蒙端直接调用本地 API
} else {
return new ArkUIXService(); // iOS/Android 端通过 Bridge 调用
}
}
}
三、 ArkTS 实现层:ArkUI-X Bridge 封装
将底层的 @arkui-x.bridge 封装为符合统一接口的服务类。
// ArkUIXService.ets:封装 iOS/Android 桥接调用
import bridge from '@arkui-x.bridge';
import { IPlatformService } from './PlatformInterface';
export class ArkUIXService implements IPlatformService {
private bridgeImpl = bridge.createBridge('Bridge');
async getDeviceStatus(): Promise<string> {
// 调用 iOS 侧的 getDeviceStatus 方法
const result = await this.bridgeImpl.callMethod('getDeviceStatus');
return result?.toString() || 'Unknown';
}
async sendMessageToNative(data: string): Promise<string> {
// 向 iOS 侧发送消息并获取回执
const response = await this.bridgeImpl.sendMessage(data);
return response?.toString() || 'No Response';
}
}
四、 业务层:无感知调用
在 UI 组件中,业务代码完全不需要关心底层是鸿蒙还是 iOS,实现真正的“一码三平台”。
// Index.ets:业务页面
import { PlatformFactory } from './bridge/PlatformFactory';
import { IPlatformService } from './bridge/PlatformInterface';
@Entry
@Component
struct Index {
@State status: string = 'Loading...';
private platformService: IPlatformService = PlatformFactory.createPlatformService();
aboutToAppear() {
this.loadStatus();
}
async loadStatus() {
this.status = await this.platformService.getDeviceStatus();
}
build() {
Column() {
Text(`Device Status: ${this.status}`)
Button('Send Message')
.onClick(async () => {
const res = await this.platformService.sendMessageToNative('Hello from ArkUI');
console.log('Native Response:', res);
})
}
}
}
五、 核心进阶:双向方法注册与动态注销
除了基础的数据传递,ArkUI-X 支持原生平台与 ArkTS 侧方法的互相调用。在 iOS 侧,开发者通过实现 IMethodResult 接口,可以精准监听 ArkTS 侧的事件注销通知,从而释放原生资源。
// iOS 侧:实现方法注册与注销监听
// 原生平台侧供 ArkTS 侧调用的方法无需注册,但 ArkTS 侧暴露给 iOS 调用的方法需通过 registerMethod 定义
// 监听 ArkTS 侧的事件注销通知
- (void)onMethodCancel:(NSString *)methodName {
if ([methodName isEqualToString:@"startLocation"]) {
// 停止 iOS 端的定位服务,释放资源
[self.locationManager stopUpdatingLocation];
}
}
六、 性能突破:Bridge 线程并发模式
在复杂的跨平台应用中,数据编解码和原生 API 调用极易阻塞主 UI 线程。ArkUI-X 提供了线程并发模式,将耗时处理转移到后台异步线程,保障 UI 的 60FPS 流畅度。
- 适用场景:大文件读取、复杂 JSON 解析、高频传感器数据上报。
- 架构优势:用户调度的 Bridge 都在 Platform 线程,由 Platform 切换到 JS 线程时,将耗时操作放入后台异步线程处理,让 Bridge 调用者可连续发送数据而不卡顿。
- 注意:线程并发模式目前只能在原生平台侧(iOS/Android)创建平台桥接实例时指定。
七、 架构治理:“一码三平台”的接口抽象层
跨平台框架的最终目的是“写一套代码,运行在三个平台上”。为了在引入 Bridge 时修改最少量的原有架构代码,必须采用分层架构设计。
- 公共能力层(Commons Layer):定义统一的接口(如
CameraInterface)。 - 平台适配层:
- 鸿蒙侧(CameraLocal):直接调用鸿蒙原生 API。
- iOS/Android 侧(CameraArkUIX):通过 Bridge 调用 iOS/Android 原生能力。
- 业务层(Feature Layer):上层业务统一调用
CameraInterface,完全无需区分当前运行平台,实现真正的“一码三平台”。
更多推荐



所有评论(0)