Compare commits

...

25 Commits

Author SHA1 Message Date
f589f9ebd7 update wechat ios sdk to 2.0.5 2025-07-24 16:49:03 +08:00
snowfox
629cb18cbd
Merge pull request #284 from Norcy/feat/qrcode
实现扫码登录
2024-08-22 15:26:12 +08:00
snowfox
03f117dc08
Merge pull request #283 from Norcy/fix/compile
修复安卓编译问题
2024-08-22 15:16:45 +08:00
Norcy
6a54386a6f 回滚格式 2024-08-19 16:59:00 +08:00
Norcy
59b1e05de0 添加 sha1 加密依赖,用于微信登录加密 2024-08-19 16:58:24 +08:00
Norcy
d1c5e74ea5 文档 2024-08-19 16:56:30 +08:00
Norcy
86bc8bd031 JS 封装 2024-08-19 16:51:41 +08:00
Norcy
80739f7ab7 文档 2024-08-19 15:37:09 +08:00
Norcy
f356067265 安卓实现扫码登录 2024-08-19 15:22:09 +08:00
Norcy
a325e153c8 iOS 实现扫码登录 2024-08-19 15:19:33 +08:00
Norcy
52275af954 修复安卓编译问题 2024-08-19 15:11:25 +08:00
snowfox
7e90d9d7d2
Merge pull request #282 from Norcy/feat/scan
双端实现分享本地文件到微信
2024-08-08 14:52:57 +08:00
chenying09
3376243a2c 格式化 2024-08-07 21:57:53 +08:00
chenying09
41bd398214 格式化 2024-08-07 21:54:06 +08:00
chenying09
d6ef691f95 格式化 2024-08-07 21:49:11 +08:00
chenying09
81915e19e0 文档 2024-08-07 21:42:50 +08:00
chenying09
ad9b5f1ef1 支持分享本地文件 2024-08-07 21:29:18 +08:00
chenying09
efe268229f 支持分享本地文件 2024-08-07 21:26:30 +08:00
chenying09
367ae4bbde 支持分享本地文件 2024-08-07 21:19:51 +08:00
chenying09
48b51fd8df 格式化 2024-08-07 21:14:37 +08:00
snowfox
2c774270cb
Merge pull request #245 from BambooSword/master
feat: add openCustomerServiceChat method
2023-07-01 16:41:27 +08:00
BambooSword
9ba05c11e5 fix: add the corpId param 2023-06-27 21:40:06 +08:00
BambooSword
d3292dd064 feat: add openCustomerServiceChat method 2023-06-23 22:08:37 +08:00
snowfox
d73102a44a
Update README.md 2023-05-11 16:58:45 +08:00
snowfox
d65934cf8d
Update README.md 2023-05-11 16:57:55 +08:00
12 changed files with 659 additions and 232 deletions

View File

