Merge pull request #282 from Norcy/feat/scan

双端实现分享本地文件到微信
This commit is contained in:
snowfox 2024-08-08 14:52:57 +08:00 committed by GitHub
commit 7e90d9d7d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 234 additions and 200 deletions

View File

@ -226,7 +226,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 +237,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

@ -255,6 +255,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://"开头的用于共享的路径
}
/** /**
* 分享文本 * 分享文本
@ -265,7 +280,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;

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,10 +1,10 @@
// 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>
@implementation WechatLib @implementation WechatLib
@ -16,8 +16,7 @@
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];
@ -25,26 +24,22 @@ RCT_EXPORT_MODULE()
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 +48,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 +84,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 +99,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 +114,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 +164,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 +177,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 +192,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 +208,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 +224,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 +234,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 +243,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 +266,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 +275,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 +298,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 +309,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 +318,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 +341,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 +352,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 +361,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 +377,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 +393,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 +405,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 +431,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 +447,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 +457,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 +466,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 +487,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 +514,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 +524,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;
}; };
@ -569,85 +545,81 @@ RCT_EXPORT_METHOD(pay:(NSDictionary *)data
} }
// 跳转微信客服 // 跳转微信客服
RCT_EXPORT_METHOD(openCustomerServiceChat:(NSString *)corpId RCT_EXPORT_METHOD(openCustomerServiceChat
:(NSString *)corpId
:(NSString *)kfUrl :(NSString *)kfUrl
:(RCTResponseSenderBlock)callback) :(RCTResponseSenderBlock)callback) {
{
WXOpenCustomerServiceReq *req = [[WXOpenCustomerServiceReq alloc] init]; WXOpenCustomerServiceReq *req = [[WXOpenCustomerServiceReq alloc] init];
req.corpid = corpId; //企业ID req.corpid = corpId; // 企业 ID
req.url = kfUrl; //客服URL req.url = kfUrl; // 客服 URL
[WXApi sendReq:req completion:nil]; [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;
@ -656,7 +628,7 @@ RCT_EXPORT_METHOD(openCustomerServiceChat:(NSString *)corpId
} }
} }
-(WXMiniProgramType) integerToWXMiniProgramType:(int)value { - (WXMiniProgramType)integerToWXMiniProgramType:(int)value {
WXMiniProgramType type = WXMiniProgramTypeRelease; WXMiniProgramType type = WXMiniProgramTypeRelease;
switch (value) { switch (value) {
case 0: case 0:
@ -673,4 +645,3 @@ RCT_EXPORT_METHOD(openCustomerServiceChat:(NSString *)corpId
} }
@end @end