在鸿蒙 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 对应 NSStringboolean 对应 NSNumber numberWithBool
  • 数值类型:ArkTS 的 number 根据精度可映射为 NSNumber numberWithInt(32位)、NSNumber numberWithLong(64位)或 NSNumber numberWithDouble
  • 集合类型Array 对应 NSArrayRecord/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 时修改最少量的原有架构代码,必须采用分层架构设计。

  1. 公共能力层(Commons Layer):定义统一的接口(如 CameraInterface)。
  2. 平台适配层
    • 鸿蒙侧(CameraLocal):直接调用鸿蒙原生 API。
    • iOS/Android 侧(CameraArkUIX):通过 Bridge 调用 iOS/Android 原生能力。
  3. 业务层(Feature Layer):上层业务统一调用 CameraInterface,完全无需区分当前运行平台,实现真正的“一码三平台”。
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