🚀 2025 年最新教程:在 React Native 0.70+ 项目中接入 react-native-wechat-lib

939 阅读11分钟

前言:为何要写这篇文章?🤔

react-native-wechat-lib 可以说是目前 React Native 生态中,为数不多还能勉强使用的微信 SDK 封装库了。但问题是,这个库已经好几年没有实质性更新了!😱 这几年间,React Native 本身经历了从旧架构到新架构的巨大变革,而 Android 和 iOS 两大原生平台更是天翻覆地:

  • Android: 从 Java 全面拥抱 Kotlin,权限体系变得更加严格,构建工具和依赖管理也焕然一新。
  • iOS: SDK 版本持续迭代,对 Universal Links(通用链接)的要求越来越高,Xcode 的配置也变得更加复杂。

这些变化导致官方文档和网上流传的旧教程,在面对 0.70+ 版本的 React Native 时,几乎处处是坑。最近,我所在的项目(一个基于 Taro RN 的项目)正好需要接入微信分享和支付功能,于是我便一头扎了进去,把这些坑一个个填平了。

为了让后来者少走弯路,我决定将这次“填坑”的完整经历整理成一篇详尽的教程。虽然文章会涉及部分 Taro RN 的内容,但核心的配置和代码逻辑对于所有 React Native 项目都是通用的,请放心“食用”!👍

🚨 风险提示:根据官方 README,我们使用的 3.0.x 版本仍处于开发阶段,部分功能未经完全测试。在生产环境使用前,请务必进行充分测试。

💡 2025/11/25 编辑更新: 随着 React Native 生态的演进,越来越多的项目开始采用 Swift 编写原生层代码。本文已在底部新增了 Swift 项目接入方式。如果你使用的是 Swift 版的 AppDelegate,请直接跳转查阅。

整体流程概览

在开始动手之前,我们先通过一个流程图来了解整个接入过程的脉络。这能帮助我们建立一个清晰的全局观。

graph TD;
    A["开始"] --> B{"安装依赖"};
    B --> C{"iOS 平台配置"};
    C --> D["链接原生库与框架"];
    C --> E["配置 Info.plist"];
    C --> F["配置 AppDelegate"];
    B --> G{"Android 平台配置"};
    G --> H["配置 AndroidManifest.xml"];
    G --> I["创建 WXEntryActivity & WXPayEntryActivity"];
    G --> J["注册原生模块"];
    F & J --> K{"JavaScript/TypeScript 代码集成"};
    K --> L["初始化 SDK & 监听事件"];
    K --> M["封装 WeChat Hook"];
    M --> N["在页面中使用"];
    N --> O["完成 🎉"];

    style A fill:#28a745,stroke:#333,stroke-width:2px
    style O fill:#28a745,stroke:#333,stroke-width:2px

第一步:安装依赖 📦

首先,我们需要将 react-native-wechat-lib 添加到项目中。我们指定 3.0.4 版本,以适配 RN 0.70+。

npm install react-native-wechat-lib@3.0.4
# 或者
yarn add react-native-wechat-lib@3.0.4

对于 iOS,安装完 npm 包后,需要进入 ios 目录执行 pod install 来链接原生依赖。

cd ios && pod install

第二步:iOS 平台配置 🍎

iOS 的配置是整个过程中最容易出错的地方,请务必一步步仔细操作,不要遗漏。

2.1 手动链接原生库与框架

这是至关重要的一步!

  1. 打开 Xcode 项目:在你的 React Native 项目中,找到 ios 文件夹,双击 .xcworkspace 文件(白色图标那个),用 Xcode 打开它。

  2. 添加 libWeChatSDK.a

    • ../node_modules/react-native-wechat-lib/ios/ 目录中的 libWeChatSDK.a 文件 复制到你项目中的 ios 文件夹中
    • 在 Xcode 左侧的项目导航器中,右键点击你的项目名称(最顶层那个),选择 "Add Files to '[Your Project Name]'"。
    • 导航到 你项目/ios/ 目录,选中 libWeChatSDK.a 文件,然后点击 "Add"。
  3. 添加系统框架依赖

    • 在 Xcode 中,点击你的项目名称,然后选择主 Target

    • 切换到 libWeChatSDK.a 文件 标签页。

    • 展开 "Link Binary With Libraries" 区域。

    • 点击左下角的 "+" 号按钮。

    • 在弹出的窗口中,搜索并逐个添加以下系统框架:

      • WebKit.framework
      • SystemConfiguration.framework
      • CoreTelephony.framework
      • libsqlite3.0.tbd
      • libc++.tbd
      • libz.tbd

