React Native 集成 iOS 原生功能

React Native 集成 iOS 原生功能完整指南

前言

在 React Native 项目中集成 iOS 原生功能是一个常见需求。本文将同样以打印机功能为例,详细介绍如何在 React Native 项目中集成 iOS 原生功能。

集成步骤概述

  1. 创建原生模块(Native Module)
  2. 创建桥接文件(Bridge Header)
  3. 在 JavaScript/TypeScript 端创建接口
  4. 在 React Native 中调用原生功能

详细实现

1. 创建原生模块

首先创建一个继承自 RCTEventEmitter 的 Objective-C 类:

objectivec:ios/ZICOXPrinter/ZICOXPrinter.h 复制代码
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>

@interface ZICOXPrinter : RCTEventEmitter <RCTBridgeModule>
@end

实现文件:

objectivec:ios/ZICOXPrinter/ZICOXPrinter.m 复制代码
#import "ZICOXPrinter.h"

@implementation ZICOXPrinter

RCT_EXPORT_MODULE();

// 暴露方法给 JavaScript 调用
RCT_EXPORT_METHOD(print:(NSString *)text
                  resolver:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
    // 打印功能实现
    @try {
        // 打印逻辑
        resolve(@YES);
    } @catch (NSException *exception) {
        reject(@"PRINT_ERROR", exception.reason, nil);
    }
}

// 如果需要支持事件发送,需要实现以下方法
- (NSArray<NSString *> *)supportedEvents
{
    return @[@"onPrintProgress", @"onPrintComplete"];
}

@end

2. Swift 实现(可选)

如果您更喜欢使用 Swift,需要创建一个桥接文件:

swift:ios/ZICOXPrinter/ZICOXPrinter.swift 复制代码
import Foundation

@objc(ZICOXPrinter)
class ZICOXPrinter: RCTEventEmitter {
    
    @objc
    override static func moduleName() -> String! {
        return "ZICOXPrint"
    }
    
    @objc
    override func supportedEvents() -> [String]! {
        return ["onPrintProgress", "onPrintComplete"]
    }
    
    @objc
    func print(_ text: String,
               resolver resolve: @escaping RCTPromiseResolveBlock,
               rejecter reject: @escaping RCTPromiseRejectBlock) {
        do {
            // 打印逻辑实现
            resolve(true)
        } catch {
            reject("PRINT_ERROR", error.localizedDescription, error)
        }
    }
}

对应的桥接文件:

objectivec:ios/ZICOXPrinter/ZICOXPrinter-Bridging-Header.h 复制代码
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>

3. 创建 TypeScript 接口

与 Android 类似,我们需要在 JS 端创建对应的接口:

typescript:src/native/ZICOXPrinter.ts 复制代码
// 定义接口
interface ZICOXPrinterInterface {
  print(text: string): Promise<boolean>;
  connect(address: string): Promise<void>;
}

// 声明模块
declare module 'react-native' {
  interface NativeModulesStatic {
    ZICOXPrint: ZICOXPrinterInterface;
  }
}

// 创建包装器
import { NativeModules, NativeEventEmitter } from 'react-native';

const { ZICOXPrint } = NativeModules;
const eventEmitter = new NativeEventEmitter(ZICOXPrint);

export const ZICOXPrinter = {
  async print(text: string): Promise<boolean> {
    try {
      return await ZICOXPrint.print(text);
    } catch (error) {
      console.error('打印失败:', error);
      throw error;
    }
  },

  // 监听事件
  addPrintListener(callback: (progress: number) => void) {
    return eventEmitter.addListener('onPrintProgress', callback);
  }
};

4. 在 React 组件中使用

最后在 React 组件中使用这些原生功能:

typescript:src/components/PrintButton.tsx 复制代码
import React, { useEffect } from 'react';
import { Button } from 'react-native';
import { ZICOXPrinter } from '../native/ZICOXPrinter';

export const PrintButton: React.FC = () => {
  useEffect(() => {
    const subscription = ZICOXPrinter.addPrintListener((progress) => {
      console.log('打印进度:', progress);
    });

    return () => subscription.remove();
  }, []);

  const handlePrint = async () => {
    try {
      const result = await ZICOXPrinter.print('要打印的内容');
      if (result) {
        console.log('打印成功');
      }
    } catch (error) {
      console.error('打印失败:', error);
    }
  };

  return <Button title="打印" onPress={handlePrint} />;
};

注意事项

  1. iOS 特有的注意点

    • 需要注意内存管理和循环引用问题
    • 在主线程处理 UI 相关操作
    • 正确处理权限请求
  2. 事件处理

    • iOS 端使用 RCTEventEmitter 发送事件
    • JS 端使用 NativeEventEmitter 监听事件
  3. 调试技巧

    • 使用 Xcode 控制台查看日志
    • 善用断点调试
    • 检查桥接是否正确配置

总结

iOS 原生模块的集成虽然在细节上与 Android 有所不同,但整体思路是类似的。通过合理的架构设计和类型定义,我们可以构建出类型安全、易于维护的原生功能扩展。特别注意 iOS 平台特有的一些特性和限制,确保代码在实际运行中的稳定性和性能。

相关推荐
HarderCoder13 小时前
iOS 知识积累第一弹:从 struct 到 APP 生命周期的全景复盘
ios
木西14 小时前
React Native DApp 开发全栈实战·从 0 到 1 系列(兑换-前端部分)
react native·web3·solidity
叽哥1 天前
Flutter Riverpod上手指南
android·flutter·ios
小仙女喂得猪2 天前
2025 Android原生开发者角度的React/ReactNative 笔记整理
react native·react.js
用户092 天前
SwiftUI Charts 函数绘图完全指南
ios·swiftui·swift
YungFan2 天前
iOS26适配指南之UIColor
ios·swift
XTransfer技术2 天前
RN也有微前端框架了? Xtransfer的RN优化实践(一)多bundle架构
前端·react native
权咚3 天前
阿权的开发经验小集
git·ios·xcode
用户093 天前
TipKit与CloudKit同步完全指南
ios·swift
法的空间3 天前
Flutter JsonToDart 支持 JsonSchema
android·flutter·ios