前言:为何要写这篇文章?🤔
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 手动链接原生库与框架
这是至关重要的一步!
-
打开 Xcode 项目:在你的 React Native 项目中,找到
ios文件夹,双击.xcworkspace文件(白色图标那个),用 Xcode 打开它。 -
添加
libWeChatSDK.a:- 将
../node_modules/react-native-wechat-lib/ios/目录中的libWeChatSDK.a文件 复制到你项目中的 ios 文件夹中 - 在 Xcode 左侧的项目导航器中,右键点击你的项目名称(最顶层那个),选择 "Add Files to '[Your Project Name]'"。
- 导航到 你项目
/ios/目录,选中libWeChatSDK.a文件,然后点击 "Add"。
- 将
-
添加系统框架依赖:
-
在 Xcode 中,点击你的项目名称,然后选择主 Target。
-
切换到
libWeChatSDK.a文件 标签页。 -
展开 "Link Binary With Libraries" 区域。
-
点击左下角的 "+" 号按钮。
-
在弹出的窗口中,搜索并逐个添加以下系统框架:
WebKit.frameworkSystemConfiguration.frameworkCoreTelephony.frameworklibsqlite3.0.tbdlibc++.tbdlibz.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.h 和 AppDelegate.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!
-
创建
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() } } -
创建
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>
🚨 重点标注:
WXEntryActivity中添加的android:taskAffinity和android:launchMode="singleTask"是为了解决从小程序返回 App 失败的问题,强烈建议配置。taskAffinity的值应为你的 App 包名。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 中执行以下文件操作:
- 移除旧文件:在项目导航栏中,找到
main.m、AppDelegate.h和AppDelegate.mm。右键点击选择 Delete,确认为 Move to Trash(彻底删除)或 Remove Reference(仅移除引用)。 - 创建 Swift 入口:新建一个名为
AppDelegate.swift的文件。 - 创建桥接头文件:新建一个名为
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。
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 {
}
总结 🏁
好了,朋友们,经过一番“魔改”,我们这篇指南现在应该能覆盖绝大多数场景了。回顾一下,我们主要解决了以下几个核心问题:
- 适配新版原生环境:针对 iOS 和 Android 的最新系统特性,更新了原生项目的配置。
- 处理依赖链接问题:通过详细的手动链接步骤,确保了原生库和框架被正确引用。
- 完善安卓配置:新增了
WXPayEntryActivity来支持支付,并用taskAffinity解决了小程序返回 App 的难题。 - 建立回调机制:引入了
DeviceEventEmitter监听,这是正确处理支付和登录回调的关键。 - 代码现代化封装:通过一个功能更全面的
useWeChatHook,将微信的 API 调用封装得更加优雅和易于维护。
虽然 react-native-wechat-lib 已经垂垂老矣,但在没有更好的替代品出现之前,通过我们自己的努力,依然能让它在新版本的 React Native 项目中焕发新生。希望这篇“填坑”指南能为你节省宝贵的时间和精力。
如果你在接入过程中遇到了任何问题,欢迎在评论区留言讨论。如果觉得这篇文章对你有帮助,别忘了点赞、收藏、分享三连哦!👍❤️