🚨 重点标注:这一步是解决大量 "library not found" 或 "undefined symbols" 编译错误的关键。如果你是新手,请务必仔细核对,确保所有库都已添加。

2.2 配置 Info.plist

打开 ios/[YourProjectName]/Info.plist 文件,我们需要添加微信的 URL Scheme 和允许查询的 Scheme,这样你的 App 才能被微信唤起和唤起微信。

<!-- "微信 URL Scheme" -->
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>weixin</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <!-- "🚨 这里必须替换成你在微信开放平台申请的 AppID" -->
            <string>wx028c********8197</string>
        </array>
    </dict>
</array>

<!-- "允许查询的应用 Scheme,用于检查微信是否安装" -->
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>weixin</string>
    <string>wechat</string>
    <string>weixinULAPI</string>
</array>

2.3 配置 AppDelegate 文件

这是处理微信回调的关键。我们需要修改 AppDelegate.hAppDelegate.mm 文件。

AppDelegate.h

#import <RCTAppDelegate.h>
#import <UIKit/UIKit.h>
#import "WXApi.h" // 导入微信 SDK 头文件

// 遵循 WXApiDelegate 协议
@interface AppDelegate : RCTAppDelegate <WXApiDelegate>

@end

AppDelegate.mm

#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTLinkingManager.h> // 导入链接管理器

@implementation AppDelegate

// ... App 默认的 didFinishLaunchingWithOptions 方法

// 关键!添加以下方法来处理微信的回调
// 支持 iOS 9.0+
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
  // 优先处理 RN 的 Deep Link
  [RCTLinkingManager application:application openURL:url options:options];
  // 再处理微信的回调
  return [WXApi handleOpenURL:url delegate:self];
}

// 支持 Universal Links(通用链接),微信支付回调等场景必需
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
 restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
  [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
  return [WXApi handleOpenUniversalLink:userActivity delegate:self];
}

// ... 其他 AppDelegate 代码

@end

第三步:Android 平台配置 🤖

Android 平台的适配同样重要,特别是针对新系统的变更和微信支付的特殊要求。

3.1 创建回调 Activities

微信的分享、登录、支付等功能需要不同的 Activity 来接收回调。

路径android/app/src/main/java/com/[your_package_name]/wxapi/

🚨 重要提示:路径和包名 wxapi 必须完全正确,com.[your_package_name] 要换成你自己应用的包名,否则微信将绝对无法回调到你的 App!

  1. 创建 WXEntryActivity.kt (用于登录和分享)

    // "包名必须是你的应用包名 + .wxapi"
    package com.your_package_name.wxapi
    
    import android.app.Activity
    import android.os.Bundle
    import com.wechatlib.WeChatLibModule
    
    class WXEntryActivity : Activity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            WeChatLibModule.handleIntent(intent)
            finish()
        }
    }
    
  2. 创建 WXPayEntryActivity.kt (仅用于支付)

    // "包名必须是你的应用包名 + .wxapi"
    package com.your_package_name.wxapi
    
    import android.app.Activity
    import android.os.Bundle
    import com.wechatlib.WeChatLibModule
    
    class WXPayEntryActivity : Activity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            WeChatLibModule.handleIntent(intent)
            finish()
        }
    }
    

3.2 配置 AndroidManifest.xml

现在注册我们创建的 Activities,并进行重要配置。

<manifest xmlns:android="[http://schemas.android.com/apk/res/android](http://schemas.android.com/apk/res/android)">
    
    <!-- "微信 Android 11+ 适配,允许查询微信包信息" -->
    <queries>
        <package android:name="com.tencent.mm" />
    </queries>
    
    <application>
        <!-- ... 其他 activity ... -->

        <!-- "用于微信登录和分享的回调" -->
        <activity
          android:name=".wxapi.WXEntryActivity"
          android:label="@string/app_name"
          android:exported="true"
          android:taskAffinity="com.your_package_name"
          android:launchMode="singleTask"
        />

        <!-- "用于微信支付的回调" -->
        <activity
          android:name=".wxapi.WXPayEntryActivity"
          android:label="@string/app_name"
          android:exported="true"
        />
    </application>
