简介
Fluwx是一个用于在Flutter应用中集成微信SDK的插件,它支持微信登录、支付、分享等功能。本文将详细介绍如何在Flutter项目中使用Fluwx实现各种微信相关功能。
环境准备
1. 添加依赖
在pubspec.yaml文件中添加Fluwx依赖:
dependencies:
fluwx: ^6.0.6
2. 微信开放平台配置
- 前往微信开放平台注册开发者账号
- 创建应用并获取AppID和AppSecret
- 配置应用的包名和签名
3. 项目配置
Android配置
- 在
android/app/build.gradle中添加以下配置:
android {
defaultConfig {
// ... 其他配置
manifestPlaceholders = [
WX_APPID: "你的AppID"
]
}
}
- 在
AndroidManifest.xml中添加必要的权限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
iOS配置
- 在
ios/Runner/Info.plist中添加以下配置:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>weixinULAPI</string>
<string>weixin</string>
<string>weixinURLParamsAPI</string>
</array>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>wx你的AppID</string>
</array>
<key>CFBundleURLName</key>
<string>weixin</string>
</dict>
</array>
初始化
在应用启动时初始化Fluwx:
import 'package:fluwx/fluwx.dart';
// fluwx 4.x 起所有调用都走 Fluwx 实例,顶层函数 registerWxApi 已移除
final fluwx = Fluwx();
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await fluwx.registerApi(
appId: "你的AppID",
universalLink: "你的通用链接", // iOS需要
);
runApp(MyApp());
}
微信登录实现
1. 发起登录请求
Future<void> loginWithWeChat() async {
try {
final fluwx = Fluwx();
// 返回的是"是否成功调起微信",真正的登录 code 走下面的回调
var launched = await fluwx.authBy(
which: NormalAuth(
scope: "snsapi_userinfo",
state: "wechat_sdk_demo",
),
);
print("调起微信结果:$launched");
} catch (e) {
print("登录请求发送失败:$e");
}
}
2. 处理登录回调
void initState() {
super.initState();
final fluwx = Fluwx();
// 5.x 起订阅回调用 addSubscriber,旧的 weChatResponseEventHandler 已移除;
// 返回的对象可调用 cancel() 取消订阅
fluwx.addSubscriber((res) {
if (res is WeChatAuthResponse) {
// 处理登录结果
print("登录结果:code=${res.code}");
// 获取到code后,需要将code发送到自己的服务器换取access_token
}
});
}
微信支付实现
1. 发起支付
Future<void> startWeChatPay({
required String prepayId,
required String partnerId,
required String packageValue,
required String nonceStr,
required int timeStamp, // 4.x 起 timestamp 是 int,不再是 String
required String sign,
}) async {
try {
final fluwx = Fluwx();
// 返回的是"是否成功调起微信支付",不是支付结果;结果走下面的回调
var launched = await fluwx.pay(
which: Payment(
appId: "你的AppID",
partnerId: partnerId,
prepayId: prepayId,
packageValue: packageValue,
nonceStr: nonceStr,
timestamp: timeStamp,
sign: sign,
),
);
print("调起微信支付结果:$launched");
} catch (e) {
print("支付请求发送失败:$e");
}
}
2. 处理支付回调
void initState() {
super.initState();
final fluwx = Fluwx();
fluwx.addSubscriber((res) {
if (res is WeChatPaymentResponse) {
// 处理支付结果(客户端回调仅供展示,到底付没付钱以服务端为准)
if (res.isSuccessful) {
print("支付成功");
} else {
print("支付失败:${res.errStr}");
}
}
});
}
分享功能实现
1. 分享文本
Future<void> shareText(String text) async {
try {
final fluwx = Fluwx();
// 4.x 起:share 是实例方法;scene 枚举值按 Dart 规范改为小写
var result = await fluwx.share(
WeChatShareTextModel(
text,
scene: WeChatScene.session, // 分享到会话
),
);
print("分享请求发送结果:$result");
} catch (e) {
print("分享请求发送失败:$e");
}
}
2. 分享图片
Future<void> shareImage(String imagePath) async {
try {
final fluwx = Fluwx();
// 4.x 起图片要包一层 WeChatImageToShare
var result = await fluwx.share(
WeChatShareImageModel(
WeChatImageToShare(localImagePath: imagePath),
scene: WeChatScene.timeline, // 分享到朋友圈
),
);
print("分享请求发送结果:$result");
} catch (e) {
print("分享请求发送失败:$e");
}
}
3. 分享网页
Future<void> shareWebPage({
required String url,
required String title,
required String description,
}) async {
try {
final fluwx = Fluwx();
// 4.x 起:webPage 改为位置参数;thumbnail 参数已移除,
// 缩略图现在走 thumbData(Uint8List,需自己把网络图下载成字节再传)
var result = await fluwx.share(
WeChatShareWebPageModel(
url,
title: title,
description: description,
scene: WeChatScene.session,
),
);
print("分享请求发送结果:$result");
} catch (e) {
print("分享请求发送失败:$e");
}
}
打开小程序
1. 基本用法
Future<void> openMiniProgram({
required String username, // 小程序原始ID
required String path, // 小程序页面路径
WXMiniProgramType type = WXMiniProgramType.release, // 小程序类型
}) async {
try {
final fluwx = Fluwx();
var result = await fluwx.open(
target: MiniProgram(
username: username,
path: path,
miniProgramType: type,
),
);
print("打开小程序结果:$result");
} catch (e) {
print("打开小程序失败:$e");
}
}
2. 小程序类型说明
Fluwx支持打开不同类型的小程序版本:
enum WXMiniProgramType {
release, // 正式版
test, // 体验版
preview // 开发版
}
- 正式版(release):已上线的小程序版本,适用于生产环境
- 体验版(test):开发完成待审核的版本,用于测试验证
- 开发版(preview):开发中的版本,用于开发调试
3. 环境切换示例
class MiniProgramConfig {
static WXMiniProgramType getType(String env) {
switch (env) {
case 'prod':
return WXMiniProgramType.release;
case 'staging':
return WXMiniProgramType.test;
case 'dev':
return WXMiniProgramType.preview;
default:
return WXMiniProgramType.release;
}
}
}
// 使用示例
Future<void> openMiniProgramWithEnv({
required String username,
required String path,
required String env,
}) async {
final type = MiniProgramConfig.getType(env);
await openMiniProgram(
username: username,
path: path,
type: type,
);
}
4. 错误处理
class MiniProgramHelper {
static Future<bool> openMiniProgramSafely({
required String username,
required String path,
WXMiniProgramType type = WXMiniProgramType.release,
}) async {
try {
final fluwx = Fluwx();
// 检查微信是否安装(4.x 起 isWeChatInstalled 是实例 getter)
var installed = await fluwx.isWeChatInstalled;
if (!installed) {
throw Exception("请先安装微信");
}
var result = await fluwx.open(
target: MiniProgram(
username: username,
path: path,
miniProgramType: type,
),
);
return result;
} catch (e) {
print("打开小程序失败:$e");
// 可以根据需要显示错误提示或进行其他处理
return false;
}
}
}
// 使用示例
final success = await MiniProgramHelper.openMiniProgramSafely(
username: "gh_xxxxx", // 小程序原始ID
path: "pages/index/index", // 页面路径
type: WXMiniProgramType.release,
);
if (success) {
print("小程序打开成功");
} else {
print("小程序打开失败");
}
5. 注意事项
- 确保已正确初始化Fluwx(参考前面的初始化章节)
- 小程序原始ID可在微信开放平台查看
- 页面路径需要符合小程序路由规则
- 建议在打开小程序前先检查微信是否安装
- 不同类型的小程序版本需要对应的权限
常见问题及解决方案
1. 微信未安装
在使用微信相关功能前,建议先检查微信是否安装:
Future<void> checkWeChatInstalled() async {
final fluwx = Fluwx();
var installed = await fluwx.isWeChatInstalled;
if (!installed) {
// 提示用户安装微信
print("请先安装微信");
return;
}
// 继续执行微信相关操作
}
2. 签名校验失败
常见原因:
- Android签名不匹配:确保在微信开放平台配置的签名与应用签名一致
- iOS Bundle ID不匹配:确保在微信开放平台配置的Bundle ID与应用Bundle ID一致
3. 分享图片失败
- 检查图片大小是否超过限制(建议不超过10MB)
- 确保图片路径正确且有访问权限
- 网络图片需要确保可以正常访问
4. 支付失败
- 检查支付参数是否完整且正确
- 确保签名算法正确
- 验证商户号是否正确
最佳实践
- 统一错误处理
class WeChatHelper {
static Future<T?> handleWeChatOperation<T>(Future<T> Function() operation) async {
try {
final fluwx = Fluwx();
var installed = await fluwx.isWeChatInstalled;
if (!installed) {
throw Exception("请先安装微信");
}
return await operation();
} catch (e) {
print("微信操作失败:$e");
// 可以根据需要显示错误提示或进行其他处理
return null;
}
}
}
// 使用示例
await WeChatHelper.handleWeChatOperation(() => loginWithWeChat());
- 响应式状态管理
class WeChatState extends ChangeNotifier {
bool _isLoading = false;
String? _error;
bool get isLoading => _isLoading;
String? get error => _error;
Future<void> performWeChatOperation(Future<void> Function() operation) async {
try {
_isLoading = true;
_error = null;
notifyListeners();
await operation();
} catch (e) {
_error = e.toString();
} finally {
_isLoading = false;
notifyListeners();
}
}
}
实战案例
微信 SDK(分享/登录/支付)我还没在项目里接过——我的 App 都没做到需要微信登录的体量。但我研究过 fluwx 的接入,最大的坑不在代码,在资质:微信开放平台注册、AppID 申请、应用签名校验,个人开发者光是”应用官网”这一项就卡住(要 ICP 备案的域名)。代码层面反而简单,按文档配好微信 scheme 回调就行。我的建议:个人小项目别碰微信 SDK,先把”手机号+验证码”登录跑通;真要做,预留两周走资质流程,代码只占 20% 工作量。参考:fluwx 官方文档。
总结
本篇覆盖了 fluwx 的主要能力:初始化、微信登录、微信支付、分享与打开小程序。资质与签名配置是实际接入中的主要工作量,代码只是最后一步;上线前务必在真机上走完登录→支付→分享的完整回调链路。
