前言:为何要写这篇文章?🤔
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
版本仍处于开发阶段,部分功能未经完全测试。在生产环境使用前,请务必进行充分测试。
整体流程概览
在开始动手之前,我们先通过一个流程图来了解整个接入过程的脉络。这能帮助我们建立一个清晰的全局观。
第一步:安装依赖 📦
首先,我们需要将 react-native-wechat-lib
添加到项目中。我们指定 3.0.4
版本,以适配 RN 0.70+。
perl
npm install react-native-wechat-lib@3.0.4
# 或者
yarn add react-native-wechat-lib@3.0.4
对于 iOS,安装完 npm 包后,需要进入 ios
目录执行 pod install
来链接原生依赖。
bash
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.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 才能被微信唤起和唤起微信。
xml
<!-- "微信 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
objectivec
#import <RCTAppDelegate.h>
#import <UIKit/UIKit.h>
#import "WXApi.h" // 导入微信 SDK 头文件
// 遵循 WXApiDelegate 协议
@interface AppDelegate : RCTAppDelegate <WXApiDelegate>
@end
AppDelegate.mm
objectivec
#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
(用于登录和分享)kotlin// "包名必须是你的应用包名 + .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
(仅用于支付)kotlin// "包名必须是你的应用包名 + .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,并进行重要配置。
xml
<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
。
kotlin
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
)中操作:
javascript
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。
typescript
// 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 在页面中使用
现在,调用登录、分享、支付都变得非常简单。
javascript
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' }
});
总结 🏁
好了,朋友们,经过一番"魔改",我们这篇指南现在应该能覆盖绝大多数场景了。回顾一下,我们主要解决了以下几个核心问题:
- 适配新版原生环境:针对 iOS 和 Android 的最新系统特性,更新了原生项目的配置。
- 处理依赖链接问题:通过详细的手动链接步骤,确保了原生库和框架被正确引用。
- 完善安卓配置 :新增了
WXPayEntryActivity
来支持支付,并用taskAffinity
解决了小程序返回 App 的难题。 - 建立回调机制 :引入了
DeviceEventEmitter
监听,这是正确处理支付和登录回调的关键。 - 代码现代化封装 :通过一个功能更全面的
useWeChat
Hook,将微信的 API 调用封装得更加优雅和易于维护。
虽然 react-native-wechat-lib
已经垂垂老矣,但在没有更好的替代品出现之前,通过我们自己的努力,依然能让它在新版本的 React Native 项目中焕发新生。希望这篇"填坑"指南能为你节省宝贵的时间和精力。
如果你在接入过程中遇到了任何问题,欢迎在评论区留言讨论。如果觉得这篇文章对你有帮助,别忘了点赞、收藏、分享三连哦!👍❤️