</manifest>

🚨 重点标注

  1. WXEntryActivity 中添加的 android:taskAffinityandroid:launchMode="singleTask" 是为了解决从小程序返回 App 失败的问题,强烈建议配置taskAffinity 的值应为你的 App 包名。
  2. android:exported="true" 在高版本的 Android 系统中是必需的,否则其他应用(如微信)无法启动你的 Activity。

3.3 注册 WeChatLibPackage

最后,我们需要在 MainApplication.kt (或 MainApplication.java) 中注册 WeChatLibPackage

package com.your_package_name

// ... 其他 import
import com.wechatlib.WeChatLibPackage // 导入微信包

class MainApplication : Application(), ReactApplication {
  override val reactNativeHost: ReactNativeHost =
      object : DefaultReactNativeHost(this) {
        override fun getPackages(): List<ReactPackage> =
            PackageList(this).packages.apply {
              // 在这里添加 WeChatLibPackage
              add(WeChatLibPackage())
            }
        // ... 其他配置
      }
  // ... 其他代码
}

第四步:JS/TS 代码集成 💻

原生配置完成后,我们终于回到了熟悉的 JS/TS 世界。

4.1 初始化 SDK 与事件监听

根据官方文档,支付、小程序返回等回调是通过 DeviceEventEmitter 来触发的。所以我们需要在应用启动时就设置好监听。

在你的应用入口文件(例如 App.tsx)中操作:

import { useEffect } from 'react';
import { DeviceEventEmitter } from 'react-native';
import * as WeChat from 'react-native-wechat-lib';

const WECHAT_APPID = 'wx028********18197'; // 🚨 替换成你的 AppID
const WECHAT_UNIVERSALLINK = '[https://your.domain.com/app/](https://your.domain.com/app/)'; // 🚨 替换成你的 Universal Link

function App() {
  useEffect(() => {
    // 1. 注册 App
    WeChat.registerApp(WECHAT_APPID, WECHAT_UNIVERSALLINK);

    // 2. 添加事件监听
    const wechatRespListener = DeviceEventEmitter.addListener('WeChat_Resp', resp => {
      console.log('收到微信回调', resp);
      // resp.type === 'SendMessageToWX.Resp' // 分享
      // resp.type === 'PayReq.Resp' // 支付
      // resp.type === 'SendAuth.Resp' // 登录
      if (resp.errCode === 0) {
        // 根据 resp.type 处理成功逻辑
      } else {
        // 处理失败逻辑
      }
    });

    return () => {
      // 移除监听
      wechatRespListener.remove();
    };
  }, []);

  // ... 你的应用其他逻辑
  return <RootNavigation />;
}

4.2 封装一个更强大的 useWeChat Hook

为了统一管理所有微信相关操作,我们来重构并扩展之前的 Hook。

// src/hooks/useWeChat.ts
import * as WeChat from 'react-native-wechat-lib';
import { Alert } from 'react-native';

// 定义分享场景的枚举
export enum ShareScene {
  Session = 0,  // 会话
  Timeline = 1, // 朋友圈
  Favorite = 2, // 收藏
}

// 支付请求参数类型
export interface PaymentPayload {
  partnerId: string;
  prepayId: string;
  nonceStr: string;
  timeStamp: string;
  package: string;
  sign: string;
}

export function useWeChat() {
  const checkInstall = async () => {
    const isInstalled = await WeChat.isWXAppInstalled();
    if (!isInstalled) {
      Alert.alert('提示', '请先安装微信客户端');
      return false;
    }
    return true;
  };

  // 登录
  const sendAuthRequest = async (scope: string | string[] = 'snsapi_userinfo', state = 'wechat_sdk_demo') => {
    if (!(await checkInstall())) return;
    try {
      const result = await WeChat.sendAuthRequest(scope, state);
      // 登录成功,result.code 可用于换取 access_token
      console.log('登录成功', result);
      return result;
    } catch (e) {
      console.error('登录失败', e);
      Alert.alert('登录失败', '请稍后重试');
    }
  };
  
  // 分享网页
  const shareWebpage = async (options: {
    title: string;
    description?: string;
    thumbImageUrl?: string;
    webpageUrl: string;
    scene?: ShareScene;
  }) => {
    if (!(await checkInstall())) return;
    try {
      await WeChat.shareWebpage({
        scene: ShareScene.Session,
        ...options,
      });
    } catch (e) {
      console.error('分享失败', e);
      Alert.alert('分享失败', '请稍后重试');
    }
  };

  // 支付
  const pay = async (payload: PaymentPayload) => {
    if (!(await checkInstall())) return;
    try {
      const result = await WeChat.pay(payload);
      // 注意:这里的 result 可能不代表最终支付结果,最终结果请以服务器异步通知和 DeviceEventEmitter 监听为准
      console.log('支付请求已发送', result);
      return result;
    } catch (e) {
      console.error('支付请求失败', e);
      Alert.alert('支付失败', '无法调起微信支付');
    }
  };

  return {
    isWXAppInstalled: WeChat.isWXAppInstalled,
    sendAuthRequest,
    shareWebpage,
    pay,
  };
}