@ -17,7 +17,7 @@
<br> <br>
## 路线图 ## 路线图
- 3.0.0 - 3.0.x
- [X] React native 70 - [X] React native 70
- [X] Android SDK 6.8.20 - [X] Android SDK 6.8.20
- [X] iOS SDK 2.0 - [X] iOS SDK 2.0
@ -34,9 +34,9 @@
## 注意 ## 注意
如果你的 IOS 应用需要使用**不带支付功能**的 WeChat SDK请使用带有 “-notpay” 后缀的 NPM 包。 如果你的 IOS 应用需要使用**不带支付功能**的 WeChat SDK请使用带有 “-notpay” 后缀的 NPM 包。
目前最新代码版本为 3.0.0但 NPM Last 版本暂时只到 1.1.26,因为 **3.0.0 暂时还处于开发阶段**,很多功能**未经过测试**。 目前最新代码版本为 3.0.x但 NPM Last 版本暂时只到 1.1.26,因为 **3.0.x 暂时还处于开发阶段**,有小部分功能**未经过测试**。
如果你需要使用 3.0.0 版本,请在 package.json 中加上版本号 react-native-wechat-lib@3.0.0,切换前请你清楚了解该版本的风险,该版本为开发版。 如果你需要使用 3.0.x 版本,请在 package.json 中加上版本号 react-native-wechat-lib@3.0.4,切换前请你清楚了解该版本的风险,该版本为开发版。
我会尽快推出 3.0.x 发行版。 我会尽快推出 3.0.x 发行版。
@ -154,6 +154,36 @@ following fields:
| lang | String | The user language | | lang | String | The user language |
| country | String | The user country | | country | String | The user country |
#### authByScan([scope, nonceStr, onQRGet]) 微信扫码授权登录
- `appId` {String} the appId you get from WeChat dashboard
- `appSecret` {String} the appSecret you get from WeChat dashboard
- `onQRGet` (String) => void
调用 authByScan 后,需要监听二维码的获取,展示完二维码,用户扫码登录完成后才会回调 callback字段如下
| field | type | description |
| ------- | ------ | ----------------------------------- |
| errCode | Number | Error Code |
| errStr | String | Error message if any error occurred |
| nickname | String | 微信昵称 |
| headimgurl | String | 微信头像链接 |
| openid | String | openid |
| unionid | String | unionid |
示例如下
```js
const ret = await WeChat.authByScan(WeiXinId, WeiXinSecret, (qrcode) => {
console.log(qrcode)
// 拿到 qrcode 用 Image 去渲染
});
console.log('登录信息', ret);
```
如有不懂,可以查看[微信官方文档](https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_Login/Login_via_Scan.html)
#### ShareText(ShareTextMetadata) 分享文本 #### ShareText(ShareTextMetadata) 分享文本
ShareTextMetadata ShareTextMetadata
@ -226,7 +256,7 @@ ShareFileMetadata
| name | type | description | | name | type | description |
| ----- | ------ | -------------- | | ----- | ------ | -------------- |
| url | String | 文件地址 | | url | String | 文件地址。如果是远程文件,则为 http 开头;如果是本地文件,则为绝对路径,如 /storage/emulated/0/Android/xxx |
| title | String | 文件标题 | | title | String | 文件标题 |
| scene | Number | 分享到, 0:会话 | | scene | Number | 分享到, 0:会话 |
@ -237,6 +267,9 @@ Return:
| errCode | Number | 0 if authorization succeed | | errCode | Number | 0 if authorization succeed |
| errStr | String | Error message if any error occurred | | errStr | String | Error message if any error occurred |
安卓实现分享本地文件需要对工程进行一些配置,详见 [Android 安装](./docs/build-setup-android.md#分享本地文件)
```js ```js
import * as WeChat from 'react-native-wechat-lib'; import * as WeChat from 'react-native-wechat-lib';

View File

@ -6,8 +6,10 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.net.Uri; import android.net.Uri;
import android.os.Environment; import android.os.Environment;
import android.util.Base64;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;
import com.facebook.common.executors.UiThreadImmediateExecutorService; import com.facebook.common.executors.UiThreadImmediateExecutorService;
import com.facebook.common.internal.Files; import com.facebook.common.internal.Files;
@ -24,14 +26,21 @@ import com.facebook.imagepipeline.request.ImageRequestBuilder;
import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule; import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.modules.core.RCTNativeAppEventEmitter;
import com.tencent.mm.opensdk.diffdev.DiffDevOAuthFactory;
import com.tencent.mm.opensdk.diffdev.IDiffDevOAuth;
import com.tencent.mm.opensdk.diffdev.OAuthErrCode;
import com.tencent.mm.opensdk.diffdev.OAuthListener;
import com.tencent.mm.opensdk.modelbase.BaseReq; import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp; import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.modelbiz.ChooseCardFromWXCardPackage; import com.tencent.mm.opensdk.modelbiz.ChooseCardFromWXCardPackage;
import com.tencent.mm.opensdk.modelbiz.WXOpenCustomerServiceChat;
import com.tencent.mm.opensdk.modelmsg.SendAuth; import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX; import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.ShowMessageFromWX; import com.tencent.mm.opensdk.modelmsg.ShowMessageFromWX;
@ -147,6 +156,42 @@ public class WeChatLibModule extends ReactContextBaseJavaModule implements IWXAP
} }
} }
private void sendEvent(ReactContext reactContext, String eventName, WritableMap params) {
reactContext.getJSModule(RCTNativeAppEventEmitter.class).emit(eventName, params);
}
@ReactMethod
public void authByScan(String appid, String nonceStr, String timeStamp, String scope, String signature, String schemeData, final Callback callback) {
if (api == null) {
callback.invoke(NOT_REGISTERED);
return;
}
IDiffDevOAuth oauth = DiffDevOAuthFactory.getDiffDevOAuth();
oauth.stopAuth();
oauth.auth(appid, scope, nonceStr, timeStamp, signature, new OAuthListener() {
@Override
public void onAuthGotQrcode(String var1, byte[] var2){
WritableMap map = Arguments.createMap();
String base64String = Base64.encodeToString(var2, Base64.DEFAULT);
map.putString("qrcode", base64String);
sendEvent(getReactApplicationContext(), "onAuthGotQrcode", map);
}
@Override
public void onQrcodeScanned() {
}
@Override
public void onAuthFinish(OAuthErrCode var1, String var2){
WritableMap map = Arguments.createMap();
map.putString("authCode", var2);
map.putInt("errCode", var1.getCode());
callback.invoke(null, map);
}
});
}
@ReactMethod @ReactMethod
public void registerApp(String appid, String universalLink, Callback callback) { public void registerApp(String appid, String universalLink, Callback callback) {
this.appId = appid; this.appId = appid;
@ -254,6 +299,21 @@ public class WeChatLibModule extends ReactContextBaseJavaModule implements IWXAP
return data; return data;
} }
public String getFileUri(Context context, File file) {
if (file == null || !file.exists()) {
return null;
}
Uri contentUri = FileProvider.getUriForFile(context,
context.getPackageName() + ".fileprovider", // 要与`AndroidManifest.xml`里配置的`authorities`一致
file);
// 授权给微信访问路径
context.grantUriPermission("com.tencent.mm", // 这里填微信包名
contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
return contentUri.toString(); // contentUri.toString() 即是以"content://"开头的用于共享的路径
}
/** /**
* 分享文本 * 分享文本
@ -264,7 +324,15 @@ public class WeChatLibModule extends ReactContextBaseJavaModule implements IWXAP
@ReactMethod @ReactMethod
public void shareFile(ReadableMap data, Callback callback) throws Exception { public void shareFile(ReadableMap data, Callback callback) throws Exception {
WXFileObject fileObj = new WXFileObject(); WXFileObject fileObj = new WXFileObject();
fileObj.fileData = loadRawDataFromURL(data.getString("url"));
String url = data.getString("url");
if (url.startsWith("http")) {
fileObj.fileData = loadRawDataFromURL(url);
} else {
File file = new File(url);
String fileUri = getFileUri(getReactApplicationContext(), file);
fileObj.filePath = fileUri;
}
WXMediaMessage msg = new WXMediaMessage(); WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = fileObj; msg.mediaObject = fileObj;
@ -672,6 +740,20 @@ public class WeChatLibModule extends ReactContextBaseJavaModule implements IWXAP
callback.invoke(api.sendReq(payReq) ? null : INVOKE_FAILED); callback.invoke(api.sendReq(payReq) ? null : INVOKE_FAILED);
} }
@ReactMethod
public void openCustomerServiceChat(String corpId, String kfUrl, Callback callback) {
if (api == null) {
callback.invoke(NOT_REGISTERED);
return;
}
// open customer service logic
WXOpenCustomerServiceChat.Req req = new WXOpenCustomerServiceChat.Req();
req.corpId = corpId;
req.url = kfUrl;
callback.invoke(null, api.sendReq(req));
}
private void _share(final int scene, final ReadableMap data, final Callback callback) { private void _share(final int scene, final ReadableMap data, final Callback callback) {
Uri uri = null; Uri uri = null;
if (data.hasKey("thumbImage")) { if (data.hasKey("thumbImage")) {

View File

@ -114,6 +114,43 @@ android:launchMode="singleTask"
</manifest> </manifest>
``` ```
## 分享本地文件
如果你需要分享本地文件,需要在 Android 的工程里进行一些设置,否则会有权限问题
步骤 1app/src/main/AndroidManifest.xml 中添加 provider 标签,其中 com.yourapp.xxx 要替换为你自己的包名,记得保留后面的 `.fileprovider`
```xml
<application ...>
...
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.yourapp.xxx.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
...
</application>
```
步骤 2实现 app/src/main/res/xml/filepaths.xml
```xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="myexternalimages" path="Download/" />
<cache-path name="my_cache_files" path="." />
<root-path name="root" path="" />
<files-path name="files-path" path="." />
</paths>
```
在这个 XML 文件中,你可以定义不同的路径类型(如 cache-path、external-path 等),以及对应的路径前缀。这样,在使用 FileProvider.getUriForFile() 时,就可以根据这些定义来获取正确的 URI。
请注意,当组件库被集成到不同的应用中时,你可能需要根据你自己的需求调整 filepaths.xml 中的路径定义。
## 关于 Android11 ## 关于 Android11
微信将于近期发布 targetSdkVersion 30的客户端版本因Android11系统特性该微信版本在Android 11及以上系统版本的设备上运行时授权登录、分享、微信支付等功能受到影响可能无法正常使用。为了适配 Android 系统新版本特性保证微信功能正常使用请第三方应用2021年11月1日之前进行更新 微信将于近期发布 targetSdkVersion 30的客户端版本因Android11系统特性该微信版本在Android 11及以上系统版本的设备上运行时授权登录、分享、微信支付等功能受到影响可能无法正常使用。为了适配 Android 系统新版本特性保证微信功能正常使用请第三方应用2021年11月1日之前进行更新

View File

@ -1,4 +1,4 @@
// test3 //
// WXApi.h // WXApi.h
// 所有Api接口 // 所有Api接口
// //

View File

@ -308,6 +308,9 @@ typedef void(^WXCheckULCompletion)(WXULCheckStep step, WXCheckULStepResult* resu
@property (nonatomic, copy, nullable) NSString *code; @property (nonatomic, copy, nullable) NSString *code;
/** 第三方程序发送时用来标识其请求的唯一性的标志由第三方程序调用sendReq时传入由微信终端回传 /** 第三方程序发送时用来标识其请求的唯一性的标志由第三方程序调用sendReq时传入由微信终端回传
* @note state字符串长度不能超过1K * @note state字符串长度不能超过1K
* @note
* SendAuthResp的内容
* SendAuthResp.state符合预期时
*/ */
@property (nonatomic, copy, nullable) NSString *state; @property (nonatomic, copy, nullable) NSString *state;
@property (nonatomic, copy, nullable) NSString *lang; @property (nonatomic, copy, nullable) NSString *lang;
@ -821,7 +824,7 @@ typedef void(^WXCheckULCompletion)(WXULCheckStep step, WXCheckULStepResult* resu
/*! @brief 设置消息缩略图的方法 /*! @brief 设置消息缩略图的方法
* *
* @param image * @param image
* @note 64K * @note 256K
*/ */
- (void)setThumbImage:(UIImage *)image; - (void)setThumbImage:(UIImage *)image;
@ -853,6 +856,17 @@ typedef void(^WXCheckULCompletion)(WXULCheckStep step, WXCheckULStepResult* resu
*/ */
@property (nonatomic, copy, nullable) NSString *imgDataHash; @property (nonatomic, copy, nullable) NSString *imgDataHash;
/** 分享的图片消息是否要带小程序入口,若 'entranceMiniProgramUsername' 非空则显示
*
* @note app图片消息
*/
@property (nonatomic, copy, nullable) NSString *entranceMiniProgramUsername;
/** 分享的图片消息显示的小程序入口可以跳转的小程序路径
* 'entranceMiniProgramUsername'
*/
@property (nonatomic, copy, nullable) NSString *entranceMiniProgramPath;
@end @end
@ -1235,6 +1249,31 @@ typedef void(^WXCheckULCompletion)(WXULCheckStep step, WXCheckULStepResult* resu
@end @end
@interface WXNativeGamePageObject : NSObject
/** 是否为视频类型
*/
@property (nonatomic, assign) BOOL isVideo;
/** 视频时长
@note
*/
@property (nonatomic, assign) UInt32 videoDuration;
/** 透传字段
@note 100K
*/
@property (nonatomic, copy) NSString *shareData;
/** 缩略图
@note 256K
*/
@property (nonatomic, strong) NSData *gameThumbData;
+ (WXNativeGamePageObject *)object;
@end
#pragma mark - WXLaunchMiniProgramReq #pragma mark - WXLaunchMiniProgramReq
/*! @brief WXLaunchMiniProgramReq对象, 可实现通过sdk拉起微信小程序 /*! @brief WXLaunchMiniProgramReq对象, 可实现通过sdk拉起微信小程序

View File

@ -1,10 +1,17 @@
// Created by little-snow-fox on 2019-10-9. // Created by little-snow-fox on 2019-10-9.
#import "WechatLib.h"
#import "WXApiObject.h" #import "WXApiObject.h"
#import <React/RCTEventDispatcher.h> #import "WechatLib.h"
#import <React/RCTBridge.h> #import <React/RCTBridge.h>
#import <React/RCTLog.h> #import <React/RCTEventDispatcher.h>
#import <React/RCTImageLoader.h> #import <React/RCTImageLoader.h>
#import <React/RCTLog.h>
#import "WechatAuthSDK.h"
@interface WechatLib () <WechatAuthAPIDelegate>
@property (nonatomic, strong) WechatAuthSDK *authSDK;
@property (nonatomic, strong) RCTResponseSenderBlock scanCallback;
@end
@implementation WechatLib @implementation WechatLib
@ -16,35 +23,32 @@
RCT_EXPORT_MODULE() RCT_EXPORT_MODULE()
- (instancetype)init - (instancetype)init {
{
self = [super init]; self = [super init];
if (self) { if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleOpenURL:) name:@"RCTOpenURLNotification" object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleOpenURL:) name:@"RCTOpenURLNotification" object:nil];
self.authSDK = [[WechatAuthSDK alloc] init];
self.authSDK.delegate = self;
} }
return self; return self;
} }
- (void)dealloc - (void)dealloc {
{
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
} }
- (BOOL)handleOpenURL:(NSNotification *)aNotification - (BOOL)handleOpenURL:(NSNotification *)aNotification {
{ NSString *aURLString = [aNotification userInfo][@"url"];
NSString * aURLString = [aNotification userInfo][@"url"]; NSURL *aURL = [NSURL URLWithString:aURLString];
NSURL * aURL = [NSURL URLWithString:aURLString];
if ([WXApi handleOpenURL:aURL delegate:self]) if ([WXApi handleOpenURL:aURL delegate:self]) {
{
return YES; return YES;
} else { } else {
return NO; return NO;
} }
} }
- (dispatch_queue_t)methodQueue - (dispatch_queue_t)methodQueue {
{
return dispatch_get_main_queue(); return dispatch_get_main_queue();
} }
@ -53,9 +57,9 @@ RCT_EXPORT_MODULE()
} }
// 获取网络图片的公共方法 // 获取网络图片的公共方法
- (UIImage *) getImageFromURL:(NSString *)fileURL { - (UIImage *)getImageFromURL:(NSString *)fileURL {
UIImage * result; UIImage *result;
NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]]; NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];
result = [UIImage imageWithData:data]; result = [UIImage imageWithData:data];
return result; return result;
} }
@ -89,7 +93,7 @@ RCT_EXPORT_MODULE()
lastDataLength = data.length; lastDataLength = data.length;
CGFloat ratio = (CGFloat)maxLength / data.length; CGFloat ratio = (CGFloat)maxLength / data.length;
CGSize size = CGSizeMake((NSUInteger)(resultImage.size.width * sqrtf(ratio)), CGSize size = CGSizeMake((NSUInteger)(resultImage.size.width * sqrtf(ratio)),
(NSUInteger)(resultImage.size.height * sqrtf(ratio))); // Use NSUInteger to prevent white blank (NSUInteger)(resultImage.size.height * sqrtf(ratio))); // Use NSUInteger to prevent white blank
UIGraphicsBeginImageContext(size); UIGraphicsBeginImageContext(size);
[resultImage drawInRect:CGRectMake(0, 0, size.width, size.height)]; [resultImage drawInRect:CGRectMake(0, 0, size.width, size.height)];
resultImage = UIGraphicsGetImageFromCurrentImageContext(); resultImage = UIGraphicsGetImageFromCurrentImageContext();
@ -104,10 +108,10 @@ RCT_EXPORT_MODULE()
return data; return data;
} }
RCT_EXPORT_METHOD(registerApp:(NSString *)appid RCT_EXPORT_METHOD(registerApp
:(NSString *)appid
:(NSString *)universalLink :(NSString *)universalLink
:(RCTResponseSenderBlock)callback) :(RCTResponseSenderBlock)callback) {
{
self.appId = appid; self.appId = appid;
callback(@[[WXApi registerApp:appid universalLink:universalLink] ? [NSNull null] : INVOKE_FAILED]); callback(@[[WXApi registerApp:appid universalLink:universalLink] ? [NSNull null] : INVOKE_FAILED]);
} }
@ -119,56 +123,49 @@ RCT_EXPORT_METHOD(registerApp:(NSString *)appid
// callback(@[[WXApi registerApp:appid withDescription:appdesc] ? [NSNull null] : INVOKE_FAILED]); // callback(@[[WXApi registerApp:appid withDescription:appdesc] ? [NSNull null] : INVOKE_FAILED]);
// } // }
RCT_EXPORT_METHOD(isWXAppInstalled:(RCTResponseSenderBlock)callback) RCT_EXPORT_METHOD(isWXAppInstalled:(RCTResponseSenderBlock)callback) {
{
callback(@[[NSNull null], @([WXApi isWXAppInstalled])]); callback(@[[NSNull null], @([WXApi isWXAppInstalled])]);
} }
RCT_EXPORT_METHOD(isWXAppSupportApi:(RCTResponseSenderBlock)callback) RCT_EXPORT_METHOD(isWXAppSupportApi:(RCTResponseSenderBlock)callback) {
{
callback(@[[NSNull null], @([WXApi isWXAppSupportApi])]); callback(@[[NSNull null], @([WXApi isWXAppSupportApi])]);
} }
RCT_EXPORT_METHOD(getWXAppInstallUrl:(RCTResponseSenderBlock)callback) RCT_EXPORT_METHOD(getWXAppInstallUrl:(RCTResponseSenderBlock)callback) {
{
callback(@[[NSNull null], [WXApi getWXAppInstallUrl]]); callback(@[[NSNull null], [WXApi getWXAppInstallUrl]]);
} }
RCT_EXPORT_METHOD(getApiVersion:(RCTResponseSenderBlock)callback) RCT_EXPORT_METHOD(getApiVersion:(RCTResponseSenderBlock)callback) {
{
callback(@[[NSNull null], [WXApi getApiVersion]]); callback(@[[NSNull null], [WXApi getApiVersion]]);
} }
RCT_EXPORT_METHOD(openWXApp:(RCTResponseSenderBlock)callback) RCT_EXPORT_METHOD(openWXApp:(RCTResponseSenderBlock)callback) {
{
callback(@[([WXApi openWXApp] ? [NSNull null] : INVOKE_FAILED)]); callback(@[([WXApi openWXApp] ? [NSNull null] : INVOKE_FAILED)]);
} }
RCT_EXPORT_METHOD(sendRequest:(NSString *)openid RCT_EXPORT_METHOD(sendRequest
:(RCTResponseSenderBlock)callback) :(NSString *)openid
{ :(RCTResponseSenderBlock)callback) {
BaseReq* req = [[BaseReq alloc] init]; BaseReq *req = [[BaseReq alloc] init];
req.openID = openid; req.openID = openid;
// callback(@[[WXApi sendReq:req] ? [NSNull null] : INVOKE_FAILED]); // callback(@[[WXApi sendReq:req] ? [NSNull null] : INVOKE_FAILED]);
void ( ^ completion )( BOOL ); void (^completion)(BOOL);
completion = ^( BOOL success ) completion = ^(BOOL success) {
{
callback(@[success ? [NSNull null] : INVOKE_FAILED]); callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return; return;
}; };
[WXApi sendReq:req completion:completion]; [WXApi sendReq:req completion:completion];
} }
RCT_EXPORT_METHOD(sendAuthRequest:(NSString *)scope RCT_EXPORT_METHOD(sendAuthRequest
:(NSString *)scope
:(NSString *)state :(NSString *)state
:(RCTResponseSenderBlock)callback) :(RCTResponseSenderBlock)callback) {
{ SendAuthReq *req = [[SendAuthReq alloc] init];
SendAuthReq* req = [[SendAuthReq alloc] init];
req.scope = scope; req.scope = scope;
req.state = state; req.state = state;
void ( ^ completion )( BOOL ); void (^completion)(BOOL);
completion = ^( BOOL success ) completion = ^(BOOL success) {
{
callback(@[success ? [NSNull null] : INVOKE_FAILED]); callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return; return;
}; };
@ -176,13 +173,12 @@ RCT_EXPORT_METHOD(sendAuthRequest:(NSString *)scope
[WXApi sendAuthReq:req viewController:rootViewController delegate:self completion:completion]; [WXApi sendAuthReq:req viewController:rootViewController delegate:self completion:completion];
} }
RCT_EXPORT_METHOD(sendSuccessResponse:(RCTResponseSenderBlock)callback) RCT_EXPORT_METHOD(sendSuccessResponse
{ :(RCTResponseSenderBlock)callback) {
BaseResp* resp = [[BaseResp alloc] init]; BaseResp *resp = [[BaseResp alloc] init];
resp.errCode = WXSuccess; resp.errCode = WXSuccess;
void ( ^ completion )( BOOL ); void (^completion)(BOOL);
completion = ^( BOOL success ) completion = ^(BOOL success) {
{
callback(@[success ? [NSNull null] : INVOKE_FAILED]); callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return; return;
}; };
@ -190,15 +186,14 @@ RCT_EXPORT_METHOD(sendSuccessResponse:(RCTResponseSenderBlock)callback)
// callback(@[[WXApi sendResp:resp] ? [NSNull null] : INVOKE_FAILED]); // callback(@[[WXApi sendResp:resp] ? [NSNull null] : INVOKE_FAILED]);
} }
RCT_EXPORT_METHOD(sendErrorCommonResponse:(NSString *)message RCT_EXPORT_METHOD(sendErrorCommonResponse
:(RCTResponseSenderBlock)callback) :(NSString *)message
{ :(RCTResponseSenderBlock)callback) {
BaseResp* resp = [[BaseResp alloc] init]; BaseResp *resp = [[BaseResp alloc] init];
resp.errCode = WXErrCodeCommon; resp.errCode = WXErrCodeCommon;
resp.errStr = message; resp.errStr = message;
void ( ^ completion )( BOOL ); void (^completion)(BOOL);
completion = ^( BOOL success ) completion = ^(BOOL success) {
{
callback(@[success ? [NSNull null] : INVOKE_FAILED]); callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return; return;
}; };
@ -206,15 +201,14 @@ RCT_EXPORT_METHOD(sendErrorCommonResponse:(NSString *)message
// callback(@[[WXApi sendResp:resp] ? [NSNull null] : INVOKE_FAILED]); // callback(@[[WXApi sendResp:resp] ? [NSNull null] : INVOKE_FAILED]);
} }
RCT_EXPORT_METHOD(sendErrorUserCancelResponse:(NSString *)message RCT_EXPORT_METHOD(sendErrorUserCancelResponse
:(RCTResponseSenderBlock)callback) :(NSString *)message
{ :(RCTResponseSenderBlock)callback) {
BaseResp* resp = [[BaseResp alloc] init]; BaseResp *resp = [[BaseResp alloc] init];
resp.errCode = WXErrCodeUserCancel; resp.errCode = WXErrCodeUserCancel;
resp.errStr = message; resp.errStr = message;
void ( ^ completion )( BOOL ); void (^completion)(BOOL);
completion = ^( BOOL success ) completion = ^(BOOL success) {
{
callback(@[success ? [NSNull null] : INVOKE_FAILED]); callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return; return;
}; };
@ -223,16 +217,15 @@ RCT_EXPORT_METHOD(sendErrorUserCancelResponse:(NSString *)message
} }
// 分享文本 // 分享文本
RCT_EXPORT_METHOD(shareText:(NSDictionary *)data RCT_EXPORT_METHOD(shareText
:(RCTResponseSenderBlock)callback) :(NSDictionary *)data
{ :(RCTResponseSenderBlock)callback) {
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init]; SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
req.bText = YES; req.bText = YES;
req.text = data[@"text"]; req.text = data[@"text"];
req.scene = [data[@"scene"] intValue]; req.scene = [data[@"scene"] intValue];
void ( ^ completion )( BOOL ); void (^completion)(BOOL);
completion = ^( BOOL success ) completion = ^(BOOL success) {
{
callback(@[success ? [NSNull null] : INVOKE_FAILED]); callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return; return;
}; };
@ -240,9 +233,9 @@ RCT_EXPORT_METHOD(shareText:(NSDictionary *)data
} }
// 选择发票 // 选择发票
RCT_EXPORT_METHOD(chooseInvoice:(NSDictionary *)data RCT_EXPORT_METHOD(chooseInvoice
:(RCTResponseSenderBlock)callback) :(NSDictionary *)data
{ :(RCTResponseSenderBlock)callback) {
WXChooseInvoiceReq *req = [[WXChooseInvoiceReq alloc] init]; WXChooseInvoiceReq *req = [[WXChooseInvoiceReq alloc] init];
req.appID = self.appId; req.appID = self.appId;
req.timeStamp = [data[@"timeStamp"] intValue]; req.timeStamp = [data[@"timeStamp"] intValue];
@ -250,9 +243,8 @@ RCT_EXPORT_METHOD(chooseInvoice:(NSDictionary *)data
req.cardSign = data[@"cardSign"]; req.cardSign = data[@"cardSign"];
req.signType = data[@"signType"]; req.signType = data[@"signType"];
void ( ^ completion )( BOOL ); void (^completion)(BOOL);
completion = ^( BOOL success ) completion = ^(BOOL success) {
{
callback(@[success ? [NSNull null] : INVOKE_FAILED]); callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return; return;
}; };
@ -260,13 +252,19 @@ RCT_EXPORT_METHOD(chooseInvoice:(NSDictionary *)data
} }
// 分享文件 // 分享文件
RCT_EXPORT_METHOD(shareFile:(NSDictionary *)data RCT_EXPORT_METHOD(shareFile
:(RCTResponseSenderBlock)callback) :(NSDictionary *)data
{ :(RCTResponseSenderBlock)callback) {
NSString *url = data[@"url"]; NSString *url = data[@"url"];
WXFileObject *file = [[WXFileObject alloc] init]; WXFileObject *file = [[WXFileObject alloc] init];
file.fileExtension = data[@"ext"]; file.fileExtension = data[@"ext"];
NSData *fileData = [NSData dataWithContentsOfURL:[NSURL URLWithString: url]];
NSData *fileData;
if ([url hasPrefix:@"http"]) {
fileData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
} else {
fileData = [NSData dataWithContentsOfFile:url];
}
file.fileData = fileData; file.fileData = fileData;
WXMediaMessage *message = [WXMediaMessage message]; WXMediaMessage *message = [WXMediaMessage message];
@ -277,9 +275,8 @@ RCT_EXPORT_METHOD(shareFile:(NSDictionary *)data
req.bText = NO; req.bText = NO;
req.message = message; req.message = message;
req.scene = [data[@"scene"] intValue]; req.scene = [data[@"scene"] intValue];
void ( ^ completion )( BOOL ); void (^completion)(BOOL);
completion = ^( BOOL success ) completion = ^(BOOL success) {
{
callback(@[success ? [NSNull null] : INVOKE_FAILED]); callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return; return;
}; };
@ -287,17 +284,16 @@ RCT_EXPORT_METHOD(shareFile:(NSDictionary *)data
} }
// 分享图片 // 分享图片
RCT_EXPORT_METHOD(shareImage:(NSDictionary *)data RCT_EXPORT_METHOD(shareImage
:(RCTResponseSenderBlock)callback) :(NSDictionary *)data
{ :(RCTResponseSenderBlock)callback) {
NSString *imageUrl = data[@"imageUrl"]; NSString *imageUrl = data[@"imageUrl"];
if (imageUrl == NULL || [imageUrl isEqual:@""]) { if (imageUrl == NULL || [imageUrl isEqual:@""]) {
callback([NSArray arrayWithObject:@"shareImage: The value of ImageUrl cannot be empty."]); callback([NSArray arrayWithObject:@"shareImage: The value of ImageUrl cannot be empty."]);
return; return;
} }
NSRange range = [imageUrl rangeOfString:@"."]; NSRange range = [imageUrl rangeOfString:@"."];
if ( range.length == 0) if (range.length == 0) {
{
callback([NSArray arrayWithObject:@"shareImage: ImageUrl value, Could not find file suffix."]); callback([NSArray arrayWithObject:@"shareImage: ImageUrl value, Could not find file suffix."]);
return; return;
} }
@ -311,8 +307,8 @@ RCT_EXPORT_METHOD(shareImage:(NSDictionary *)data
imageObject.imageData = imageData; imageObject.imageData = imageData;
WXMediaMessage *message = [WXMediaMessage message]; WXMediaMessage *message = [WXMediaMessage message];
// 利用原图压缩出缩略图确保缩略图大小不大于32KB // 利用原图压缩出缩略图,确保缩略图大小不大于 32KB
message.thumbData = [self compressImage: image toByte:32678]; message.thumbData = [self compressImage:image toByte:32678];
message.mediaObject = imageObject; message.mediaObject = imageObject;
message.title = data[@"title"]; message.title = data[@"title"];
message.description = data[@"description"]; message.description = data[@"description"];
@ -322,9 +318,8 @@ RCT_EXPORT_METHOD(shareImage:(NSDictionary *)data
req.message = message; req.message = message;
req.scene = [data[@"scene"] intValue]; req.scene = [data[@"scene"] intValue];
// [WXApi sendReq:req]; // [WXApi sendReq:req];
void ( ^ completion )( BOOL ); void (^completion)(BOOL);
completion = ^( BOOL success ) completion = ^(BOOL success) {
{
callback(@[success ? [NSNull null] : INVOKE_FAILED]); callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return; return;
}; };
@ -332,17 +327,16 @@ RCT_EXPORT_METHOD(shareImage:(NSDictionary *)data
} }
// 分享本地图片 // 分享本地图片
RCT_EXPORT_METHOD(shareLocalImage:(NSDictionary *)data RCT_EXPORT_METHOD(shareLocalImage
:(RCTResponseSenderBlock)callback) :(NSDictionary *)data
{ :(RCTResponseSenderBlock)callback) {
NSString *imageUrl = data[@"imageUrl"]; NSString *imageUrl = data[@"imageUrl"];
if (imageUrl == NULL || [imageUrl isEqual:@""]) { if (imageUrl == NULL || [imageUrl isEqual:@""]) {
callback([NSArray arrayWithObject:@"shareLocalImage: The value of ImageUrl cannot be empty."]); callback([NSArray arrayWithObject:@"shareLocalImage: The value of ImageUrl cannot be empty."]);
return; return;
} }
NSRange range = [imageUrl rangeOfString:@"."]; NSRange range = [imageUrl rangeOfString:@"."];
if ( range.length == 0) if (range.length == 0) {
{
callback([NSArray arrayWithObject:@"shareLocalImage: ImageUrl value, Could not find file suffix."]); callback([NSArray arrayWithObject:@"shareLocalImage: ImageUrl value, Could not find file suffix."]);
return; return;
} }
@ -356,8 +350,8 @@ RCT_EXPORT_METHOD(shareLocalImage:(NSDictionary *)data
imageObject.imageData = imageData; imageObject.imageData = imageData;
WXMediaMessage *message = [WXMediaMessage message]; WXMediaMessage *message = [WXMediaMessage message];
// 利用原图压缩出缩略图确保缩略图大小不大于32KB // 利用原图压缩出缩略图,确保缩略图大小不大于 32KB
message.thumbData = [self compressImage: image toByte:32678]; message.thumbData = [self compressImage:image toByte:32678];
message.mediaObject = imageObject; message.mediaObject = imageObject;
message.title = data[@"title"]; message.title = data[@"title"];
message.description = data[@"description"]; message.description = data[@"description"];
@ -367,9 +361,8 @@ RCT_EXPORT_METHOD(shareLocalImage:(NSDictionary *)data
req.message = message; req.message = message;
req.scene = [data[@"scene"] intValue]; req.scene = [data[@"scene"] intValue];
// [WXApi sendReq:req]; // [WXApi sendReq:req];
void ( ^ completion )( BOOL ); void (^completion)(BOOL);
completion = ^( BOOL success ) completion = ^(BOOL success) {
{
callback(@[success ? [NSNull null] : INVOKE_FAILED]); callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return; return;
}; };
@ -377,9 +370,9 @@ RCT_EXPORT_METHOD(shareLocalImage:(NSDictionary *)data
} }
// 分享音乐 // 分享音乐
RCT_EXPORT_METHOD(shareMusic:(NSDictionary *)data RCT_EXPORT_METHOD(shareMusic
:(RCTResponseSenderBlock)callback) :(NSDictionary *)data
{ :(RCTResponseSenderBlock)callback) {
WXMusicObject *musicObject = [WXMusicObject object]; WXMusicObject *musicObject = [WXMusicObject object];
musicObject.musicUrl = data[@"musicUrl"]; musicObject.musicUrl = data[@"musicUrl"];
musicObject.musicLowBandUrl = data[@"musicLowBandUrl"]; musicObject.musicLowBandUrl = data[@"musicLowBandUrl"];
@ -393,16 +386,15 @@ RCT_EXPORT_METHOD(shareMusic:(NSDictionary *)data
if (thumbImageUrl != NULL && ![thumbImageUrl isEqual:@""]) { if (thumbImageUrl != NULL && ![thumbImageUrl isEqual:@""]) {
// 根据路径下载图片 // 根据路径下载图片
UIImage *image = [self getImageFromURL:thumbImageUrl]; UIImage *image = [self getImageFromURL:thumbImageUrl];
message.thumbData = [self compressImage: image toByte:32678]; message.thumbData = [self compressImage:image toByte:32678];
} }
message.mediaObject = musicObject; message.mediaObject = musicObject;
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init]; SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
req.bText = NO; req.bText = NO;
req.message = message; req.message = message;
req.scene = [data[@"scene"] intValue]; req.scene = [data[@"scene"] intValue];
void ( ^ completion )( BOOL ); void (^completion)(BOOL);
completion = ^( BOOL success ) completion = ^(BOOL success) {
{
callback(@[success ? [NSNull null] : INVOKE_FAILED]); callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return; return;
}; };
@ -410,9 +402,9 @@ RCT_EXPORT_METHOD(shareMusic:(NSDictionary *)data
} }
// 分享视频 // 分享视频
RCT_EXPORT_METHOD(shareVideo:(NSDictionary *)data RCT_EXPORT_METHOD(shareVideo
:(RCTResponseSenderBlock)callback) :(NSDictionary *)data
{ :(RCTResponseSenderBlock)callback) {
WXVideoObject *videoObject = [WXVideoObject object]; WXVideoObject *videoObject = [WXVideoObject object];
videoObject.videoUrl = data[@"videoUrl"]; videoObject.videoUrl = data[@"videoUrl"];
videoObject.videoLowBandUrl = data[@"videoLowBandUrl"]; videoObject.videoLowBandUrl = data[@"videoLowBandUrl"];
@ -422,26 +414,24 @@ RCT_EXPORT_METHOD(shareVideo:(NSDictionary *)data
NSString *thumbImageUrl = data[@"thumbImageUrl"]; NSString *thumbImageUrl = data[@"thumbImageUrl"];
if (thumbImageUrl != NULL && ![thumbImageUrl isEqual:@""]) { if (thumbImageUrl != NULL && ![thumbImageUrl isEqual:@""]) {
UIImage *image = [self getImageFromURL:thumbImageUrl]; UIImage *image = [self getImageFromURL:thumbImageUrl];
message.thumbData = [self compressImage: image toByte:32678]; message.thumbData = [self compressImage:image toByte:32678];
} }
message.mediaObject = videoObject; message.mediaObject = videoObject;
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init]; SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
req.bText = NO; req.bText = NO;
req.message = message; req.message = message;
req.scene = [data[@"scene"] intValue]; req.scene = [data[@"scene"] intValue];
void ( ^ completion )( BOOL ); void (^completion)(BOOL);
completion = ^( BOOL success ) completion = ^(BOOL success) {
{
callback(@[success ? [NSNull null] : INVOKE_FAILED]); callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return; return;
}; };
[WXApi sendReq:req completion:completion]; [WXApi sendReq:req completion:completion];
} }
// 分享网页 // 分享网页
RCT_EXPORT_METHOD(shareWebpage:(NSDictionary *)data RCT_EXPORT_METHOD(shareWebpage
:(RCTResponseSenderBlock)callback) :(NSDictionary *)data
{ :(RCTResponseSenderBlock)callback) {
WXWebpageObject *webpageObject = [WXWebpageObject object]; WXWebpageObject *webpageObject = [WXWebpageObject object];
webpageObject.webpageUrl = data[@"webpageUrl"]; webpageObject.webpageUrl = data[@"webpageUrl"];
WXMediaMessage *message = [WXMediaMessage message]; WXMediaMessage *message = [WXMediaMessage message];
@ -450,16 +440,15 @@ RCT_EXPORT_METHOD(shareWebpage:(NSDictionary *)data
NSString *thumbImageUrl = data[@"thumbImageUrl"]; NSString *thumbImageUrl = data[@"thumbImageUrl"];
if (thumbImageUrl != NULL && ![thumbImageUrl isEqual:@""]) { if (thumbImageUrl != NULL && ![thumbImageUrl isEqual:@""]) {
UIImage *image = [self getImageFromURL:thumbImageUrl]; UIImage *image = [self getImageFromURL:thumbImageUrl];
message.thumbData = [self compressImage: image toByte:32678]; message.thumbData = [self compressImage:image toByte:32678];
} }
message.mediaObject = webpageObject; message.mediaObject = webpageObject;
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init]; SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
req.bText = NO; req.bText = NO;
req.message = message; req.message = message;
req.scene = [data[@"scene"] intValue]; req.scene = [data[@"scene"] intValue];
void ( ^ completion )( BOOL ); void (^completion)(BOOL);
completion = ^( BOOL success ) completion = ^(BOOL success) {
{
callback(@[success ? [NSNull null] : INVOKE_FAILED]); callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return; return;
}; };
@ -467,9 +456,9 @@ RCT_EXPORT_METHOD(shareWebpage:(NSDictionary *)data
} }
// 分享小程序 // 分享小程序
RCT_EXPORT_METHOD(shareMiniProgram:(NSDictionary *)data RCT_EXPORT_METHOD(shareMiniProgram
:(RCTResponseSenderBlock)callback) :(NSDictionary *)data
{ :(RCTResponseSenderBlock)callback) {
WXMiniProgramObject *object = [WXMiniProgramObject object]; WXMiniProgramObject *object = [WXMiniProgramObject object];
object.webpageUrl = data[@"webpageUrl"]; object.webpageUrl = data[@"webpageUrl"];
object.userName = data[@"userName"]; object.userName = data[@"userName"];
@ -477,8 +466,8 @@ RCT_EXPORT_METHOD(shareMiniProgram:(NSDictionary *)data
NSString *hdImageUrl = data[@"hdImageUrl"]; NSString *hdImageUrl = data[@"hdImageUrl"];
if (hdImageUrl != NULL && ![hdImageUrl isEqual:@""]) { if (hdImageUrl != NULL && ![hdImageUrl isEqual:@""]) {
UIImage *image = [self getImageFromURL:hdImageUrl]; UIImage *image = [self getImageFromURL:hdImageUrl];
// 压缩图片到小于128KB // 压缩图片到小于 128KB
object.hdImageData = [self compressImage: image toByte:131072]; object.hdImageData = [self compressImage:image toByte:131072];
} }
object.withShareTicket = data[@"withShareTicket"]; object.withShareTicket = data[@"withShareTicket"];
int miniProgramType = [data[@"miniProgramType"] integerValue]; int miniProgramType = [data[@"miniProgramType"] integerValue];
@ -486,21 +475,20 @@ RCT_EXPORT_METHOD(shareMiniProgram:(NSDictionary *)data
WXMediaMessage *message = [WXMediaMessage message]; WXMediaMessage *message = [WXMediaMessage message];
message.title = data[@"title"]; message.title = data[@"title"];
message.description = data[@"description"]; message.description = data[@"description"];
//兼容旧版本节点的图片小于32KB新版本优先 // 兼容旧版本节点的图片,小于 32KB新版本优先
//使用WXMiniProgramObject的hdImageData属性 // 使用 WXMiniProgramObject hdImageData 属性
NSString *thumbImageUrl = data[@"thumbImageUrl"]; NSString *thumbImageUrl = data[@"thumbImageUrl"];
if (thumbImageUrl != NULL && ![thumbImageUrl isEqual:@""]) { if (thumbImageUrl != NULL && ![thumbImageUrl isEqual:@""]) {
UIImage *image = [self getImageFromURL:thumbImageUrl]; UIImage *image = [self getImageFromURL:thumbImageUrl];
message.thumbData = [self compressImage: image toByte:32678]; message.thumbData = [self compressImage:image toByte:32678];
} }
message.mediaObject = object; message.mediaObject = object;
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init]; SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
req.bText = NO; req.bText = NO;
req.message = message; req.message = message;
req.scene = [data[@"scene"] integerValue]; req.scene = [data[@"scene"] integerValue];
void ( ^ completion )( BOOL ); void (^completion)(BOOL);
completion = ^( BOOL success ) completion = ^(BOOL success) {
{
callback(@[success ? [NSNull null] : INVOKE_FAILED]); callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return; return;
}; };
@ -508,27 +496,26 @@ RCT_EXPORT_METHOD(shareMiniProgram:(NSDictionary *)data
} }
// 一次性订阅消息 // 一次性订阅消息
RCT_EXPORT_METHOD(subscribeMessage:(NSDictionary *)data RCT_EXPORT_METHOD(subscribeMessage
:(RCTResponseSenderBlock)callback) :(NSDictionary *)data
{ :(RCTResponseSenderBlock)callback) {
WXSubscribeMsgReq *req = [[WXSubscribeMsgReq alloc] init]; WXSubscribeMsgReq *req = [[WXSubscribeMsgReq alloc] init];
req.scene = [data[@"scene"] integerValue]; req.scene = [data[@"scene"] integerValue];
req.templateId = data[@"templateId"]; req.templateId = data[@"templateId"];
req.reserved = data[@"reserved"]; req.reserved = data[@"reserved"];
void ( ^ completion )( BOOL ); void (^completion)(BOOL);
completion = ^( BOOL success ) completion = ^(BOOL success) {
{
callback(@[success ? [NSNull null] : INVOKE_FAILED]); callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return; return;
}; };
[WXApi sendReq:req completion:completion]; [WXApi sendReq:req completion:completion];
} }
RCT_EXPORT_METHOD(launchMiniProgram:(NSDictionary *)data RCT_EXPORT_METHOD(launchMiniProgram
:(RCTResponseSenderBlock)callback) :(NSDictionary *)data
{ :(RCTResponseSenderBlock)callback) {
WXLaunchMiniProgramReq *launchMiniProgramReq = [WXLaunchMiniProgramReq object]; WXLaunchMiniProgramReq *launchMiniProgramReq = [WXLaunchMiniProgramReq object];
// 拉起的小程序的username // 拉起的小程序的 username
launchMiniProgramReq.userName = data[@"userName"]; launchMiniProgramReq.userName = data[@"userName"];
// 拉起小程序页面的可带参路径,不填默认拉起小程序首页 // 拉起小程序页面的可带参路径,不填默认拉起小程序首页
launchMiniProgramReq.path = data[@"path"]; launchMiniProgramReq.path = data[@"path"];
@ -536,9 +523,8 @@ RCT_EXPORT_METHOD(launchMiniProgram:(NSDictionary *)data
int miniProgramType = [data[@"miniProgramType"] integerValue]; int miniProgramType = [data[@"miniProgramType"] integerValue];
launchMiniProgramReq.miniProgramType = [self integerToWXMiniProgramType:miniProgramType]; launchMiniProgramReq.miniProgramType = [self integerToWXMiniProgramType:miniProgramType];
// launchMiniProgramReq.miniProgramType = [data[@"miniProgramType"] integerValue]; // launchMiniProgramReq.miniProgramType = [data[@"miniProgramType"] integerValue];
void ( ^ completion )( BOOL ); void (^completion)(BOOL);
completion = ^( BOOL success ) completion = ^(BOOL success) {
{
callback(@[success ? [NSNull null] : INVOKE_FAILED]); callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return; return;
}; };
@ -547,19 +533,18 @@ RCT_EXPORT_METHOD(launchMiniProgram:(NSDictionary *)data
// callback(@[success ? [NSNull null] : INVOKE_FAILED]); // callback(@[success ? [NSNull null] : INVOKE_FAILED]);
} }
RCT_EXPORT_METHOD(pay:(NSDictionary *)data RCT_EXPORT_METHOD(pay
:(RCTResponseSenderBlock)callback) :(NSDictionary *)data
{ :(RCTResponseSenderBlock)callback) {
PayReq* req = [PayReq new]; PayReq *req = [PayReq new];
req.partnerId = data[@"partnerId"]; req.partnerId = data[@"partnerId"];
req.prepayId = data[@"prepayId"]; req.prepayId = data[@"prepayId"];
req.nonceStr = data[@"nonceStr"]; req.nonceStr = data[@"nonceStr"];
req.timeStamp = [data[@"timeStamp"] unsignedIntValue]; req.timeStamp = [data[@"timeStamp"] unsignedIntValue];
req.package = data[@"package"]; req.package = data[@"package"];
req.sign = data[@"sign"]; req.sign = data[@"sign"];
void ( ^ completion )( BOOL ); void (^completion)(BOOL);
completion = ^( BOOL success ) completion = ^(BOOL success) {
{
callback(@[success ? [NSNull null] : INVOKE_FAILED]); callback(@[success ? [NSNull null] : INVOKE_FAILED]);
return; return;
}; };
@ -568,75 +553,82 @@ RCT_EXPORT_METHOD(pay:(NSDictionary *)data
// callback(@[success ? [NSNull null] : INVOKE_FAILED]); // callback(@[success ? [NSNull null] : INVOKE_FAILED]);
} }
// 跳转微信客服
RCT_EXPORT_METHOD(openCustomerServiceChat
:(NSString *)corpId
:(NSString *)kfUrl
:(RCTResponseSenderBlock)callback) {
WXOpenCustomerServiceReq *req = [[WXOpenCustomerServiceReq alloc] init];
req.corpid = corpId; // 企业 ID
req.url = kfUrl; // 客服 URL
[WXApi sendReq:req completion:nil];
}
#pragma mark - wx callback #pragma mark - wx callback
-(void) onReq:(BaseReq*)req - (void)onReq:(BaseReq *)req {
{
if ([req isKindOfClass:[LaunchFromWXReq class]]) { if ([req isKindOfClass:[LaunchFromWXReq class]]) {
LaunchFromWXReq *launchReq = req; LaunchFromWXReq *launchReq = req;
NSString *appParameter = launchReq.message.messageExt; NSString *appParameter = launchReq.message.messageExt;
NSMutableDictionary *body = @{@"errCode":@0}.mutableCopy; NSMutableDictionary *body = @{ @"errCode": @0 }.mutableCopy;
body[@"type"] = @"LaunchFromWX.Req"; body[@"type"] = @"LaunchFromWX.Req";
body[@"lang"] = launchReq.lang; body[@"lang"] = launchReq.lang;
body[@"country"] = launchReq.country; body[@"country"] = launchReq.country;
body[@"extMsg"] = appParameter; body[@"extMsg"] = appParameter;
[self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventNameWeChatReq body:body]; [self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventNameWeChatReq body:body];
} }
} }
-(void) onResp:(BaseResp*)resp - (void)onResp:(BaseResp *)resp {
{ if ([resp isKindOfClass:[SendMessageToWXResp class]]) {
if([resp isKindOfClass:[SendMessageToWXResp class]])
{
SendMessageToWXResp *r = (SendMessageToWXResp *)resp; SendMessageToWXResp *r = (SendMessageToWXResp *)resp;
NSMutableDictionary *body = @{@"errCode":@(r.errCode)}.mutableCopy; NSMutableDictionary *body = @{ @"errCode": @(r.errCode) }.mutableCopy;
body[@"errStr"] = r.errStr; body[@"errStr"] = r.errStr;
body[@"lang"] = r.lang; body[@"lang"] = r.lang;
body[@"country"] =r.country; body[@"country"] = r.country;
body[@"type"] = @"SendMessageToWX.Resp"; body[@"type"] = @"SendMessageToWX.Resp";
[self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body]; [self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body];
} else if ([resp isKindOfClass:[SendAuthResp class]]) { } else if ([resp isKindOfClass:[SendAuthResp class]]) {
SendAuthResp *r = (SendAuthResp *)resp; SendAuthResp *r = (SendAuthResp *)resp;
NSMutableDictionary *body = @{@"errCode":@(r.errCode)}.mutableCopy; NSMutableDictionary *body = @{ @"errCode": @(r.errCode) }.mutableCopy;
body[@"errStr"] = r.errStr; body[@"errStr"] = r.errStr;
body[@"state"] = r.state; body[@"state"] = r.state;
body[@"lang"] = r.lang; body[@"lang"] = r.lang;
body[@"country"] =r.country; body[@"country"] = r.country;
body[@"type"] = @"SendAuth.Resp"; body[@"type"] = @"SendAuth.Resp";
if (resp.errCode == WXSuccess) { if (resp.errCode == WXSuccess) {
if (self.appId && r) { if (self.appId && r) {
// ios第一次获取不到appid会卡死加个判断OK // ios 第一次获取不到 appid 会卡死,加个判断 OK
[body addEntriesFromDictionary:@{@"appid":self.appId, @"code":r.code}]; [body addEntriesFromDictionary:@{ @"appid": self.appId, @"code": r.code }];
[self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body]; [self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body];
} }
} } else {
else {
[self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body]; [self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body];
} }
} else if ([resp isKindOfClass:[PayResp class]]) { } else if ([resp isKindOfClass:[PayResp class]]) {
PayResp *r = (PayResp *)resp; PayResp *r = (PayResp *)resp;
NSMutableDictionary *body = @{@"errCode":@(r.errCode)}.mutableCopy; NSMutableDictionary *body = @{ @"errCode": @(r.errCode) }.mutableCopy;
body[@"errStr"] = r.errStr; body[@"errStr"] = r.errStr;
body[@"type"] = @(r.type); body[@"type"] = @(r.type);
body[@"returnKey"] =r.returnKey; body[@"returnKey"] = r.returnKey;
body[@"type"] = @"PayReq.Resp"; body[@"type"] = @"PayReq.Resp";
[self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body]; [self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body];
} else if ([resp isKindOfClass:[WXLaunchMiniProgramResp class]]){ } else if ([resp isKindOfClass:[WXLaunchMiniProgramResp class]]) {
WXLaunchMiniProgramResp *r = (WXLaunchMiniProgramResp *)resp; WXLaunchMiniProgramResp *r = (WXLaunchMiniProgramResp *)resp;
NSMutableDictionary *body = @{@"errCode":@(r.errCode)}.mutableCopy; NSMutableDictionary *body = @{ @"errCode": @(r.errCode) }.mutableCopy;
body[@"errStr"] = r.errStr; body[@"errStr"] = r.errStr;
body[@"extMsg"] = r.extMsg; body[@"extMsg"] = r.extMsg;
body[@"type"] = @"WXLaunchMiniProgramReq.Resp"; body[@"type"] = @"WXLaunchMiniProgramReq.Resp";
[self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body]; [self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body];
} else if ([resp isKindOfClass:[WXChooseInvoiceResp class]]){ } else if ([resp isKindOfClass:[WXChooseInvoiceResp class]]) {
WXChooseInvoiceResp *r = (WXChooseInvoiceResp *)resp; WXChooseInvoiceResp *r = (WXChooseInvoiceResp *)resp;
NSMutableDictionary *body = @{@"errCode":@(r.errCode)}.mutableCopy; NSMutableDictionary *body = @{ @"errCode": @(r.errCode) }.mutableCopy;
body[@"errStr"] = r.errStr; body[@"errStr"] = r.errStr;
NSMutableArray *arr = [[NSMutableArray alloc] init]; NSMutableArray *arr = [[NSMutableArray alloc] init];
for (WXCardItem* cardItem in r.cardAry) { for (WXCardItem *cardItem in r.cardAry) {
NSMutableDictionary *item = @{@"cardId":cardItem.cardId,@"encryptCode":cardItem.encryptCode,@"appId":cardItem.appID}.mutableCopy; NSMutableDictionary *item = @{ @"cardId": cardItem.cardId, @"encryptCode": cardItem.encryptCode, @"appId": cardItem.appID }.mutableCopy;
[arr addObject:item]; [arr addObject:item];
} }
body[@"cards"] = arr; body[@"cards"] = arr;
@ -645,7 +637,7 @@ RCT_EXPORT_METHOD(pay:(NSDictionary *)data
} }
} }
-(WXMiniProgramType) integerToWXMiniProgramType:(int)value { - (WXMiniProgramType)integerToWXMiniProgramType:(int)value {
WXMiniProgramType type = WXMiniProgramTypeRelease; WXMiniProgramType type = WXMiniProgramTypeRelease;
switch (value) { switch (value) {
case 0: case 0:
@ -661,5 +653,56 @@ RCT_EXPORT_METHOD(pay:(NSDictionary *)data
return type; return type;
} }
@end #pragma mark - WechatAuthAPIDelegate
RCT_EXPORT_METHOD(addListener:(NSString *)eventName) {
}
RCT_EXPORT_METHOD(removeListeners:(double)count) {
}
RCT_EXPORT_METHOD(authByScan:(NSString *)appid
nonceStr:(NSString *)nonceStr
timeStamp:(NSString *)timeStamp
scope:(NSString *)scope
signature:(NSString *)signature
schemeData:(nullable NSString *)schemeData
callback:(RCTResponseSenderBlock)callback) {
self.scanCallback = callback;
[self.authSDK StopAuth];
[self.authSDK Auth:appid nonceStr:nonceStr timeStamp:timeStamp scope:scope signature:signature schemeData:schemeData];
}
//得到二维码
- (void)onAuthGotQrcode:(UIImage *)image {
NSLog(@"onAuthGotQrcode");
NSData *imageData = UIImagePNGRepresentation(image);
if (!imageData) {
imageData = UIImageJPEGRepresentation(image, 1);
}
NSString *base64String = [imageData base64EncodedStringWithOptions:0];
[self.bridge.eventDispatcher sendDeviceEventWithName:@"onAuthGotQrcode" body:@{@"qrcode": base64String}];
}
//二维码被扫描
- (void)onQrcodeScanned {
NSLog(@"onQrcodeScanned");
}
//成功登录
- (void)onAuthFinish:(int)errCode AuthCode:(nullable NSString *)authCode {
NSLog(@"onAuthFinish");
if (self.scanCallback) {
self.scanCallback(@[[NSNull null], @{@"authCode": authCode?:@"", @"errCode": @(errCode)}]);
self.scanCallback = nil;
}
}
- (NSArray<NSString *> *)supportedEvents
{
return @[@"onAuthGotQrcode", @"onQrcodeScanned", @"onAuthFinish"];
}
@end

View File

@ -8,7 +8,7 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
86D0366429A4BF3E00A01343 /* libWeChatSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 86D0365E29A4BF2600A01343 /* libWeChatSDK.a */; }; 86D0366429A4BF3E00A01343 /* libWeChatSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 86D0365E29A4BF2600A01343 /* libWeChatSDK.a */; };
86D0366529A4BF5900A01343 /* WechatLib.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* WechatLib.m */; }; 86D0366529A4BF5900A01343 /* WechatLib.mm in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* WechatLib.mm */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
@ -31,7 +31,7 @@
86D0366029A4BF2700A01343 /* WechatAuthSDK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WechatAuthSDK.h; sourceTree = "<group>"; }; 86D0366029A4BF2700A01343 /* WechatAuthSDK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WechatAuthSDK.h; sourceTree = "<group>"; };
86D0366129A4BF2700A01343 /* WXApi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXApi.h; sourceTree = "<group>"; }; 86D0366129A4BF2700A01343 /* WXApi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXApi.h; sourceTree = "<group>"; };
B3E7B5881CC2AC0600A0062D /* WechatLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WechatLib.h; sourceTree = "<group>"; }; B3E7B5881CC2AC0600A0062D /* WechatLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WechatLib.h; sourceTree = "<group>"; };
B3E7B5891CC2AC0600A0062D /* WechatLib.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WechatLib.m; sourceTree = "<group>"; }; B3E7B5891CC2AC0600A0062D /* WechatLib.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WechatLib.mm; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -63,7 +63,7 @@
86D0366129A4BF2700A01343 /* WXApi.h */, 86D0366129A4BF2700A01343 /* WXApi.h */,
86D0365D29A4BF2600A01343 /* WXApiObject.h */, 86D0365D29A4BF2600A01343 /* WXApiObject.h */,
B3E7B5881CC2AC0600A0062D /* WechatLib.h */, B3E7B5881CC2AC0600A0062D /* WechatLib.h */,
B3E7B5891CC2AC0600A0062D /* WechatLib.m */, B3E7B5891CC2AC0600A0062D /* WechatLib.mm */,
134814211AA4EA7D00B7C361 /* Products */, 134814211AA4EA7D00B7C361 /* Products */,
86D0366329A4BF3E00A01343 /* Frameworks */, 86D0366329A4BF3E00A01343 /* Frameworks */,
); );
@ -133,7 +133,7 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
86D0366529A4BF5900A01343 /* WechatLib.m in Sources */, 86D0366529A4BF5900A01343 /* WechatLib.mm in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

Binary file not shown.

View File

@ -71,14 +71,16 @@
"react-native": "0.70.6", "react-native": "0.70.6",
"react-native-builder-bob": "^0.20.0", "react-native-builder-bob": "^0.20.0",
"release-it": "^15.0.0", "release-it": "^15.0.0",
"typescript": "^4.5.2" "typescript": "^4.5.2",
"js-sha1": "^0.7.0"
}, },
"resolutions": { "resolutions": {
"@types/react": "17.0.21" "@types/react": "17.0.21"
}, },
"peerDependencies": { "peerDependencies": {
"react": "*", "react": "*",
"react-native": "*" "react-native": "*",
"js-sha1": "*"
}, },
"engines": { "engines": {
"node": ">= 16.0.0" "node": ">= 16.0.0"

60
src/index.d.ts vendored
View File

@ -9,7 +9,14 @@ enum WXScene {
} }
declare module 'react-native-wechat-lib' { declare module 'react-native-wechat-lib' {
export function registerApp(appId: string, universalLink?: string): Promise<boolean>; export function registerApp(
appId: string,
universalLink?: string
): Promise<boolean>;
export function openCustomerServiceChat(
corpId: string,
kfUrl: string
): Promise<string>;
export function isWXAppInstalled(): Promise<boolean>; export function isWXAppInstalled(): Promise<boolean>;
export function isWXAppSupportApi(): Promise<boolean>; export function isWXAppSupportApi(): Promise<boolean>;
export function getApiVersion(): Promise<string>; export function getApiVersion(): Promise<string>;
@ -39,9 +46,30 @@ declare module 'react-native-wechat-lib' {
state?: string; state?: string;
returnKey?: string; returnKey?: string;
} }
export function sendAuthRequest(scope: string | string[], state?: string): Promise<AuthResponse>; export interface ScanLoginResp {
nickname?: string;
headimgurl?: string;
openid?: string;
unionid?: string;
errCode?: number;
errStr?: string;
}
export function sendAuthRequest(
scope: string | string[],
state?: string
): Promise<AuthResponse>;
export function authByScan(appId: string, appSecret: string, onQRGet: (qrcode: string)=>void): Promise<ScanLoginResp>;
export interface ShareMetadata { export interface ShareMetadata {
type: 'news' | 'text' | 'imageUrl' | 'imageFile' | 'imageResource' | 'video' | 'audio' | 'file'; type:
| 'news'
| 'text'
| 'imageUrl'
| 'imageFile'
| 'imageResource'
| 'video'
| 'audio'
| 'file';
thumbImage?: string; thumbImage?: string;
description?: string; description?: string;
webpageUrl?: string; webpageUrl?: string;
@ -109,31 +137,31 @@ declare module 'react-native-wechat-lib' {
} }
export function shareText( export function shareText(
message: ShareTextMetadata, message: ShareTextMetadata
): Promise<{ errCode?: number; errStr?: string }>; ): Promise<{ errCode?: number; errStr?: string }>;
export function shareImage( export function shareImage(
message: ShareImageMetadata, message: ShareImageMetadata
): Promise<{ errCode?: number; errStr?: string }>; ): Promise<{ errCode?: number; errStr?: string }>;
export function shareLocalImage( export function shareLocalImage(
message: ShareImageMetadata, message: ShareImageMetadata
): Promise<{ errCode?: number; errStr?: string }>; ): Promise<{ errCode?: number; errStr?: string }>;
export function shareMusic( export function shareMusic(
message: ShareMusicMetadata, message: ShareMusicMetadata
): Promise<{ errCode?: number; errStr?: string }>; ): Promise<{ errCode?: number; errStr?: string }>;
export function shareVideo( export function shareVideo(
message: ShareVideoMetadata, message: ShareVideoMetadata
): Promise<{ errCode?: number; errStr?: string }>; ): Promise<{ errCode?: number; errStr?: string }>;
export function shareWebpage( export function shareWebpage(
message: ShareWebpageMetadata, message: ShareWebpageMetadata
): Promise<{ errCode?: number; errStr?: string }>; ): Promise<{ errCode?: number; errStr?: string }>;
export function shareMiniProgram( export function shareMiniProgram(
message: ShareMiniProgramMetadata, message: ShareMiniProgramMetadata
): Promise<{ errCode?: number; errStr?: string }>; ): Promise<{ errCode?: number; errStr?: string }>;
export function launchMiniProgram( export function launchMiniProgram(
message: LaunchMiniProgramMetadata, message: LaunchMiniProgramMetadata
): Promise<{ errCode?: number; errStr?: string }>; ): Promise<{ errCode?: number; errStr?: string }>;
export function subscribeMessage( export function subscribeMessage(
message: SubscribeMessageMetadata, message: SubscribeMessageMetadata
): Promise<{ errCode?: number; errStr?: string }>; ): Promise<{ errCode?: number; errStr?: string }>;
export interface PaymentLoad { export interface PaymentLoad {
partnerId: string; partnerId: string;
@ -143,7 +171,9 @@ declare module 'react-native-wechat-lib' {
package: string; package: string;
sign: string; sign: string;
} }
export function pay(payload: PaymentLoad): Promise<{ errCode?: number; errStr?: string }>; export function pay(
payload: PaymentLoad
): Promise<{ errCode?: number; errStr?: string }>;
export interface ChooseInvoice { export interface ChooseInvoice {
signType?: string; signType?: string;
@ -159,7 +189,7 @@ declare module 'react-native-wechat-lib' {
} }
export function chooseInvoice( export function chooseInvoice(
data: ChooseInvoice, data: ChooseInvoice
): Promise<{ errCode?: number; errStr?: string; cards: Invoice[] }>; ): Promise<{ errCode?: number; errStr?: string; cards: Invoice[] }>;
export interface ShareFileMetadata { export interface ShareFileMetadata {
@ -169,6 +199,6 @@ declare module 'react-native-wechat-lib' {
scene?: WXScene; scene?: WXScene;
} }
export function shareFile( export function shareFile(
data: ShareFileMetadata, data: ShareFileMetadata
): Promise<{ errCode?: number; errStr?: string }>; ): Promise<{ errCode?: number; errStr?: string }>;
} }

View File

@ -1,7 +1,8 @@
'use strict'; 'use strict';
import { DeviceEventEmitter, NativeModules, Platform } from 'react-native';
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import { sha1 } from 'js-sha1';
import { DeviceEventEmitter, NativeEventEmitter, NativeModules, Platform } from 'react-native';
let isAppRegistered = false; let isAppRegistered = false;
let { WeChat, WechatLib } = NativeModules; let { WeChat, WechatLib } = NativeModules;
@ -146,13 +147,19 @@ export const getApiVersion = wrapApi(WeChat.getApiVersion);
* @return {Promise} * @return {Promise}
*/ */
export const openWXApp = wrapApi(WeChat.openWXApp); export const openWXApp = wrapApi(WeChat.openWXApp);
/**
* Open wechat app
* @method openCustomerServiceChat
* @return {Promise}
*/
export const openCustomerServiceChat = wrapApi(WeChat.openCustomerServiceChat);
// wrap the APIs // wrap the APIs
const nativeShareToTimeline = wrapApi(WeChat.shareToTimeline); // const nativeShareToTimeline = wrapApi(WeChat.shareToTimeline);
const nativeLaunchMiniProgram = wrapApi(WeChat.launchMiniProgram); const nativeLaunchMiniProgram = wrapApi(WeChat.launchMiniProgram);
const nativeShareToSession = wrapApi(WeChat.shareToSession); // const nativeShareToSession = wrapApi(WeChat.shareToSession);
const nativeShareToFavorite = wrapApi(WeChat.shareToFavorite); const nativeShareToFavorite = wrapApi(WeChat.shareToFavorite);
const nativeSendAuthRequest = wrapApi(WeChat.sendAuthRequest); // const nativeSendAuthRequest = wrapApi(WeChat.sendAuthRequest);
const nativeShareText = wrapApi(WeChat.shareText); const nativeShareText = wrapApi(WeChat.shareText);
const nativeShareImage = wrapApi(WeChat.shareImage); const nativeShareImage = wrapApi(WeChat.shareImage);
const nativeShareLocalImage = wrapApi(WeChat.shareLocalImage); const nativeShareLocalImage = wrapApi(WeChat.shareLocalImage);
@ -164,6 +171,152 @@ const nativeSubscribeMessage = wrapApi(WeChat.subscribeMessage);
const nativeChooseInvoice = wrapApi(WeChat.chooseInvoice); const nativeChooseInvoice = wrapApi(WeChat.chooseInvoice);
const nativeShareFile = wrapApi(WeChat.shareFile); const nativeShareFile = wrapApi(WeChat.shareFile);
const nativeScan = wrapApi(WeChat.authByScan);
// https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
const getAccessToken = async (WeiXinId, WeiXinSecret) => {
let url =
'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' +
WeiXinId +
'&secret=' +
WeiXinSecret;
const response = await fetch(url);
const res = await response.json();
return res.access_token;
};
const getSDKTicket = async (accessToken) => {
let url =
'https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=2&access_token=' +
accessToken;
const response = await fetch(url);
const res = await response.json();
return res.ticket;
};
const createSignature = (
WeiXinId,
nonceStr,
sdkTicket,
timestamp
) => {
const origin =
'appid=' +
WeiXinId +
'&noncestr=' +
nonceStr +
'&sdk_ticket=' +
sdkTicket +
'&timestamp=' +
timestamp;
const ret = sha1(origin);
// console.log('wx scan signature', origin, ret);
return ret;
};
const getUserInfo = (
WeiXinId,
WeiXinSecret,
code,
callback
) => {
let accessTokenUrl =
'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' +
WeiXinId +
'&secret=' +
WeiXinSecret +
'&code=' +
code +
'&grant_type=authorization_code';
fetch(accessTokenUrl)
.then((res) => {
return res.json();
})
.then((res) => {
// console.log('wechat get access code success: ', res.access_token);
let userInfoUrl =
'https://api.weixin.qq.com/sns/userinfo?access_token=' +
res.access_token +
'&openid=' +
res.openid;
fetch(userInfoUrl)
.then((res2) => {
return res2.json();
})
.then((json) => {
// console.log('wechat get user info success: ', json);
callback({
nickname: json.nickname,
headimgurl: json.headimgurl,
openid: json.openid,
unionid: json.unionid,
});
})
.catch((e) => {
console.warn('wechat get user info fail ', e);
callback({ error: e });
});
})
.catch((e) => {
console.warn('wechat get access code fail ', e);
callback({ error: e });
});
};
const generateObjectId = () => {
var timestamp = ((new Date().getTime() / 1000) | 0).toString(16); // eslint-disable-line no-bitwise
return (
timestamp +
'xxxxxxxxxxxxxxxx'.replace(/[x]/g, function () {
return ((Math.random() * 16) | 0).toString(16).toLowerCase(); // eslint-disable-line no-bitwise
})
);
}
/**
* @method authByScan
* @param {String} appId - the app id
* @param {String} appSecret - the app secret
* @param {Function} onQRGet - (qrcode: string) => void
* @return {Promise}
*/
export function authByScan(appId, appSecret, onQRGet) {
return new Promise(async (resolve, reject) => {
const accessToken = await getAccessToken(appId, appSecret);
const ticket = await getSDKTicket(accessToken);
const nonceStr = generateObjectId();
const timestamp = String(Math.round(Date.now() / 1000));
const signature = createSignature(appId, nonceStr, ticket, timestamp);
const qrcodeEmitter = new NativeEventEmitter(NativeModules.WeChat);
const subscription = qrcodeEmitter.addListener('onAuthGotQrcode', (res) =>
onQRGet && onQRGet(res.qrcode)
);
const ret = await nativeScan(appId, nonceStr, timestamp, 'snsapi_userinfo', signature, '');
// console.log('扫码结果', ret)
subscription.remove();
if (!ret?.authCode) {
reject(new WechatError({
errStr: 'Auth code 获取失败',
errCode: -1
}))
return;
}
getUserInfo(appId, appSecret, ret?.authCode, (result) => {
// console.log('扫码登录结果', result)
if (!result.error) {
resolve(result)
} else {
reject(new WechatError({
errStr: '扫码登录失败' + JSON.stringify(e),
errCode: -2
}))
}
});
});
}
/** /**
* @method sendAuthRequest * @method sendAuthRequest
@ -218,8 +371,8 @@ export function chooseInvoice(data = {}) {
const cardItemList = JSON.parse(resp.cardItemList); const cardItemList = JSON.parse(resp.cardItemList);
resp.cards = cardItemList resp.cards = cardItemList
? cardItemList.map((item) => ({ ? cardItemList.map((item) => ({
cardId: item.card_id, cardId: item.card_id,
encryptCode: item.encrypt_code, encryptCode: item.encrypt_code,
})) }))
: []; : [];
} }
@ -385,14 +538,22 @@ export function shareMiniProgram(data) {
* @param {Integer} miniProgramType - 拉起小程序的类型. 0-正式版 1-开发版 2-体验版 * @param {Integer} miniProgramType - 拉起小程序的类型. 0-正式版 1-开发版 2-体验版
* @param {String} path - 拉起小程序页面的可带参路径不填默认拉起小程序首页 * @param {String} path - 拉起小程序页面的可带参路径不填默认拉起小程序首页
*/ */
export function launchMiniProgram({ userName, miniProgramType = 0, path = '' }) { export function launchMiniProgram({
userName,
miniProgramType = 0,
path = '',
}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (miniProgramType !== 0 && miniProgramType !== 1 && miniProgramType !== 2) { if (
miniProgramType !== 0 &&
miniProgramType !== 1 &&
miniProgramType !== 2
) {
reject( reject(
new WechatError({ new WechatError({
errStr: '拉起小程序的类型不对0-正式版 1-开发版 2-体验版', errStr: '拉起小程序的类型不对0-正式版 1-开发版 2-体验版',
errCode: -1, errCode: -1,
}), })
); );
return; return;
} }

View File

@ -7,7 +7,7 @@
"allowUnreachableCode": false, "allowUnreachableCode": false,
"allowUnusedLabels": false, "allowUnusedLabels": false,
"esModuleInterop": true, "esModuleInterop": true,
"importsNotUsedAsValues": "error", "verbatimModuleSyntax": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"jsx": "react", "jsx": "react",
"lib": ["esnext"], "lib": ["esnext"],