4.3 在页面中使用

现在,调用登录、分享、支付都变得非常简单。

import React from 'react';
import { View, Button, StyleSheet } from 'react-native';
import { useWeChat } from '~/hooks/useWeChat';

export default function MyFeatureScreen() {
  const { sendAuthRequest, shareWebpage, pay } = useWeChat();

  const handleLogin = () => {
    sendAuthRequest();
  };

  const handleShare = () => {
    shareWebpage({
      title: '一篇超棒的技术文章!',
      description: '快来看看如何在最新的 RN 项目中接入微信吧!',
      webpageUrl: '[https://your.article.link](https://your.article.link)',
    });
  };

  const handlePayment = () => {
    // 实际项目中,支付参数应从你的服务器获取
    const paymentPayload = {
      partnerId: 'your_partner_id',
      prepayId: 'your_prepay_id',
      nonceStr: 'your_nonce_str',
      timeStamp: 'your_timestamp',
      package: 'Sign=WXPay',
      sign: 'your_sign',
    };
    pay(paymentPayload);
  };

  return (
    <View style={styles.container}>
      <Button title="微信登录" onPress={handleLogin} />
      <View style={{ height: 20 }} />
      <Button title="分享给微信好友" onPress={handleShare} />
      <View style={{ height: 20 }} />
      <Button title="发起微信支付" onPress={handlePayment} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center' }
});

附录:Swift 接入方式 (2025 更新版)

如果你的 iOS 项目已经迁移到 Swift,或者你正在使用基于 Expo Modules 的新架构,传统的 Objective-C 配置方式将不再适用。请按照以下步骤进行 Swift 环境下的适配。

1. 文件清理与替换

在 Xcode 中执行以下文件操作:

  1. 移除旧文件:在项目导航栏中,找到 main.mAppDelegate.hAppDelegate.mm。右键点击选择 Delete,确认为 Move to Trash(彻底删除)或 Remove Reference(仅移除引用)。
  2. 创建 Swift 入口:新建一个名为 AppDelegate.swift 的文件。
  3. 创建桥接头文件:新建一个名为 BridgingHeader.h 的头文件。

2. 配置桥接头文件 (Bridging Header)

由于微信 SDK 和 React Native 的部分核心库仍是 Objective-C 编写的,我们需要通过桥接文件让 Swift 识别它们。

第一步:写入桥接内容

在你的 BridgingHeader.h 中填入以下代码:

// BridgingHeader.h

#import <React/RCTBundleURLProvider.h>
#import <React/RCTLinkingManager.h>
#import <React/RCTBridge.h>
#import <ReactAppDependencyProvider/RCTAppDependencyProvider.h>
// 引入微信 SDK 头文件
#import "WXApi.h"

第二步:配置 Build Settings

  • 在 Xcode 中点击左侧蓝色的项目图标 例如:taroDemo
  • 选择 Build Settings 标签。
  • 搜索 Bridging Header
  • 找到 Objective-C Bridging Header 选项。
  • 双击填入路径:taroDemo/BridgingHeader.h (或者 $(SRCROOT)/taroDemo/BridgingHeader.h)。
  • 关键点:确保路径正确,如果文件就在 ios/taroDemo 下,通常写 taroDemo/BridgingHeader.h

image.png

3. 实现 AppDelegate.swift

将新建的 AppDelegate.swift 内容替换为以下代码。这段代码结合了 Expo 模块初始化与微信 SDK 的代理回调:

import UIKit
import Expo
import React
import React_RCTAppDelegate
import ReactAppDependencyProvider

// 1. 引入 WXApiDelegate 协议
@main
class AppDelegate: ExpoAppDelegate, WXApiDelegate {

  var window: UIWindow?
  var reactNativeDelegate: ReactNativeDelegate?
  var reactNativeFactory: RCTReactNativeFactory?

  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
  ) -> Bool {
    // 2. 注册微信 AppID 和 Universal Link
    // 🚨 请替换为你自己的 AppID 和 Universal Link
    WXApi.registerApp("wx_YOUR_APP_ID", universalLink: "https://your.universal.link/")

    let delegate = CustomReactNativeDelegate()
    let factory = ExpoReactNativeFactory(delegate: delegate)
    delegate.dependencyProvider = RCTAppDependencyProvider()

    reactNativeDelegate = delegate
    reactNativeFactory = factory
    bindReactNativeFactory(factory)

    window = UIWindow(frame: UIScreen.main.bounds)

    factory.startReactNative(
      withModuleName: "YourModuleName", // 🚨 这里替换为你 package.json 中的 name
      in: window,
      launchOptions: launchOptions
    )

    // 调用父类方法,确保 Expo 和其他库的初始化
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }

  // 3. 处理 Scheme 跳转 (OpenURL) - iOS 9+
  override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    // 优先让微信处理 URL
    let isWeChatHandled = WXApi.handleOpen(url, delegate: self)

    // 如果微信处理了,直接返回 true
    if isWeChatHandled {
        return true
    }

    // 否则让 React Native Linking 继续处理
    return RCTLinkingManager.application(app, open: url, options: options)
  }

  // 4. 处理 Universal Link 跳转
  override func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    // 优先让微信处理 Universal Link
    let isWeChatHandled = WXApi.handleOpenUniversalLink(userActivity, delegate: self)

    if isWeChatHandled {
        return true
    }

    // 否则让 React Native Linking 继续处理
    return RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
  }

  // MARK: - WXApiDelegate

  // 5. 实现 WXApiDelegate 代理方法
  // 虽然 react-native-wechat-lib 内部会监听通知,但实现这些代理方法是标准做法,防止警告或潜在回调丢失

  func onReq(_ req: BaseReq) {
    // 微信终端向第三方程序发送请求
  }

  func onResp(_ resp: BaseResp) {
    // 第三方程序向微信发送请求,微信处理完后向第三方程序发送响应
    // react-native-wechat-lib 会通过 DeviceEventEmitter 处理具体逻辑
  }
}

class ReactNativeDelegate: ExpoReactNativeFactoryDelegate {
  override func sourceURL(for bridge: RCTBridge) -> URL? {
    bridge.bundleURL ?? bundleURL()
  }

  override func bundleURL() -> URL? {
#if DEBUG
    RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
#else
    Bundle.main.url(forResource: "main-ios", withExtension: "jsbundle")
#endif
  }
}

// 用于插入自定义方法
class CustomReactNativeDelegate: ReactNativeDelegate {
}

总结 🏁

好了,朋友们,经过一番“魔改”,我们这篇指南现在应该能覆盖绝大多数场景了。回顾一下,我们主要解决了以下几个核心问题:

  1. 适配新版原生环境:针对 iOS 和 Android 的最新系统特性,更新了原生项目的配置。
  2. 处理依赖链接问题:通过详细的手动链接步骤,确保了原生库和框架被正确引用。
  3. 完善安卓配置:新增了 WXPayEntryActivity 来支持支付,并用 taskAffinity 解决了小程序返回 App 的难题。
  4. 建立回调机制:引入了 DeviceEventEmitter 监听,这是正确处理支付和登录回调的关键。
  5. 代码现代化封装:通过一个功能更全面的 useWeChat Hook,将微信的 API 调用封装得更加优雅和易于维护。

虽然 react-native-wechat-lib 已经垂垂老矣,但在没有更好的替代品出现之前,通过我们自己的努力,依然能让它在新版本的 React Native 项目中焕发新生。希望这篇“填坑”指南能为你节省宝贵的时间和精力。

如果你在接入过程中遇到了任何问题,欢迎在评论区留言讨论。如果觉得这篇文章对你有帮助,别忘了点赞、收藏、分享三连哦!👍❤️