This commit is contained in:
dongdayu
2018-05-02 19:00:53 +08:00
parent 2e43d78802
commit 5fc8672795
49 changed files with 2118 additions and 1701 deletions

8
.gitignore vendored
View File

@@ -1,4 +1,3 @@
# OSX
#
.DS_Store
@@ -8,7 +7,7 @@
node_modules/
npm-debug.log
yarn-error.log
# Xcode
#
@@ -29,7 +28,7 @@ DerivedData
*.ipa
*.xcuserstate
project.xcworkspace
# Android/IntelliJ
#
@@ -43,4 +42,5 @@ local.properties
buck-out/
\.buckd/
*.keystore
yarn.lock

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) present, Dayu Dong.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

382
README.md
View File

@@ -1 +1,383 @@
# react-native-wechat
## 安装
```bash
yarn add @yyyyu/react-native-wechat
```
or
```bash
npm install --save @yyyyu/react-native-wechat
```
## 配置
### ios
#### 1. 自动配置(推荐)
```bash
react-native link @yyyyu/react-native-wechat
```
如果项目**使用 Pods 管理依赖**需要在 Podfile 中添加
```ruby
pod 'React', :path => '../node_modules/react-native', :subspecs => ['Dependency']
```
#### 2. 手动配置
1. 使用 Xcode 打开项目,在项目依赖目录(Libraries)下添加 node_modules 中的 @yyyyu/react-native-wechat 项目
2. 在 Linked Frameworks and Libraries 添加 libRNWechat.a
#### 额外配置 [微信官方文档参考](https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&id=1417694084&lang=zh_CN)
1. **手动配置**需要在 Linked Frameworks and Libraries 添加 libsqlite3.0
2. 在 AppDelegate.m 文件中添加下列代码
```objective-c
#import <React/RCTLinkingManager.h>
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [RCTLinkingManager application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
}
```
3. 在 Info.plist 文件中添加 URL Schemes
- identifier -> weixin
- URL Schemes -> **你的 appId**
4. ​在 Info.plist 文件添加 LSApplicationQueriesSchemes 字段,值类型为 Array添加字符串子元素 weixin
### android
#### 1. 自动配置(如果 IOS 已经运行过,不需要重复运行)
```bash
react-native link @yyyyu/react-native-wechat
```
#### 2. 手动配置
1. 在 android/settings.gradle 文件中添加
```Groovy
include ':react-native-wechat'
project(':react-native-wechat').projectDir = new File(rootProject.projectDir, '../node_modules/@yyyyu/react-native-wechat/android')
```
2. 在 android/app/build.gradle 文件中依赖部分添加
```Groovy
dependencies {
// other dependencies
compile project(':react-native-wechat')
}
```
3. 在 MainApplication.java 文件中添加
```Java
import com.rnlib.wechat.RNWechatPackage;
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
// other packages
new RNWechatPackage()
);
}
```
#### 额外配置 [微信官方文档参考](https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&id=1417751808&lang=zh_CN)
1. 在 MainActivity.java 文件中添加下列代码,标识出当前状态,在微信唤起应用时需要做不同处理
```java
public class MainActivity extends ReactActivity {
public static boolean isActivityCreated;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
isActivityCreated = true;
}
@Override
protected void onDestroy() {
super.onDestroy();
isActivityCreated = false;
}
}
```
2. 在应用包名下创建 wxapi 这个包,并新建 WXEntryActivity 类(这里要严格按照这种形式创建,否则无法接收到微信的应答)
```java
package 包名.wxapi;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import com.rnlib.wechat.RNWechatModule;
import 包名.MainActivity;
public class WXEntryActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (MainActivity.isActivityCreated) {
RNWechatModule.handleIntent(this.getIntent());
} else {
// 如果应用未在后台启动,就打开应用
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
finish();
}
}
```
3. 如果需要使用微信支付功能,在 wxapi 这个包下新建 WXPayEntryActivity 类(注意此处类名和上面不同)
```java
package 包名.wxapi;
import android.app.Activity;
import android.os.Bundle;
import com.rnlib.wechat.RNWechatModule;
public class WXPayEntryActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RNWechatModule.handleIntent(this.getIntent());
finish();
}
}
```
4. 在 AndroidManifest.xml 中注册上述 activity
```xml
<application>
<activity
android:name=".wxapi.WXEntryActivity"
android:label="@string/app_name"
android:exported="true" />
<!-- 微信支付可选 -->
<activity
android:name=".wxapi.WXPayEntryActivity"
android:label="@string/app_name"
android:exported="true" />
</application>
```
5. **一定要签名才能正常调用接口**,注意签名 MD5 和微信平台登记一致,调试也需要签名(微信上好像说 debug 版本可以用 debug.keystore 调试,我没有试过)
## JS API
```javascript
import wechat from '@yyyyu/react-native-wechat'
wechat.registerApp({ appId: 'appId' })
.then(res => { console.log(res) })
.catch(err => { console.error(err) })
```
### 参数说明
1. 参数注释带有 optional 字样为可选参数括号内为默认值e.g. optional('default')
2. iosOnly androidOnly 表示只有在相应平台才会生效
3. 发送场景类型有 session (会话、聊天) timeline (朋友圈) favorite (收藏),默认 session
4. 小程序类型有 test (测试版) preview (体验版) release (正式版),默认 test
5. 图片、缩略图,可以使用原生的 path 或 uri (第三方库 [react-native-camera](https://github.com/react-native-community/react-native-camera)、[react-native-image-picker](https://github.com/react-community/react-native-image-picker) 返回值),也可以使用 react native 的 require('image.png'),还可以使用 base64(安卓未测试)
### 返回值说明
1. 错误代码
```javascript
import { ErrCode } from '@yyyyu/react-native-wechat'
console.log(ErrCode)
{
// 微信 sdk 返回错误类型
Success: 0, // 成功
Common: -1, // 普通错误
UserCancel: -2, // 点击取消返回
SentFail: -3, // 发送失败
AuthDeny: -4, // 授权失败
Unsupport: -5, // 不支持
Ban: -6, // 禁止 androidOnly
// 自定义错误类型
ActiveSuccess: 1, // 发送请求后通过系统唤起(任务列表选择唤起),无法判断成功失败
RequestFailed: -7, // 请求失败
UnRegisteApi: -8, // 未注册接口
UnInstall: -9, // 未安装微信
UnSupportApi: -10, // 不支持 Api
Unknow: -99 // 未知错误
}
```
2. 抛出错误处理方式
```javascript
import { WechatError } from '@yyyyu/react-native-wechat'
try {
const res = await wechat.sendText({ text: 'example' })
console.log(res)
} catch (e) {
if (e instanceof WechatError) {
const { errCode, errMsg } = e
console.error(errCode, errMsg)
}
}
```
#### registerApp 注册微信 api
```javascript
// @return Boolean
wechat.registerApp({
appId: 'you app id', // 微信平台注册应用后得到的 appId
isDebug: false, // optional(false)
})
```
#### isWXAppInstalled 检测是否安装微信
```javascript
// @return Boolean
wechat.isWXAppInstalled()
```
#### isWXAppSupportApi 检测当前版本微信是否支持 Api
```javascript
// @return Boolean
wechat.isWXAppSupportApi()
```
#### getWXAppInstallUrl 获取微信 iTunes 的安装地址 iosOnly
```javascript
// @return String
wechat.getWXAppInstallUrl()
```
#### openWXApp 打开微信(需要先注册 api 才可以调用)
```javascript
wechat.openWXApp()
```
#### sendAuthRequest OAuth2 微信登录
```javascript
wechat.sendAuthRequest({
state: 'state' // 返回值会包含相同的数据用于验证请求 optional('')
})
```
#### sendText 发送文字
安卓版本分享到会话无法使用,不知道是不是我自己的问题
```javascript
wechat.sendText({
text: 'text', // 用于发送的文字
scene: 'session' // 发送场景 optional('session')
})
```
#### sendImage 发送图片
```javascript
wechat.sendImage({
image: require('path/image.png'), // 用于发送的图片
scene: 'session' // 发送场景 optional('session')
})
```
#### sendMusic 发送音乐
```javascript
wechat.sendMusic({
music: 'https://music.com/music.html', // 音乐地址
data: 'https://music.com/data', // 音乐数据地址
title: 'title', // 标题
desc: 'description', // 描述
thumb: require('path/thumb.png'), // 缩略图
scene: 'session' // 发送场景 optional('session')
})
```
#### sendVideo 发送视频
```javascript
wechat.sendVideo({
video: 'https://video.com/video', // 视频地址
title: 'title', // 标题
desc: 'description', // 描述
thumb: require('path/thumb.png'), // 缩略图
scene: 'session' // 发送场景 optional('session')
})
```
#### sendLink 发送链接
```javascript
wechat.sendLink({
link: 'https://link.com/', // 链接地址
title: 'title', // 标题
desc: 'description', // 描述
thumb: require('path/thumb.png'), // 缩略图
scene: 'session' // 发送场景 optional('session')
})
```
#### sendMiniProgram 发送小程序
```javascript
wechat.sendMiniProgram({
username: 'you username', // 原始 id微信开放平台注册小程序处获取
path: '/path1/path2', // 小程序路由地址
title: 'title', // 标题
desc: 'description', // 描述
hdThumb: require('path/thumb.png'), // 缩略图
link: 'https://www.link.com/', // 兼容旧版本链接,不支持小程序的微信版本会以此方式打开
thumb: require('path/thumb.png'), // 兼容旧版本缩略图,不支持小程序的微信版本会看到此缩略图
type: 'test' // 分享小程序类型 optional('release')
})
```
#### pay 支付(没有账号,未测试)
```javascript
wechat.pay({
appId: 'you appId', // appId androidOnly 安卓 sdk 就是这样
partnerId: 'you partnerId', // 商家 id
prepayId: 'you prepayId', // 预支付订单 id
nonceStr: 'nonceStr', // 随机串
timestamp: 'timestamp', // 时间戳
packageSign: 'you packageSign', // 财付通签名
sign: 'you sign', // 微信开放平台签名
})
```

21
RNWechat.podspec Normal file
View File

@@ -0,0 +1,21 @@
require "json"
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
Pod::Spec.new do |s|
s.name = "RNWechat"
s.version = package["version"]
s.summary = "react native wechat"
s.description = package["description"]
s.license = package["license"]
s.author = { package["author"] => "g592842897@gmail.com" }
s.homepage = package["homepage"]
s.source = { :git => package["repository"]["url"], :tag => package["version"] }
s.requires_arc = true
s.platform = :ios, "8.0"
s.source_files = "ios/**/*.{h,m}"
s.exclude_files = "ios/SDK/*"
s.dependency "WechatOpenSDK"
end

View File

@@ -1,4 +1,3 @@
buildscript {
repositories {
jcenter()

View File

@@ -1,5 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ytanglib.wechat">
package="com.rnlib.wechat">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

View File

@@ -0,0 +1,376 @@
package com.rnlib.wechat;
import android.content.Intent;
import android.graphics.Bitmap;
import android.util.Log;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.rnlib.wechat.helper.ActivityHelper;
import com.rnlib.wechat.helper.FormatConversion;
import com.rnlib.wechat.helper.SendMessageToWXHelper;
import com.rnlib.wechat.helper.WXMediaMessageHelper;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.WXImageObject;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
import com.tencent.mm.opensdk.modelmsg.WXMiniProgramObject;
import com.tencent.mm.opensdk.modelmsg.WXMusicObject;
import com.tencent.mm.opensdk.modelmsg.WXTextObject;
import com.tencent.mm.opensdk.modelmsg.WXVideoObject;
import com.tencent.mm.opensdk.modelmsg.WXWebpageObject;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.modelpay.PayResp;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.tencent.mm.opensdk.utils.ILog;
public class RNWechatModule extends ReactContextBaseJavaModule {
private static ReactApplicationContext mReactContext;
private static final String TAG = "RNWechat";
private static final String RNWechatEventName = "RNWechatEvent";
private static IWXAPI api;
private boolean isWXApiRegisteSuccess = false;
public RNWechatModule(ReactApplicationContext reactContext) {
super(reactContext);
mReactContext = reactContext;
}
@Override
public String getName() {
return "RNWechat";
}
/**
* 注册 api
*/
@ReactMethod
public void registerApp(String appId, Boolean isDebug, Promise promise) {
if (!appId.isEmpty()) {
api = WXAPIFactory.createWXAPI(mReactContext, appId, true);
if (isDebug) {
api.setLogImpl(new ILog() {
@Override
public void v(String s, String s1) {
Log.d(TAG, s1);
}
@Override
public void d(String s, String s1) {
Log.d(TAG, s1);
}
@Override
public void i(String s, String s1) {
Log.i(TAG, s1);
}
@Override
public void w(String s, String s1) {
Log.w(TAG, s1, null);
}
@Override
public void e(String s, String s1) {
Log.e(TAG, s1, null);
}
});
}
isWXApiRegisteSuccess = api.registerApp(appId);
if (isWXApiRegisteSuccess) {
Log.d(TAG, "WXApi register success. appId: " + appId);
} else {
Log.d(TAG, "WXApi register failed. appId: " + appId);
}
} else {
Log.d(TAG, "There is no appId for WXApi.");
}
promise.resolve(isWXApiRegisteSuccess);
}
/**
* api 注册是否成功
*/
@ReactMethod
public void isWXApiRegisteSuccess(Promise promise) {
promise.resolve(isWXApiRegisteSuccess);
}
/**
* 微信是否安装
*/
@ReactMethod
public void isWXAppInstalled(Promise promise) {
promise.resolve(api.isWXAppInstalled());
}
/**
* 安装版本微信是否支持 api
*/
@ReactMethod
public void isWXAppSupportApi(Promise promise) {
promise.resolve(api.isWXAppSupportAPI());
}
/**
* 打开微信
*/
@ReactMethod
public void openWXApp(Promise promise) {
promise.resolve(api.openWXApp());
}
/**
* OAuth2
*/
@ReactMethod
public void sendAuthRequest(
String scope,
String state,
Promise promise) {
final SendAuth.Req req = new SendAuth.Req();
req.scope = scope;
req.state = state;
promise.resolve(api.sendReq(req));
}
/**
* 发送文字
*/
@ReactMethod
public void sendText(
String text,
Integer sceneType,
Promise promise) {
WXTextObject textObject = new WXTextObject(text);
WXMediaMessage mediaMessage = WXMediaMessageHelper.getInstance(null, null, null, textObject);
SendMessageToWX.Req req = SendMessageToWXHelper.getInstance(mediaMessage, sceneType);
promise.resolve(api.sendReq(req));
}
/**
* 发送图片
*/
@ReactMethod
public void sendImage(
String imageString,
Integer sceneType,
Promise promise) {
WXImageObject imageObject = new WXImageObject(FormatConversion.stringToBitmap(imageString));
WXMediaMessage mediaMessage = WXMediaMessageHelper.getInstance(null, null, null, imageObject);
SendMessageToWX.Req req = SendMessageToWXHelper.getInstance(mediaMessage, sceneType);
promise.resolve(api.sendReq(req));
}
/**
* 发送音乐
*/
@ReactMethod
public void sendMusic(
String musicUrl,
String musicDataUrl,
String title,
String description,
String thumbString,
Integer sceneType,
Promise promise) {
WXMusicObject musicObject = new WXMusicObject();
musicObject.musicUrl = musicUrl;
musicObject.musicDataUrl = musicDataUrl;
Bitmap thumb = FormatConversion.stringToBitmapWithScale(thumbString, 100, 100);
WXMediaMessage mediaMessage = WXMediaMessageHelper.getInstance(
title, description, FormatConversion.bitmapToByteArray(thumb), musicObject);
SendMessageToWX.Req req = SendMessageToWXHelper.getInstance(mediaMessage, sceneType);
promise.resolve(api.sendReq(req));
}
/**
* 发送视频
*/
@ReactMethod
public void sendVideo(
String videoUrl,
String title,
String description,
String thumbString,
Integer sceneType,
Promise promise) {
WXVideoObject videoObject = new WXVideoObject();
videoObject.videoUrl = videoUrl;
Bitmap thumb = FormatConversion.stringToBitmapWithScale(thumbString, 100, 100);
WXMediaMessage mediaMessage = WXMediaMessageHelper.getInstance(
title, description, FormatConversion.bitmapToByteArray(thumb), videoObject);
SendMessageToWX.Req req = SendMessageToWXHelper.getInstance(mediaMessage, sceneType);
promise.resolve(api.sendReq(req));
}
/**
* 发送链接
*/
@ReactMethod
public void sendLink(
String linkString,
String title,
String description,
String thumbString,
Integer sceneType,
Promise promise) {
WXWebpageObject webpageObj = new WXWebpageObject(linkString);
Bitmap thumb = FormatConversion.stringToBitmapWithScale(thumbString, 100, 100);
WXMediaMessage mediaMessage = WXMediaMessageHelper.getInstance(
title, description, FormatConversion.bitmapToByteArray(thumb), webpageObj);
SendMessageToWX.Req req = SendMessageToWXHelper.getInstance(mediaMessage, sceneType);
promise.resolve(api.sendReq(req));
}
/**
* 发送小程序
*/
@ReactMethod
public void sendMiniProgram(
String userName,
Integer miniprogramType,
String path,
String hdThumbString,
String title,
String description,
String webpageUrl,
String thumbString,
Promise promise) {
WXMiniProgramObject miniprogramObject = new WXMiniProgramObject();
miniprogramObject.userName = userName;
miniprogramObject.miniprogramType = miniprogramType;
miniprogramObject.path = path;
miniprogramObject.webpageUrl = webpageUrl;
miniprogramObject.withShareTicket = true;
String realThumbString = hdThumbString.isEmpty() ? thumbString : hdThumbString;
Bitmap realThumb = FormatConversion.stringToBitmapWithScale(realThumbString, 500, 400);
WXMediaMessage mediaMessage = WXMediaMessageHelper.getInstance(
title, description, FormatConversion.bitmapToByteArray(realThumb), miniprogramObject);
SendMessageToWX.Req req = SendMessageToWXHelper.getInstance(mediaMessage, SendMessageToWX.Req.WXSceneSession);
promise.resolve(api.sendReq(req));
}
/**
* 支付
*/
@ReactMethod
public void pay(
String appId,
String partnerId,
String prepayId,
String nonceStr,
Integer timeStamp,
String packageValue,
String sign,
Promise promise) {
PayReq req = new PayReq();
req.appId = appId;
req.partnerId = partnerId;
req.prepayId = prepayId;
req.nonceStr = nonceStr;
req.timeStamp = timeStamp.toString();
req.packageValue = packageValue;
req.sign = sign;
promise.resolve(api.sendReq(req));
}
public static void handleIntent(Intent intent) {
api.handleIntent(intent, new IWXAPIEventHandler() {
@Override
public void onReq(BaseReq baseReq) {
// TODO: 2018/5/2 微信小程序唤醒 App 参数传递
// if (baseReq instanceof ShowMessageFromWX.Req) {
// ShowMessageFromWX.Req req = (ShowMessageFromWX.Req) baseReq;
// WritableMap reqBody = Arguments.createMap();
// reqBody.putString("messageExt", req.message.messageExt);
// }
try {
ActivityHelper.moveTop(mReactContext);
} catch (NullPointerException ignored) {
}
}
@Override
public void onResp(BaseResp baseResp) {
WritableMap body = Arguments.createMap();
body.putInt("errCode", baseResp.errCode);
body.putString("errStr", FormatConversion.getNonNullString(baseResp.errStr));
if (baseResp instanceof SendMessageToWX.Resp) {
// 分享
body.putString("eventType", "SendMessageToWXResp");
} else if (baseResp instanceof SendAuth.Resp) {
// OAuth2
SendAuth.Resp resp = (SendAuth.Resp) baseResp;
body.putString("eventType", "SendAuthResp");
body.putString("code", FormatConversion.getNonNullString(resp.code));
body.putString("state", FormatConversion.getNonNullString(resp.state));
body.putString("url", FormatConversion.getNonNullString(resp.url));
body.putString("lang", FormatConversion.getNonNullString(resp.lang));
body.putString("country", FormatConversion.getNonNullString(resp.country));
} else if (baseResp instanceof PayResp) {
// 支付
PayResp resp = (PayResp) baseResp;
body.putString("eventType", "PayResp");
body.putString("prepayId", FormatConversion.getNonNullString(resp.prepayId));
body.putString("returnKey", FormatConversion.getNonNullString(resp.returnKey));
}
RNWechatModule.sendEvent(body);
}
});
}
private static void sendEvent(WritableMap mBody) {
mReactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(RNWechatEventName, mBody);
}
}

View File

@@ -1,4 +1,4 @@
package com.ytanglib.wechat;
package com.rnlib.wechat;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;

View File

@@ -0,0 +1,16 @@
package com.rnlib.wechat.helper;
import android.app.ActivityManager;
import android.content.Context;
import com.facebook.react.bridge.ReactApplicationContext;
public class ActivityHelper {
public static void moveTop(ReactApplicationContext context) throws NullPointerException {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
activityManager.moveTaskToFront(
context.getCurrentActivity().getTaskId(),
ActivityManager.MOVE_TASK_NO_USER_ACTION);
}
}

View File

@@ -0,0 +1,77 @@
package com.rnlib.wechat.helper;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public final class FormatConversion {
public static String getNonNullString(Object obj) {
return obj instanceof String ? obj.toString() : "";
}
public static Bitmap stringToBitmap(String string) {
return stringToBitmapWithScale(string, 0, 0);
}
public static Bitmap stringToBitmapWithScale(String string, int width, int height) {
Bitmap result = null;
if (isPath(string)) {
result = BitmapFactory.decodeFile(string);
} else {
try {
URL url = new URL(string);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setConnectTimeout(3000);
conn.connect();
InputStream stream = conn.getInputStream();
result = BitmapFactory.decodeStream(stream);
conn.disconnect();
} catch (Exception ignored) {
}
}
return resizeBitmap(result, width, height);
}
public static byte[] bitmapToByteArray(Bitmap bitmap) {
if (bitmap == null) {
return null;
}
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
try {
stream.close();
} catch (IOException ignore) {
}
return stream.toByteArray();
}
private static boolean isPath(String string) {
return string.startsWith("/") || string.startsWith("file:/");
}
private static Bitmap resizeBitmap(Bitmap bitmap, int newWidth, int newHeight) {
if (bitmap == null) {
return null;
}
if (newWidth <= 0 || newHeight <= 0) {
return bitmap;
}
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false);
}
}

View File

@@ -0,0 +1,15 @@
package com.rnlib.wechat.helper;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
public class SendMessageToWXHelper {
public static SendMessageToWX.Req getInstance(WXMediaMessage message, int scene) {
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.message = message;
req.scene = scene;
return req;
}
}

View File

@@ -0,0 +1,18 @@
package com.rnlib.wechat.helper;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
public class WXMediaMessageHelper {
public static WXMediaMessage getInstance(String title,
String description,
byte[] thumbData,
WXMediaMessage.IMediaObject mediaObject) {
WXMediaMessage mediaMessage = new WXMediaMessage(mediaObject);
mediaMessage.title = title;
mediaMessage.description = description;
mediaMessage.thumbData = thumbData;
return mediaMessage;
}
}

View File

@@ -1,206 +0,0 @@
package com.ytanglib.wechat;
import android.content.Intent;
import android.util.Log;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.ShowMessageFromWX;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
import com.tencent.mm.opensdk.modelmsg.WXMiniProgramObject;
import com.tencent.mm.opensdk.modelmsg.WXTextObject;
import com.tencent.mm.opensdk.modelmsg.WXWebpageObject;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
public class RNWechatModule extends ReactContextBaseJavaModule {
private static ReactApplicationContext mReactContext;
private static final String Tag = "RNWechat";
private static final String RNWechatEventName = "RNWechatEvent";
private static IWXAPI api;
private boolean isWXApiRegisteSuccess = false;
public RNWechatModule(ReactApplicationContext reactContext) {
super(reactContext);
mReactContext = reactContext;
}
@Override
public String getName() {
return "RNWechat";
}
@ReactMethod
public void registerApp(String appId, String isDebug, Promise promise) {
if (!appId.isEmpty()) {
api = WXAPIFactory.createWXAPI(mReactContext, appId, true);
isWXApiRegisteSuccess = api.registerApp(appId);
if (isWXApiRegisteSuccess) {
Log.i(Tag, "WXApi register success. appId: " + appId);
} else {
Log.i(Tag, "WXApi register failed. appId: " + appId);
}
} else {
Log.i(Tag, "There is no appId for WXApi.");
}
promise.resolve(getOperateResult(isWXApiRegisteSuccess));
}
@ReactMethod
public void isWXApiRegisteSuccess(Promise promise) {
promise.resolve(getOperateResult(isWXApiRegisteSuccess));
}
@ReactMethod
public void isWXAppInstalled(Promise promise) {
promise.resolve(getOperateResult(api.isWXAppInstalled()));
}
@ReactMethod
public void sendAuthRequestScope(
String scope,
String state,
String openId,
Promise promise) {
final SendAuth.Req req = new SendAuth.Req();
req.scope = scope;
req.state = state;
req.openId = openId;
boolean res = api.sendReq(req);
promise.resolve(getOperateResult(res));
}
@ReactMethod
public void sendText(
String text,
Integer sceneType,
Promise promise) {
WXTextObject textObject = new WXTextObject();
textObject.text = text;
WXMediaMessage mediaMessage = getMediaMessageWithData(null, null, null, textObject);
promise.resolve(getOperateResult(sendMessageRequest(mediaMessage, sceneType)));
}
@ReactMethod
public void sendLinkURL(
String urlString,
String title,
String description,
String thumbUrlString,
Integer sceneType,
Promise promise) {
WXWebpageObject webObj = new WXWebpageObject();
webObj.webpageUrl = urlString;
byte[] thumbByteArray = Utils.getByteArrayFromUrlStringWithScale(thumbUrlString, 100, 100);
WXMediaMessage mediaMessage = getMediaMessageWithData(title, description, thumbByteArray, webObj);
promise.resolve(getOperateResult(sendMessageRequest(mediaMessage, sceneType)));
}
@ReactMethod
public void sendMiniProgramWebpageUrl(
String webpageUrl,
String userName,
String path,
String title,
String description,
String thumbUrlString,
String hdImageUrlString,
Integer programType,
Promise promise) {
WXMiniProgramObject miniObj = new WXMiniProgramObject();
miniObj.webpageUrl = webpageUrl;
miniObj.userName = userName;
miniObj.path = path;
miniObj.miniprogramType = programType;
miniObj.withShareTicket = true;
String imageUrlString = hdImageUrlString.isEmpty() ? thumbUrlString : hdImageUrlString;
byte[] thumbByteArray = Utils.getByteArrayFromUrlStringWithScale(imageUrlString, 500, 400);
WXMediaMessage mediaMessage = getMediaMessageWithData(title, description, thumbByteArray, miniObj);
promise.resolve(getOperateResult(sendMessageRequest(mediaMessage, SendMessageToWX.Req.WXSceneSession)));
}
private String getOperateResult(boolean isOperateSucc) {
return isOperateSucc ? "true" : "false";
}
private WXMediaMessage getMediaMessageWithData(
String title,
String description,
byte[] thumbData,
WXMediaMessage.IMediaObject mediaObject) {
WXMediaMessage mediaMessage = new WXMediaMessage();
mediaMessage.title = title;
mediaMessage.description = description;
mediaMessage.thumbData = thumbData;
mediaMessage.mediaObject = mediaObject;
return mediaMessage;
}
private boolean sendMessageRequest(WXMediaMessage mediaMessage, Integer scene) {
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.message = mediaMessage;
req.scene = scene;
return api.sendReq(req);
}
public static void handleIntent(Intent intent) {
api.handleIntent(intent, new IWXAPIEventHandler() {
@Override
public void onReq(BaseReq baseReq) {
if (baseReq instanceof ShowMessageFromWX.Req) {
try {
Utils.moveCurrentActivityToTop(mReactContext);
} catch (NullPointerException ignored) {
}
}
}
@Override
public void onResp(BaseResp baseResp) {
WritableMap body = Arguments.createMap();
body.putInt("errCode", baseResp.errCode);
body.putString("errStr", Utils.checkNullableString(baseResp.errStr));
// body.putString("transaction", Utils.checkNullableString(baseResp.transaction));
// body.putString("openId", Utils.checkNullableString(baseResp.openId));
if (baseResp instanceof SendMessageToWX.Resp) {
SendMessageToWX.Resp resp = (SendMessageToWX.Resp) baseResp;
body.putString("eventType", "SendMessageToWXResp");
} else if (baseResp instanceof SendAuth.Resp) {
SendAuth.Resp resp = (SendAuth.Resp) baseResp;
body.putString("eventType", "SendAuthResp");
body.putString("code", Utils.checkNullableString(resp.code));
body.putString("state", Utils.checkNullableString(resp.state));
body.putString("url", Utils.checkNullableString(resp.url));
body.putString("lang", Utils.checkNullableString(resp.lang));
body.putString("country", Utils.checkNullableString(resp.country));
}
RNWechatModule.sendEvent(body);
}
});
}
private static void sendEvent(WritableMap mBody) {
mReactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(RNWechatEventName, mBody);
}
}

View File

@@ -1,77 +0,0 @@
package com.ytanglib.wechat;
import java.net.URL;
import java.net.HttpURLConnection;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import android.content.Context;
import android.app.ActivityManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import com.facebook.react.bridge.ReactApplicationContext;
/**
* Created by dayudong on 08/03/2018.
*/
public class Utils {
public static String checkNullableString(String str) {
return str != null ? str : "";
}
public static byte[] getByteArrayFromUrlStringWithScale(String urlString, int width, int height) {
Bitmap bitmap = getBitmapFromUrlString(urlString);
Bitmap resizeBitmap = getResizeBitmapFromBitmap(bitmap, width, height);
return transformBitmapToByteArray(resizeBitmap);
}
public static void moveCurrentActivityToTop(ReactApplicationContext context) throws NullPointerException {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
activityManager.moveTaskToFront(
context.getCurrentActivity().getTaskId(),
ActivityManager.MOVE_TASK_NO_USER_ACTION);
}
private static Bitmap getBitmapFromUrlString(String urlString) {
if (urlString.isEmpty()) {
return null;
}
Bitmap imageBitmap = null;
try {
URL imageUrl = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection();
conn.setDoInput(true);
conn.setConnectTimeout(5000);
conn.connect();
InputStream imageStream = conn.getInputStream();
imageBitmap = BitmapFactory.decodeStream(imageStream);
} catch (Exception ignored) {}
return imageBitmap;
}
private static Bitmap getResizeBitmapFromBitmap(Bitmap bitmap, int newWidth, int newHeight) {
if (bitmap == null) {
return null;
}
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false);
}
private static byte[] transformBitmapToByteArray(Bitmap bitmap) {
if (bitmap == null) {
return null;
}
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
return stream.toByteArray();
}
}

View File

@@ -1,4 +1,5 @@
import WXApi from './src/index'
import * as WXApi from './src'
export { WXErrCode } from './src/const'
export { ErrCode } from './src/const'
export { WechatError } from './src/index'
export default WXApi

View File

@@ -1,110 +1,49 @@
//
// WXApiManager.h
// SDKSample
//
// Created by Jeason on 15/7/14.
//
//
#import <Foundation/Foundation.h>
#import "WXApiObject.h"
@interface WXApiRequestHandler : NSObject
+ (BOOL)sendAuthRequestScope:(NSString *)scope
State:(NSString *)state;
+ (BOOL)sendText:(NSString *)text
InScene:(enum WXScene)scene;
+ (BOOL)sendImageData:(NSData *)imageData
TagName:(NSString *)tagName
MessageExt:(NSString *)messageExt
Action:(NSString *)action
ThumbImage:(UIImage *)thumbImage
InScene:(enum WXScene)scene;
+ (BOOL)sendImage:(NSData *)anImageData
InScene:(enum WXScene)aScene;
+ (BOOL)sendLinkURL:(NSString *)urlString
TagName:(NSString *)tagName
Title:(NSString *)title
Description:(NSString *)description
ThumbImage:(UIImage *)thumbImage
InScene:(enum WXScene)scene;
+ (BOOL)sendMusic:(NSString *)aMusicUrl
musicDataUrl:(NSString *)aMusicDataUrl
title:(NSString *)aTitle
description:(NSString *)aDescription
thumbImage:(NSData *)aThumbImageData
InScene:(enum WXScene)aScene;
+ (BOOL)sendMusicURL:(NSString *)musicURL
dataURL:(NSString *)dataURL
Title:(NSString *)title
Description:(NSString *)description
ThumbImage:(UIImage *)thumbImage
InScene:(enum WXScene)scene;
+ (BOOL)sendVideo:(NSString *)aVideoUrl
title:(NSString *)aTitle
description:(NSString *)aDescription
thumbImage:(NSData *)aThumbImageData
InScene:(enum WXScene)aScene;
+ (BOOL)sendVideoURL:(NSString *)videoURL
Title:(NSString *)title
Description:(NSString *)description
ThumbImage:(UIImage *)thumbImage
InScene:(enum WXScene)scene;
+ (BOOL)sendLink:(NSString *)aLinkUrl
title:(NSString *)aTitle
description:(NSString *)aDescription
thumbImage:(NSData *)aThumbImageData
InScene:(enum WXScene)aScene;
+ (BOOL)sendEmotionData:(NSData *)emotionData
ThumbImage:(UIImage *)thumbImage
InScene:(enum WXScene)scene;
+ (BOOL)sendMiniProgram:(NSString *)aUserName
miniProgramType:(WXMiniProgramType)aMiniProgramType
path:(NSString *)aPath
hdThumbImage:(NSData *)aHdThumbImageData
title:(NSString *)aTitle
description:(NSString *)aDescription
webpageUrl:(NSString *)aWebpageUrl
thumbImage:(NSData *)aThumbImageData;
+ (BOOL)sendFileData:(NSData *)fileData
fileExtension:(NSString *)extension
Title:(NSString *)title
Description:(NSString *)description
ThumbImage:(UIImage *)thumbImage
InScene:(enum WXScene)scene;
+ (BOOL)sendMiniProgramWebpageUrl:(NSString *)webpageUrl
userName:(NSString *)userName
path:(NSString *)path
title:(NSString *)title
Description:(NSString *)description
ThumbImage:(UIImage *)thumbImage
hdImageData:(NSData *)hdImageData
withShareTicket:(BOOL)withShareTicket
miniProgramType:(WXMiniProgramType)programType
InScene:(enum WXScene)scene;
+ (BOOL)launchMiniProgramWithUserName:(NSString *)userName
path:(NSString *)path
type:(WXMiniProgramType)miniProgramType;
+ (BOOL)sendAppContentData:(NSData *)data
ExtInfo:(NSString *)info
ExtURL:(NSString *)url
Title:(NSString *)title
Description:(NSString *)description
MessageExt:(NSString *)messageExt
MessageAction:(NSString *)action
ThumbImage:(UIImage *)thumbImage
InScene:(enum WXScene)scene;
+ (BOOL)addCardsToCardPackage:(NSArray *)cardIds cardExts:(NSArray *)cardExts;
+ (BOOL)sendAuthRequestScope:(NSString *)scope
State:(NSString *)state
OpenID:(NSString *)openID;
+ (BOOL)openProfileWithAppID:(NSString *)appID
Description:(NSString *)description
UserName:(NSString *)userName
ExtMsg:(NSString *)extMessage;
+ (BOOL)jumpToBizWebviewWithAppID:(NSString *)appID
Description:(NSString *)description
tousrname:(NSString *)tousrname
ExtMsg:(NSString *)extMsg;
+ (BOOL)chooseCard:(NSString *)appid
cardSign:(NSString *)cardSign
nonceStr:(NSString *)nonceStr
signType:(NSString *)signType
timestamp:(UInt32)timestamp;
+ (BOOL)openUrl:(NSString *)url;
+ (BOOL)chooseInvoice:(NSString *)appid
cardSign:(NSString *)cardSign
nonceStr:(NSString *)nonceStr
signType:(NSString *)signType
timestamp:(UInt32)timestamp;
+ (BOOL)pay:(NSString *)aPartnerId
prepayId:(NSString *)aPrepayId
nonceStr:(NSString *)aNonceStr
timeStamp:(UInt32)aTimeStamp
package:(NSString *)aPackage
sign:(NSString *)aSign;
@end

View File

@@ -1,339 +1,160 @@
//
// WXApiManager.m
// SDKSample
//
// Created by Jeason on 15/7/14.
//
//
#import "WXApi.h"
#import "WXApiRequestHandler.h"
#import "SendMessageToWXReq+requestWithTextOrMediaMessage.h"
#import "WXMediaMessage+messageConstruct.h"
#import "SendMessageToWXReq+requestWithMessage.h"
#import "WXMediaMessage+construct.h"
@implementation WXApiRequestHandler
#pragma mark - Public Methods
+ (BOOL)sendText:(NSString *)text
InScene:(enum WXScene)scene {
SendMessageToWXReq *req = [SendMessageToWXReq requestWithText:text
OrMediaMessage:nil
bText:YES
InScene:scene];
return [WXApi sendReq:req];
}
+ (BOOL)sendImageData:(NSData *)imageData
TagName:(NSString *)tagName
MessageExt:(NSString *)messageExt
Action:(NSString *)action
ThumbImage:(UIImage *)thumbImage
InScene:(enum WXScene)scene {
WXImageObject *ext = [WXImageObject object];
ext.imageData = imageData;
WXMediaMessage *message = [WXMediaMessage messageWithTitle:nil
Description:nil
Object:ext
MessageExt:messageExt
MessageAction:action
ThumbImage:thumbImage
MediaTag:tagName];
SendMessageToWXReq* req = [SendMessageToWXReq requestWithText:nil
OrMediaMessage:message
bText:NO
InScene:scene];
return [WXApi sendReq:req];
}
+ (BOOL)sendLinkURL:(NSString *)urlString
TagName:(NSString *)tagName
Title:(NSString *)title
Description:(NSString *)description
ThumbImage:(UIImage *)thumbImage
InScene:(enum WXScene)scene {
WXWebpageObject *ext = [WXWebpageObject object];
ext.webpageUrl = urlString;
WXMediaMessage *message = [WXMediaMessage messageWithTitle:title
Description:description
Object:ext
MessageExt:nil
MessageAction:nil
ThumbImage:thumbImage
MediaTag:tagName];
SendMessageToWXReq* req = [SendMessageToWXReq requestWithText:nil
OrMediaMessage:message
bText:NO
InScene:scene];
return [WXApi sendReq:req];
}
+ (BOOL)sendMusicURL:(NSString *)musicURL
dataURL:(NSString *)dataURL
Title:(NSString *)title
Description:(NSString *)description
ThumbImage:(UIImage *)thumbImage
InScene:(enum WXScene)scene {
WXMusicObject *ext = [WXMusicObject object];
ext.musicUrl = musicURL;
ext.musicDataUrl = dataURL;
WXMediaMessage *message = [WXMediaMessage messageWithTitle:title
Description:description
Object:ext
MessageExt:nil
MessageAction:nil
ThumbImage:thumbImage
MediaTag:nil];
SendMessageToWXReq* req = [SendMessageToWXReq requestWithText:nil
OrMediaMessage:message
bText:NO
InScene:scene];
return [WXApi sendReq:req];
}
+ (BOOL)sendVideoURL:(NSString *)videoURL
Title:(NSString *)title
Description:(NSString *)description
ThumbImage:(UIImage *)thumbImage
InScene:(enum WXScene)scene {
WXMediaMessage *message = [WXMediaMessage message];
message.title = title;
message.description = description;
[message setThumbImage:thumbImage];
WXVideoObject *ext = [WXVideoObject object];
ext.videoUrl = videoURL;
message.mediaObject = ext;
SendMessageToWXReq* req = [SendMessageToWXReq requestWithText:nil
OrMediaMessage:message
bText:NO
InScene:scene];
return [WXApi sendReq:req];
}
+ (BOOL)sendEmotionData:(NSData *)emotionData
ThumbImage:(UIImage *)thumbImage
InScene:(enum WXScene)scene {
WXMediaMessage *message = [WXMediaMessage message];
[message setThumbImage:thumbImage];
WXEmoticonObject *ext = [WXEmoticonObject object];
ext.emoticonData = emotionData;
message.mediaObject = ext;
SendMessageToWXReq* req = [SendMessageToWXReq requestWithText:nil
OrMediaMessage:message
bText:NO
InScene:scene];
return [WXApi sendReq:req];
}
+ (BOOL)sendFileData:(NSData *)fileData
fileExtension:(NSString *)extension
Title:(NSString *)title
Description:(NSString *)description
ThumbImage:(UIImage *)thumbImage
InScene:(enum WXScene)scene {
WXMediaMessage *message = [WXMediaMessage message];
message.title = title;
message.description = description;
[message setThumbImage:thumbImage];
WXFileObject *ext = [WXFileObject object];
ext.fileExtension = @"pdf";
ext.fileData = fileData;
message.mediaObject = ext;
SendMessageToWXReq* req = [SendMessageToWXReq requestWithText:nil
OrMediaMessage:message
bText:NO
InScene:scene];
return [WXApi sendReq:req];
}
+ (BOOL)sendMiniProgramWebpageUrl:(NSString *)webpageUrl
userName:(NSString *)userName
path:(NSString *)path
title:(NSString *)title
Description:(NSString *)description
ThumbImage:(UIImage *)thumbImage
hdImageData:(NSData *)hdImageData
withShareTicket:(BOOL)withShareTicket
miniProgramType:(WXMiniProgramType)programType
InScene:(enum WXScene)scene
{
WXMiniProgramObject *ext = [WXMiniProgramObject object];
ext.webpageUrl = webpageUrl;
ext.userName = userName;
ext.path = path;
ext.hdImageData = hdImageData;
ext.withShareTicket = withShareTicket;
ext.miniProgramType = programType;
WXMediaMessage *message = [WXMediaMessage messageWithTitle:title
Description:description
Object:ext
MessageExt:nil
MessageAction:nil
ThumbImage:thumbImage
MediaTag:nil];
SendMessageToWXReq* req = [SendMessageToWXReq requestWithText:nil
OrMediaMessage:message
bText:NO
InScene:scene];
return [WXApi sendReq:req];
}
+ (BOOL)launchMiniProgramWithUserName:(NSString *)userName
path:(NSString *)path
type:(WXMiniProgramType)miniProgramType
{
WXLaunchMiniProgramReq *launchMiniProgramReq = [WXLaunchMiniProgramReq object];
launchMiniProgramReq.userName = userName;
launchMiniProgramReq.path = path;
launchMiniProgramReq.miniProgramType = miniProgramType;
return [WXApi sendReq:launchMiniProgramReq];
}
+ (BOOL)sendAppContentData:(NSData *)data
ExtInfo:(NSString *)info
ExtURL:(NSString *)url
Title:(NSString *)title
Description:(NSString *)description
MessageExt:(NSString *)messageExt
MessageAction:(NSString *)action
ThumbImage:(UIImage *)thumbImage
InScene:(enum WXScene)scene {
WXAppExtendObject *ext = [WXAppExtendObject object];
ext.extInfo = info;
ext.url = url;
ext.fileData = data;
WXMediaMessage *message = [WXMediaMessage messageWithTitle:title
Description:description
Object:ext
MessageExt:messageExt
MessageAction:action
ThumbImage:thumbImage
MediaTag:nil];
SendMessageToWXReq* req = [SendMessageToWXReq requestWithText:nil
OrMediaMessage:message
bText:NO
InScene:scene];
return [WXApi sendReq:req];
}
+ (BOOL)addCardsToCardPackage:(NSArray *)cardIds cardExts:(NSArray *)cardExts{
NSMutableArray *cardItems = [NSMutableArray array];
for (NSString *cardId in cardIds) {
WXCardItem *item = [[WXCardItem alloc] init];
item.cardId = cardId;
item.appID = @"wxf8b4f85f3a794e77";
[cardItems addObject:item];
}
for (NSInteger index = 0; index < cardItems.count; index++) {
WXCardItem *item = cardItems[index];
NSString *ext = cardExts[index];
item.extMsg = ext;
}
AddCardToWXCardPackageReq *req = [[AddCardToWXCardPackageReq alloc] init];
req.cardAry = cardItems;
return [WXApi sendReq:req];
}
+ (BOOL)chooseCard:(NSString *)appid
cardSign:(NSString *)cardSign
nonceStr:(NSString *)nonceStr
signType:(NSString *)signType
timestamp:(UInt32)timestamp
{
WXChooseCardReq *chooseCardReq = [[WXChooseCardReq alloc] init];
chooseCardReq.appID = appid;
chooseCardReq.cardSign = cardSign;
chooseCardReq.nonceStr = nonceStr;
chooseCardReq.signType = signType;
chooseCardReq.timeStamp = timestamp;
return [WXApi sendReq:chooseCardReq];
}
#pragma OAuth2
+ (BOOL)sendAuthRequestScope:(NSString *)scope
State:(NSString *)state
OpenID:(NSString *)openID {
{
SendAuthReq* req = [[SendAuthReq alloc] init];
req.scope = scope; // @"post_timeline,sns"
req.scope = scope;
req.state = state;
req.openID = openID;
return [WXApi sendReq:req];
}
+ (BOOL)openProfileWithAppID:(NSString *)appID
Description:(NSString *)description
UserName:(NSString *)userName
ExtMsg:(NSString *)extMessage {
[WXApi registerApp:appID];
JumpToBizProfileReq *req = [[JumpToBizProfileReq alloc]init];
req.profileType = WXBizProfileType_Device;
req.username = userName;
req.extMsg = extMessage;
return [WXApi sendReq:req];
}
+ (BOOL)jumpToBizWebviewWithAppID:(NSString *)appID
Description:(NSString *)description
tousrname:(NSString *)tousrname
ExtMsg:(NSString *)extMsg {
[WXApi registerApp:appID];
JumpToBizWebviewReq *req = [[JumpToBizWebviewReq alloc]init];
req.tousrname = tousrname;
req.extMsg = extMsg;
req.webType = WXMPWebviewType_Ad;
return [WXApi sendReq:req];
}
+ (BOOL)openUrl:(NSString *)url
#pragma Share
+ (BOOL)sendText:(NSString *)text
InScene:(enum WXScene)scene
{
OpenWebviewReq *req = [[OpenWebviewReq alloc] init];
req.url = url;
SendMessageToWXReq *req = [SendMessageToWXReq requestWithMessage:text
bText:YES
scene:scene];
return [WXApi sendReq:req];
}
+ (BOOL)chooseInvoice:(NSString *)appid
cardSign:(NSString *)cardSign
nonceStr:(NSString *)nonceStr
signType:(NSString *)signType
timestamp:(UInt32)timestamp
+ (BOOL)sendImage:(NSData *)anImageData InScene:(enum WXScene)aScene
{
WXChooseInvoiceReq *chooseInvoiceReq = [[WXChooseInvoiceReq alloc] init];
chooseInvoiceReq.appID = appid;
chooseInvoiceReq.cardSign = cardSign;
chooseInvoiceReq.nonceStr = nonceStr;
chooseInvoiceReq.signType = signType;
// chooseCardReq.cardType = @"INVOICE";
chooseInvoiceReq.timeStamp = timestamp;
// chooseCardReq.canMultiSelect = 1;
return [WXApi sendReq:chooseInvoiceReq];
WXImageObject *anImageObject = [WXImageObject object];
anImageObject.imageData = anImageData;
WXMediaMessage *aMediaMessage = [WXMediaMessage messageWithTitle:nil
description:nil
thumbData:nil
mediaObject:anImageObject];
SendMessageToWXReq *req = [SendMessageToWXReq requestWithMessage:aMediaMessage
bText:NO
scene:aScene];
return [WXApi sendReq:req];
}
+ (BOOL)sendMusic:(NSString *)aMusicUrl
musicDataUrl:(NSString *)aMusicDataUrl
title:(NSString *)aTitle
description:(NSString *)aDescription
thumbImage:(NSData *)aThumbImageData
InScene:(enum WXScene)aScene
{
WXMusicObject *aMusicObject = [WXMusicObject object];
aMusicObject.musicUrl = aMusicUrl;
aMusicObject.musicDataUrl = aMusicDataUrl;
WXMediaMessage *aMediaMessage = [WXMediaMessage messageWithTitle:aTitle
description:aDescription
thumbData:aThumbImageData
mediaObject:aMusicObject];
SendMessageToWXReq *req = [SendMessageToWXReq requestWithMessage:aMediaMessage
bText:NO
scene:aScene];
return [WXApi sendReq:req];
}
+ (BOOL)sendVideo:(NSString *)aVideoUrl
title:(NSString *)aTitle
description:(NSString *)aDescription
thumbImage:(NSData *)aThumbImageData
InScene:(enum WXScene)aScene
{
WXVideoObject *aVideoObject = [WXVideoObject object];
aVideoObject.videoUrl = aVideoUrl;
WXMediaMessage *aMediaMessage = [WXMediaMessage messageWithTitle:aTitle
description:aDescription
thumbData:aThumbImageData
mediaObject:aVideoObject];
SendMessageToWXReq *req = [SendMessageToWXReq requestWithMessage:aMediaMessage
bText:NO
scene:aScene];
return [WXApi sendReq:req];
}
+ (BOOL)sendLink:(NSString *)aLinkUrl
title:(NSString *)aTitle
description:(NSString *)aDescription
thumbImage:(NSData *)aThumbImageData
InScene:(enum WXScene)aScene
{
WXWebpageObject *aWebpageObject = [WXWebpageObject object];
aWebpageObject.webpageUrl = aLinkUrl;
WXMediaMessage *aMediaMessage = [WXMediaMessage messageWithTitle:aTitle
description:aDescription
thumbData:aThumbImageData
mediaObject:aWebpageObject];
SendMessageToWXReq *req = [SendMessageToWXReq requestWithMessage:aMediaMessage
bText:NO
scene:aScene];
return [WXApi sendReq:req];
}
+ (BOOL)sendMiniProgram:(NSString *)aUserName
miniProgramType:(WXMiniProgramType)aMiniProgramType
path:(NSString *)aPath
hdThumbImage:(NSData *)aHdThumbImageData
title:(NSString *)aTitle
description:(NSString *)aDescription
webpageUrl:(NSString *)aWebpageUrl
thumbImage:(NSData *)aThumbImageData
{
WXMiniProgramObject *aWXMiniProgramObject = [WXMiniProgramObject object];
aWXMiniProgramObject.userName = aUserName;
aWXMiniProgramObject.withShareTicket = YES;
aWXMiniProgramObject.miniProgramType = aMiniProgramType;
aWXMiniProgramObject.path = aPath;
aWXMiniProgramObject.hdImageData = aHdThumbImageData;
aWXMiniProgramObject.webpageUrl = aWebpageUrl;
WXMediaMessage *aMediaMessage = [WXMediaMessage messageWithTitle:aTitle
description:aDescription
thumbData:aThumbImageData
mediaObject:aWXMiniProgramObject];
SendMessageToWXReq *req = [SendMessageToWXReq requestWithMessage:aMediaMessage
bText:NO
scene:WXSceneSession];
return [WXApi sendReq:req];
}
+ (BOOL)pay:(NSString *)aPartnerId
prepayId:(NSString *)aPrepayId
nonceStr:(NSString *)aNonceStr
timeStamp:(UInt32)aTimeStamp
package:(NSString *)aPackage
sign:(NSString *)aSign
{
PayReq *aPayReq = [PayReq new];
aPayReq.partnerId = aPartnerId;
aPayReq.prepayId = aPrepayId;
aPayReq.nonceStr = aNonceStr;
aPayReq.timeStamp = aTimeStamp;
aPayReq.package = aPackage;
aPayReq.sign = aSign;
return [WXApi sendReq:aPayReq];
}
@end

View File

@@ -1,55 +1,5 @@
//
// WXApiResponseManager.h
// SDKSample
//
// Created by Jeason on 15/7/14.
//
//
#import <Foundation/Foundation.h>
#import "WXApiObject.h"
@interface WXApiResponseHandler : NSObject
+ (BOOL)respText:(NSString *)text;
+ (BOOL)respImageData:(NSData *)imageData
MessageExt:(NSString *)messageExt
Action:(NSString *)action
ThumbImage:(UIImage *)thumbImage;
+ (BOOL)respLinkURL:(NSString *)urlString
Title:(NSString *)title
Description:(NSString *)description
ThumbImage:(UIImage *)thumbImage;
+ (BOOL)respMusicURL:(NSString *)musicURL
dataURL:(NSString *)dataURL
Title:(NSString *)title
Description:(NSString *)description
ThumbImage:(UIImage *)thumbImage;
+ (BOOL)respVideoURL:(NSString *)videoURL
Title:(NSString *)title
Description:(NSString *)description
ThumbImage:(UIImage *)thumbImage;
+ (BOOL)respEmotionData:(NSData *)emotionData
ThumbImage:(UIImage *)thumbImage;
+ (BOOL)respFileData:(NSData *)fileData
fileExtension:(NSString *)extension
Title:(NSString *)title
Description:(NSString *)description
ThumbImage:(UIImage *)thumbImage;
+ (BOOL)respAppContentData:(NSData *)data
ExtInfo:(NSString *)info
ExtURL:(NSString *)url
Title:(NSString *)title
Description:(NSString *)description
MessageExt:(NSString *)messageExt
MessageAction:(NSString *)action
ThumbImage:(UIImage *)thumbImage;
@end

View File

@@ -1,181 +1,6 @@
//
// WXApiResponseManager.m
// SDKSample
//
// Created by Jeason on 15/7/14.
//
//
#import "WXApi.h"
#import "WXApiResponseHandler.h"
#import "GetMessageFromWXResp+responseWithTextOrMediaMessage.h"
#import "WXMediaMessage+messageConstruct.h"
@implementation WXApiResponseHandler
#pragma mark - Public Methods
+ (BOOL)respText:(NSString *)text {
GetMessageFromWXResp *resp = [GetMessageFromWXResp responseWithText:text
OrMediaMessage:nil
bText:YES];
return [WXApi sendResp:resp];
}
+ (BOOL)respImageData:(NSData *)imageData
MessageExt:(NSString *)messageExt
Action:(NSString *)action
ThumbImage:(UIImage *)thumbImage {
WXImageObject *ext = [WXImageObject object];
ext.imageData = imageData;
WXMediaMessage *message = [WXMediaMessage messageWithTitle:nil
Description:nil
Object:ext
MessageExt:messageExt
MessageAction:action
ThumbImage:thumbImage
MediaTag:nil];
GetMessageFromWXResp* resp = [GetMessageFromWXResp responseWithText:nil
OrMediaMessage:message
bText:NO];
return [WXApi sendResp:resp];
}
+ (BOOL)respLinkURL:(NSString *)urlString
Title:(NSString *)title
Description:(NSString *)description
ThumbImage:(UIImage *)thumbImage {
WXWebpageObject *ext = [WXWebpageObject object];
ext.webpageUrl = urlString;
WXMediaMessage *message = [WXMediaMessage messageWithTitle:title
Description:description
Object:ext
MessageExt:nil
MessageAction:nil
ThumbImage:thumbImage
MediaTag:nil];
GetMessageFromWXResp* resp = [GetMessageFromWXResp responseWithText:nil
OrMediaMessage:message
bText:NO];
return [WXApi sendResp:resp];
}
+ (BOOL)respMusicURL:(NSString *)musicURL
dataURL:(NSString *)dataURL
Title:(NSString *)title
Description:(NSString *)description
ThumbImage:(UIImage *)thumbImage {
WXMediaMessage *message = [WXMediaMessage message];
message.title = title;
message.description = description;
[message setThumbImage:thumbImage];
WXMusicObject *ext = [WXMusicObject object];
ext.musicUrl = musicURL;
ext.musicDataUrl = dataURL;
message.mediaObject = ext;
GetMessageFromWXResp* resp = [GetMessageFromWXResp responseWithText:nil
OrMediaMessage:message
bText:NO];
return [WXApi sendResp:resp];
}
+ (BOOL)respVideoURL:(NSString *)videoURL
Title:(NSString *)title
Description:(NSString *)description
ThumbImage:(UIImage *)thumbImage {
WXVideoObject *ext = [WXVideoObject object];
ext.videoUrl = videoURL;
WXMediaMessage *message = [WXMediaMessage messageWithTitle:title
Description:description
Object:ext
MessageExt:nil
MessageAction:nil
ThumbImage:thumbImage
MediaTag:nil];
GetMessageFromWXResp* resp = [GetMessageFromWXResp responseWithText:nil
OrMediaMessage:message
bText:NO];
return [WXApi sendResp:resp];
}
+ (BOOL)respEmotionData:(NSData *)emotionData
ThumbImage:(UIImage *)thumbImage {
WXEmoticonObject *ext = [WXEmoticonObject object];
ext.emoticonData = emotionData;
WXMediaMessage *message = [WXMediaMessage messageWithTitle:nil
Description:nil
Object:ext
MessageExt:nil
MessageAction:nil
ThumbImage:thumbImage
MediaTag:nil];
GetMessageFromWXResp* resp = [GetMessageFromWXResp responseWithText:nil
OrMediaMessage:message
bText:NO];
return [WXApi sendResp:resp];
}
+ (BOOL)respFileData:(NSData *)fileData
fileExtension:(NSString *)extension
Title:(NSString *)title
Description:(NSString *)description
ThumbImage:(UIImage *)thumbImage {
WXFileObject *ext = [WXFileObject object];
ext.fileExtension = extension;
ext.fileData = fileData;
WXMediaMessage *message = [WXMediaMessage messageWithTitle:title
Description:description
Object:ext
MessageExt:nil
MessageAction:nil
ThumbImage:thumbImage
MediaTag:nil];
GetMessageFromWXResp* resp = [GetMessageFromWXResp responseWithText:nil
OrMediaMessage:message
bText:NO];
return [WXApi sendResp:resp];
}
+ (BOOL)respAppContentData:(NSData *)data
ExtInfo:(NSString *)info
ExtURL:(NSString *)url
Title:(NSString *)title
Description:(NSString *)description
MessageExt:(NSString *)messageExt
MessageAction:(NSString *)action
ThumbImage:(UIImage *)thumbImage {
WXAppExtendObject *ext = [WXAppExtendObject object];
ext.extInfo = info;
ext.url = url;
ext.fileData = data;
WXMediaMessage *message = [WXMediaMessage messageWithTitle:title
Description:description
Object:ext
MessageExt:messageExt
MessageAction:action
ThumbImage:thumbImage
MediaTag:nil];
GetMessageFromWXResp* resp = [GetMessageFromWXResp responseWithText:nil
OrMediaMessage:message
bText:NO];
return [WXApi sendResp:resp];
}
@end

View File

@@ -0,0 +1,16 @@
#ifndef FormatConversion_h
#define FormatConversion_h
#import <UIKit/UIKit.h>
@interface FormatConversion : NSObject
+ (NSData *)stringToData:(NSString *)aString;
+ (NSData *)uiImageToData:(UIImage *)anUIImage;
+ (UIImage *)imageString:(NSString *)anImageUrlString toUIImageWithSize:(CGSize)aSize;
@end
#endif

View File

@@ -0,0 +1,53 @@
#import "FormatConversion.h"
@implementation FormatConversion
+ (NSData *)stringToData:(NSString *)aString
{
NSURL *aUrl;
if ([self isPath:aString]) {
aUrl = [NSURL fileURLWithPath:aString];
} else {
aUrl = [NSURL URLWithString:aString];
}
return [NSData dataWithContentsOfURL:aUrl];
}
+ (NSData *)uiImageToData:(UIImage *)anUIImage
{
if (anUIImage) {
return UIImagePNGRepresentation(anUIImage);
}
return nil;
}
+ (UIImage *)imageString:(NSString *)anImageString toUIImageWithSize:(CGSize)aSize
{
NSData *imageData = [self stringToData:anImageString];
UIImage *image = nil;
if (imageData != nil) {
image = [self scaleImage:[UIImage imageWithData:imageData] toSize:aSize];
}
return image;
}
+ (BOOL)isPath:(NSString *)aString
{
NSString *fullPath = aString.stringByStandardizingPath;
return [fullPath hasPrefix:@"/"] || [fullPath hasPrefix:@"file:/"];
}
+ (UIImage *)scaleImage:(UIImage *)anImage toSize:(CGSize)aNewSize
{
// UIGraphicsBeginImageContext(newSize);
// In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
// Pass 1.0 to force exact pixel size.
UIGraphicsBeginImageContextWithOptions(aNewSize, NO, 0.0);
[anImage drawInRect:CGRectMake(0, 0, aNewSize.width, aNewSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
@end

View File

@@ -1,16 +0,0 @@
//
// GetMessageFromWXResp+responseWithTextOrMediaMessage.h
// SDKSample
//
// Created by Jeason on 15/7/14.
//
//
#import "WXApiObject.h"
@interface GetMessageFromWXResp (responseWithTextOrMediaMessage)
+ (GetMessageFromWXResp *)responseWithText:(NSString *)text
OrMediaMessage:(WXMediaMessage *)message
bText:(BOOL)bText;
@end

View File

@@ -1,25 +0,0 @@
//
// GetMessageFromWXResp+responseWithTextOrMediaMessage.m
// SDKSample
//
// Created by Jeason on 15/7/14.
//
//
#import "GetMessageFromWXResp+responseWithTextOrMediaMessage.h"
@implementation GetMessageFromWXResp (responseWithTextOrMediaMessage)
+ (GetMessageFromWXResp *)responseWithText:(NSString *)text
OrMediaMessage:(WXMediaMessage *)message
bText:(BOOL)bText {
GetMessageFromWXResp *resp = [[GetMessageFromWXResp alloc] init];
resp.bText = bText;
if (bText)
resp.text = text;
else
resp.message = message;
return resp;
}
@end

View File

@@ -0,0 +1,14 @@
#ifndef SendMessageToWXReq_requestWithMessage_h
#define SendMessageToWXReq_requestWithMessage_h
#import "WXApiObject.h"
@interface SendMessageToWXReq (requestWithMessage)
+ (SendMessageToWXReq *)requestWithMessage:(id)aMessage
bText:(BOOL)aBText
scene:(enum WXScene)aScene;
@end
#endif

View File

@@ -0,0 +1,21 @@
#import "SendMessageToWXReq+requestWithMessage.h"
@implementation SendMessageToWXReq (requestWithMessage)
+ (SendMessageToWXReq *)requestWithMessage:(id)aMessage
bText:(BOOL)aBText
scene:(enum WXScene)aScene
{
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
req.bText = aBText;
req.scene = aScene;
if (aBText) {
req.text = aMessage;
} else {
req.message = aMessage;
}
return req;
}
@end

View File

@@ -1,17 +0,0 @@
//
// SendMessageToWXReq+requestWithTextOrMediaMessage.h
// SDKSample
//
// Created by Jeason on 15/7/14.
//
//
#import "WXApiObject.h"
@interface SendMessageToWXReq (requestWithTextOrMediaMessage)
+ (SendMessageToWXReq *)requestWithText:(NSString *)text
OrMediaMessage:(WXMediaMessage *)message
bText:(BOOL)bText
InScene:(enum WXScene)scene;
@end

View File

@@ -1,27 +0,0 @@
//
// SendMessageToWXReq+requestWithTextOrMediaMessage.m
// SDKSample
//
// Created by Jeason on 15/7/14.
//
//
#import "SendMessageToWXReq+requestWithTextOrMediaMessage.h"
@implementation SendMessageToWXReq (requestWithTextOrMediaMessage)
+ (SendMessageToWXReq *)requestWithText:(NSString *)text
OrMediaMessage:(WXMediaMessage *)message
bText:(BOOL)bText
InScene:(enum WXScene)scene {
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
req.bText = bText;
req.scene = scene;
if (bText)
req.text = text;
else
req.message = message;
return req;
}
@end

View File

@@ -0,0 +1,15 @@
#ifndef WXMediaMessage_construct_h
#define WXMediaMessage_construct_h
#import "WXApiObject.h"
@interface WXMediaMessage (construct)
+ (WXMediaMessage *)messageWithTitle:(NSString *)aTitle
description:(NSString *)aDescription
thumbData:(NSData *)aThumbData
mediaObject:(id)aMediaObject;
@end
#endif

View File

@@ -0,0 +1,19 @@
#import "WXMediaMessage+construct.h"
@implementation WXMediaMessage (construct)
+ (WXMediaMessage *)messageWithTitle:(NSString *)aTitle
description:(NSString *)aDescription
thumbData:(NSData *)aThumbData
mediaObject:(id)aMediaObject
{
WXMediaMessage *aMediaMessage = [WXMediaMessage message];
aMediaMessage.title = aTitle;
aMediaMessage.description = aDescription;
aMediaMessage.thumbData = aThumbData;
aMediaMessage.mediaObject = aMediaObject;
return aMediaMessage;
}
@end

View File

@@ -1,20 +0,0 @@
//
// WXMediaMessage+messageConstruct.h
// SDKSample
//
// Created by Jeason on 15/7/14.
//
//
#import "WXApiObject.h"
@interface WXMediaMessage (messageConstruct)
+ (WXMediaMessage *)messageWithTitle:(NSString *)title
Description:(NSString *)description
Object:(id)mediaObject
MessageExt:(NSString *)messageExt
MessageAction:(NSString *)action
ThumbImage:(UIImage *)thumbImage
MediaTag:(NSString *)tagName;
@end

View File

@@ -1,31 +0,0 @@
//
// WXMediaMessage+messageConstruct.m
// SDKSample
//
// Created by Jeason on 15/7/14.
//
//
#import "WXMediaMessage+messageConstruct.h"
@implementation WXMediaMessage (messageConstruct)
+ (WXMediaMessage *)messageWithTitle:(NSString *)title
Description:(NSString *)description
Object:(id)mediaObject
MessageExt:(NSString *)messageExt
MessageAction:(NSString *)action
ThumbImage:(UIImage *)thumbImage
MediaTag:(NSString *)tagName {
WXMediaMessage *message = [WXMediaMessage message];
message.title = title;
message.description = description;
message.mediaObject = mediaObject;
message.messageExt = messageExt;
message.messageAction = action;
message.mediaTagName = tagName;
[message setThumbImage:thumbImage];
return message;
}
@end

View File

@@ -1,16 +1,21 @@
#if __has_include(<React/RCTBridgeModule.h>)
#import <React/RCTBridgeModule.h>
#else
#import "RCTBridgeModule.h"
#endif
#if __has_include(<React/RCTEventEmitter.h>)
#import <React/RCTEventEmitter.h>
#else
#import "RCTEventEmitter.h"
#endif
#import "WXApi.h"
#import "WXApiRequestHandler.h"
#define RNWechatEventName @"RNWechatEvent"
#define RNWechatOperateSuccess @"true"
#define RNWechatOperateFailed @"false"
static NSString *const kOpenURLNotification = @"RCTOpenURLNotification";
@interface RNWechat : RCTEventEmitter <RCTBridgeModule, WXApiDelegate>
@property (nonatomic) BOOL isWXApiRegisteSuccess;
@end

View File

@@ -1,5 +1,5 @@
#import "RNWechat.h"
#import "Utils.h"
#import "FormatConversion.h"
#define ASSIGN_EMPTY_STRING(assign, string) \
if (string != nil) { \
@@ -8,28 +8,34 @@ if (string != nil) { \
assign = @""; \
}
static NSString *const kOpenURLNotification = @"RCTOpenURLNotification";
@implementation RNWechat
+ (NSString *)getOperateResult:(BOOL)isOperateSucc
{
return isOperateSucc ? RNWechatOperateSuccess : RNWechatOperateFailed;
@implementation RNWechat {
BOOL _isWXApiRegisteSuccess;
}
RCT_EXPORT_MODULE()
+ (BOOL)requiresMainQueueSetup
{
return YES;
}
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
#pragma lifecycle
- (instancetype)init
{
self = [super init];
if (self) {
_isWXApiRegisteSuccess = false;
// observe RCTLinking push notification
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(openURL:)
name:kOpenURLNotification
object:nil];
addObserver:self
selector:@selector(openURL:)
name:kOpenURLNotification
object:nil];
}
return self;
}
@@ -39,12 +45,265 @@ RCT_EXPORT_MODULE()
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (BOOL)openURL:(NSNotification *)aNotification
#pragma
RCT_REMAP_METHOD(registerApp,
appId:(NSString *)anAppId
isDebug:(BOOL)isDebug
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSURL *aURL = [NSURL URLWithString:[aNotification userInfo][@"url"]];
return [WXApi handleOpenURL:aURL delegate:self];
if(![anAppId isEqualToString:@""]) {
if (isDebug) {
[WXApi startLogByLevel:WXLogLevelDetail
logBlock:^(NSString *log) { NSLog(@"WXApi: %@", log); }];
}
_isWXApiRegisteSuccess = [WXApi registerApp:anAppId];
if (_isWXApiRegisteSuccess) {
NSLog(@"WXApi register success. appId: %@", anAppId);
} else {
NSLog(@"WXApi register failed. appId: %@", anAppId);
}
} else {
_isWXApiRegisteSuccess = NO;
NSLog(@"There is no appId for WXApi.");
}
resolve([self getResolveResFromBool:_isWXApiRegisteSuccess]);
}
RCT_REMAP_METHOD(isWXApiRegisteSuccess,
isWXApiRegisteSuccessResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
resolve([self getResolveResFromBool:_isWXApiRegisteSuccess]);
}
#pragma
RCT_REMAP_METHOD(isWXAppInstalled,
isWXAppInstalledResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
resolve([self getResolveResFromBool:[WXApi isWXAppInstalled]]);
}
RCT_REMAP_METHOD(isWXAppSupportApi,
isWXAppSupportApiResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
resolve([self getResolveResFromBool:[WXApi isWXAppSupportApi]]);
}
RCT_REMAP_METHOD(getWXAppInstallUrl,
getWXAppInstallUrlResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
resolve([WXApi getWXAppInstallUrl]);
}
#pragma
RCT_REMAP_METHOD(openWXApp,
openWXAppResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
resolve([self getResolveResFromBool:[WXApi openWXApp]]);
}
#pragma OAuth2
RCT_REMAP_METHOD(sendAuthRequest,
sendAuthRequestScope:(NSString *)aScope
state:(NSString *)aState
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
resolve([self getResolveResFromBool:[WXApiRequestHandler sendAuthRequestScope:aScope
State:aState]]);
}
#pragma Share
RCT_REMAP_METHOD(sendText,
sendText:(NSString *)aText
sceneType:(NSInteger *)aSceneType
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
resolve([self getResolveResFromBool:[WXApiRequestHandler sendText:aText
InScene:(enum WXScene)aSceneType]]);
}
RCT_REMAP_METHOD(sendImage,
sendImage:(NSString *)anImageString
sceneType:(NSInteger *)aSceneType
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSData *anImageData = [FormatConversion stringToData:anImageString];
resolve([self getResolveResFromBool:[WXApiRequestHandler sendImage:anImageData
InScene:(enum WXScene)aSceneType]]);
}
RCT_REMAP_METHOD(sendMusic,
musicUrl:(NSString *)aMusicUrl
musicDataUrl:(NSString *)aMusicDataUrl
title:(NSString *)aTitle
description:(NSString *)aDescription
thumbString:(NSString *)aThumbString
sceneType:(NSInteger *)aSceneType
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSData *aThumbData = [FormatConversion stringToData:aThumbString];
resolve([self getResolveResFromBool:[WXApiRequestHandler sendMusic:aMusicUrl
musicDataUrl:aMusicDataUrl
title:aTitle
description:aDescription
thumbImage:aThumbData
InScene:(enum WXScene)aSceneType]]);
}
RCT_REMAP_METHOD(sendVideo,
videoUrl:(NSString *)aVideoUrl
title:(NSString *)aTitle
description:(NSString *)aDescription
thumbString:(NSString *)aThumbString
sceneType:(NSInteger *)aSceneType
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSData *aThumbData = [FormatConversion stringToData:aThumbString];
resolve([self getResolveResFromBool:[WXApiRequestHandler sendVideo:aVideoUrl
title:aTitle
description:aDescription
thumbImage:aThumbData
InScene:(enum WXScene)aSceneType]]);
}
RCT_REMAP_METHOD(sendLink,
sendLinkString:(NSString *)aLinkString
title:(NSString *)aTitle
description:(NSString *)aDescription
thumbString:(NSString *)aThumbString
sceneType:(NSInteger *)aSceneType
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSData *aThumbData = [FormatConversion stringToData:aThumbString];
resolve([self getResolveResFromBool:[WXApiRequestHandler sendLink:aLinkString
title:aTitle
description:aDescription
thumbImage:aThumbData
InScene:(enum WXScene)aSceneType]]);
}
RCT_REMAP_METHOD(sendMiniProgram,
sendMiniProgramUserName:(NSString *)anUserName
miniProgramType:(NSInteger *)aMiniProgramType
path:(NSString *)aPath
hdThumbString:(NSString *)aHdThumbString
title:(NSString *)aTitle
description:(NSString *)aDescription
webpageUrl:(NSString *)aWebpageUrl
thumbString:(NSString *)aThumbString
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
//
NSData *aThumbData = [FormatConversion stringToData:aThumbString];
NSData *aHdThumbData = [FormatConversion stringToData:aHdThumbString];
resolve([self getResolveResFromBool:[WXApiRequestHandler sendMiniProgram:anUserName
miniProgramType:(WXMiniProgramType)aMiniProgramType
path:aPath
hdThumbImage:aHdThumbData
title:aTitle
description:aDescription
webpageUrl:aWebpageUrl
thumbImage:aThumbData]]);
}
#pragma Pay
RCT_REMAP_METHOD(pay,
payWithAppId:(NSString *)anAppId
partnerId:(NSString *)aPartnerId
prepayId:(NSString *)aPrepayId
nonceStr:(NSString *)aNonceStr
timeStamp:(nonnull NSNumber *)aTimeStamp
package:(NSString *)aPackage
sign:(NSString *)aSign
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
resolve([self getResolveResFromBool:[WXApiRequestHandler pay:aPartnerId
prepayId:aPrepayId
nonceStr:aNonceStr
timeStamp:[aTimeStamp unsignedIntValue]
package:aPackage
sign:aSign]]);
}
#pragma WXApiDelegate
// sendReq
- (void)onResp:(BaseResp *)resp {
NSMutableDictionary *body = @{}.mutableCopy;
body[@"errCode"] = @(resp.errCode);
ASSIGN_EMPTY_STRING(body[@"errStr"], resp.errStr)
if ([resp isKindOfClass:[SendAuthResp class]]) {
//
SendAuthResp *authResp = (SendAuthResp *)resp;
body[@"eventType"] = @"SendAuthResp";
ASSIGN_EMPTY_STRING(body[@"code"], authResp.code)
ASSIGN_EMPTY_STRING(body[@"state"], authResp.state)
ASSIGN_EMPTY_STRING(body[@"lang"], authResp.lang)
ASSIGN_EMPTY_STRING(body[@"country"], authResp.country)
} else if ([resp isKindOfClass:[SendMessageToWXResp class]]) {
//
SendMessageToWXResp *messageResp = (SendMessageToWXResp *)resp;
body[@"eventType"] = @"SendMessageToWXResp";
ASSIGN_EMPTY_STRING(body[@"lang"], messageResp.lang)
ASSIGN_EMPTY_STRING(body[@"country"], messageResp.country)
} else if ([resp isKindOfClass:[PayResp class]]) {
//
PayResp *payResp = (PayResp *)resp;
body[@"eventType"] = @"PayResp";
ASSIGN_EMPTY_STRING(body[@"returnKey"], payResp.returnKey);
}
[self sendEvent:body];
}
// sendResp
- (void)onReq:(BaseReq *)req {
// TODO:
// if ([req isKindOfClass:[GetMessageFromWXReq class]]) {
// GetMessageFromWXReq *getMessageReq = (GetMessageFromWXReq *)req;
// } else if ([req isKindOfClass:[ShowMessageFromWXReq class]]) {
// ShowMessageFromWXReq *showMessageReq = (ShowMessageFromWXReq *)req;
// } else if ([req isKindOfClass:[LaunchFromWXReq class]]) {
// LaunchFromWXReq *launchReq = (LaunchFromWXReq *)req;
// }
}
- (NSNumber *)getResolveResFromBool:(BOOL)boolValue
{
return [NSNumber numberWithBool:boolValue];
}
#pragma event
- (NSArray<NSString *> *)supportedEvents
{
return @[RNWechatEventName];
@@ -54,195 +313,13 @@ RCT_EXPORT_MODULE()
[self sendEventWithName:RNWechatEventName body:body];
}
- (dispatch_queue_t)methodQueue
#pragma wxapi handle url
- (BOOL)openURL:(NSNotification *)aNotification
{
return dispatch_get_main_queue();
}
+ (BOOL)requiresMainQueueSetup
{
return YES;
}
#pragma react-native-methods
RCT_REMAP_METHOD(registerApp,
appId:(NSString *)appId
isDebug:(NSString *)isDebug
registerAppResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
if(![appId isEqualToString:@""]) {
if ([isDebug isEqualToString:@"true"]) {
[WXApi startLogByLevel:WXLogLevelDetail logBlock:^(NSString *log) {
NSLog(@"WXApi: %@", log);
}];
}
_isWXApiRegisteSuccess = [WXApi registerApp:appId];
if (_isWXApiRegisteSuccess) {
NSLog(@"WXApi register success. appId: %@", appId);
} else {
NSLog(@"WXApi register failed. appId: %@", appId);
}
} else {
NSLog(@"There is no appId for WXApi.");
}
resolve([RNWechat getOperateResult:_isWXApiRegisteSuccess]);
}
RCT_REMAP_METHOD(isWXApiRegisteSuccess,
isWXApiRegisteSuccessWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
resolve([RNWechat getOperateResult:_isWXApiRegisteSuccess]);
}
RCT_REMAP_METHOD(isWXAppInstalled,
isWXAppInstalledWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
resolve([RNWechat getOperateResult:[WXApi isWXAppInstalled]]);
}
RCT_REMAP_METHOD(sendAuthRequestScope,
sendAuthRequestScope:(NSString *)scope
State:(NSString *)state
OpenID:(NSString *)openID
Resolver:(RCTPromiseResolveBlock)resolve
Rejecter:(RCTPromiseRejectBlock)reject)
{
resolve([RNWechat getOperateResult:[WXApiRequestHandler sendAuthRequestScope:scope State:state OpenID:openID]]);
}
RCT_REMAP_METHOD(sendText,
sendText:(NSString *)text
SceneType:(NSInteger)sceneType
Resolver:(RCTPromiseResolveBlock)resolve
Rejecter:(RCTPromiseRejectBlock)reject)
{
resolve([RNWechat getOperateResult:[WXApiRequestHandler sendText:text InScene:(enum WXScene)sceneType]]);
}
RCT_REMAP_METHOD(sendLinkURL,
sendLinkURL:(NSString *)urlString
Title:(NSString *)title
Description:(NSString *)description
ThumbImageUrlString:(NSString *)thumbImageUrlString
SceneType:(NSInteger)sceneType
Resolver:(RCTPromiseResolveBlock)resolve
Rejecter:(RCTPromiseRejectBlock)reject)
{
UIImage *thumbImage = [Utils imageUrlString:thumbImageUrlString toImageWithSize:CGSizeMake(100.0, 100.0)];
resolve([RNWechat getOperateResult:[WXApiRequestHandler
sendLinkURL:urlString
TagName:@""
Title:title
Description:description
ThumbImage:thumbImage
InScene:(enum WXScene)sceneType ]]);
}
RCT_REMAP_METHOD(sendMiniProgramWebpageUrl,
sendMiniProgramWebpageUrl:(NSString *)webpageUrl
userName:(NSString *)userName
path:(NSString *)path
title:(NSString *)title
Description:(NSString *)description
ThumbImageUrlString:(NSString *)thumbImageUrlString
hdImageUrlString:(NSString *)hdImageUrlString
miniProgramType:(NSInteger)programType
Resolver:(RCTPromiseResolveBlock)resolve
Rejecter:(RCTPromiseRejectBlock)reject)
{
//
UIImage *thumbImage = [Utils imageUrlString:thumbImageUrlString toImageWithSize:CGSizeMake(100.0, 100.0)];
NSData *hdImageData = [Utils imageUrlStringToData:hdImageUrlString];
resolve([RNWechat getOperateResult:[WXApiRequestHandler
sendMiniProgramWebpageUrl:webpageUrl
userName:userName path:path
title:title
Description:description
ThumbImage:thumbImage
hdImageData:hdImageData
withShareTicket:YES
miniProgramType:(WXMiniProgramType)programType
InScene:WXSceneSession ]]);
}
#pragma mark - WXApiDelegate
- (void)onResp:(BaseResp *)resp {
NSMutableDictionary *body = @{}.mutableCopy;
body[@"errCode"] = @(resp.errCode);
ASSIGN_EMPTY_STRING(body[@"errStr"], resp.errStr)
if ([resp isKindOfClass:[SendMessageToWXResp class]]) {
//
SendMessageToWXResp *messageResp = (SendMessageToWXResp *)resp;
body[@"eventType"] = @"SendMessageToWXResp";
ASSIGN_EMPTY_STRING(body[@"lang"], messageResp.lang)
ASSIGN_EMPTY_STRING(body[@"country"], messageResp.country)
} else if ([resp isKindOfClass:[SendAuthResp class]]) {
//
SendAuthResp *authResp = (SendAuthResp *)resp;
body[@"eventType"] = @"SendAuthResp";
ASSIGN_EMPTY_STRING(body[@"code"], authResp.code)
ASSIGN_EMPTY_STRING(body[@"state"], authResp.state)
ASSIGN_EMPTY_STRING(body[@"lang"], authResp.lang)
ASSIGN_EMPTY_STRING(body[@"country"], authResp.country)
} else if ([resp isKindOfClass:[AddCardToWXCardPackageResp class]]) {
//
AddCardToWXCardPackageResp *addCardResp = (AddCardToWXCardPackageResp *)resp;
body[@"eventType"] = @"AddCardToWXCardPackageResp";
ASSIGN_EMPTY_STRING(body[@"cardAry"], addCardResp.cardAry)
} else if ([resp isKindOfClass:[WXChooseCardResp class]]) {
//
WXChooseCardResp *chooseCardResp = (WXChooseCardResp *)resp;
body[@"eventType"] = @"WXChooseCardResp";
ASSIGN_EMPTY_STRING(body[@"cardAry"], chooseCardResp.cardAry)
} else if ([resp isKindOfClass:[WXChooseInvoiceResp class]]){
//
WXChooseInvoiceResp *chooseInvoiceResp = (WXChooseInvoiceResp *)resp;
body[@"eventType"] = @"WXChooseInvoiceResp";
ASSIGN_EMPTY_STRING(body[@"cardAry"], chooseInvoiceResp.cardAry)
} else if ([resp isKindOfClass:[WXSubscribeMsgResp class]]){
//
WXSubscribeMsgResp *subscribeMsgResp = (WXSubscribeMsgResp *)resp;
body[@"eventType"] = @"WXSubscribeMsgResp";
ASSIGN_EMPTY_STRING(body[@"templateId"], subscribeMsgResp.templateId)
// subscribeMsgResp.scene
ASSIGN_EMPTY_STRING(body[@"action"], subscribeMsgResp.action)
ASSIGN_EMPTY_STRING(body[@"reserved"], subscribeMsgResp.reserved)
ASSIGN_EMPTY_STRING(body[@"openId"], subscribeMsgResp.openId)
} else if ([resp isKindOfClass:[WXLaunchMiniProgramResp class]]){
//
WXLaunchMiniProgramResp *launchMiniProgramResp = (WXLaunchMiniProgramResp *)resp;
body[@"eventType"] = @"WXLaunchMiniProgramResp";
ASSIGN_EMPTY_STRING(body[@"extMsg"], launchMiniProgramResp.extMsg)
} else if([resp isKindOfClass:[WXInvoiceAuthInsertResp class]]){
WXInvoiceAuthInsertResp *invoiceAuthInsertResp = (WXInvoiceAuthInsertResp *)resp;
body[@"eventType"] = @"WXInvoiceAuthInsertResp";
ASSIGN_EMPTY_STRING(body[@"wxOrderId"], invoiceAuthInsertResp.wxOrderId)
} else if([resp isKindOfClass:[WXNontaxPayResp class]]){
WXNontaxPayResp *nontaxPayResp = (WXNontaxPayResp *)resp;
body[@"eventType"] = @"WXNontaxPayResp";
ASSIGN_EMPTY_STRING(body[@"wxOrderId"], nontaxPayResp.wxOrderId)
} else if ([resp isKindOfClass:[WXPayInsuranceResp class]]){
WXPayInsuranceResp *payInsuranceResp = (WXPayInsuranceResp *)resp;
body[@"eventType"] = @"WXPayInsuranceResp";
ASSIGN_EMPTY_STRING(body[@"wxOrderId"], payInsuranceResp.wxOrderId)
}
[self sendEvent:body];
}
- (void)onReq:(BaseReq *)req {
// if ([req isKindOfClass:[GetMessageFromWXReq class]]) {
// GetMessageFromWXReq *getMessageReq = (GetMessageFromWXReq *)req;
// } else if ([req isKindOfClass:[ShowMessageFromWXReq class]]) {
// ShowMessageFromWXReq *showMessageReq = (ShowMessageFromWXReq *)req;
// } else if ([req isKindOfClass:[LaunchFromWXReq class]]) {
// LaunchFromWXReq *launchReq = (LaunchFromWXReq *)req;
// }
NSURL *aURL = [NSURL URLWithString:[aNotification userInfo][@"url"]];
return [WXApi handleOpenURL:aURL delegate:self];
}
@end

View File

@@ -1,21 +0,0 @@
Pod::Spec.new do |s|
s.name = "RNWechat"
s.version = "1.0.0"
s.summary = "react native wechat"
s.description = <<-DESC
react native for wechat
DESC
s.homepage = ""
s.license = "MIT"
s.author = { "dongdayu" => "g592842897@gmail.com" }
s.platform = :ios, "7.0"
s.source = { :git => "https://github.com/yyyyu/react-native-wechat.git", :tag => "master" }
s.source_files = "RNWechat.{h,m}"
s.requires_arc = true
s.dependency "React"
s.dependency "WechatOpenSDK"
end

View File

@@ -7,13 +7,12 @@
objects = {
/* Begin PBXBuildFile section */
362DF4D5204FE823009D01D3 /* Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = 362DF4D4204FE823009D01D3 /* Utils.m */; };
368AFA5D204D29FB00ABB362 /* libWeChatSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 368AFA5A204D29FB00ABB362 /* libWeChatSDK.a */; };
368AFA60204D399A00ABB362 /* WXApiRequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 368AFA5F204D399A00ABB362 /* WXApiRequestHandler.m */; };
368AFA66204D3A2400ABB362 /* SendMessageToWXReq+requestWithTextOrMediaMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 368AFA65204D3A2400ABB362 /* SendMessageToWXReq+requestWithTextOrMediaMessage.m */; };
368AFA69204D3A3000ABB362 /* WXMediaMessage+messageConstruct.m in Sources */ = {isa = PBXBuildFile; fileRef = 368AFA68204D3A3000ABB362 /* WXMediaMessage+messageConstruct.m */; };
368AFA6B204D3A7E00ABB362 /* WXApiResponseHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 368AFA6A204D3A7E00ABB362 /* WXApiResponseHandler.m */; };
368AFA6F204D3A8D00ABB362 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 368AFA6E204D3A8D00ABB362 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.m */; };
3652D3C0208EE14E0083981A /* libWeChatSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3652D3BB208EE14E0083981A /* libWeChatSDK.a */; };
36761B1420946760001012B9 /* WXMediaMessage+construct.m in Sources */ = {isa = PBXBuildFile; fileRef = 36761B1320946760001012B9 /* WXMediaMessage+construct.m */; };
36761B1720946ABB001012B9 /* FormatConversion.m in Sources */ = {isa = PBXBuildFile; fileRef = 36761B1620946ABB001012B9 /* FormatConversion.m */; };
36761B5C20948051001012B9 /* WXApiRequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 36761B5820948051001012B9 /* WXApiRequestHandler.m */; };
36761B5D20948051001012B9 /* WXApiResponseHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 36761B5B20948051001012B9 /* WXApiResponseHandler.m */; };
36761B60209481D0001012B9 /* SendMessageToWXReq+requestWithMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 36761B5F209481D0001012B9 /* SendMessageToWXReq+requestWithMessage.m */; };
B3E7B58A1CC2AC0600A0062D /* RNWechat.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNWechat.m */; };
/* End PBXBuildFile section */
@@ -31,22 +30,20 @@
/* Begin PBXFileReference section */
134814201AA4EA6300B7C361 /* libRNWechat.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNWechat.a; sourceTree = BUILT_PRODUCTS_DIR; };
362DF4D4204FE823009D01D3 /* Utils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Utils.m; sourceTree = "<group>"; };
362DF4D6204FEB38009D01D3 /* Utils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Utils.h; sourceTree = "<group>"; };
368AFA59204D29FB00ABB362 /* WechatAuthSDK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WechatAuthSDK.h; path = Wechat/WechatAuthSDK.h; sourceTree = "<group>"; };
368AFA5A204D29FB00ABB362 /* libWeChatSDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libWeChatSDK.a; path = Wechat/libWeChatSDK.a; sourceTree = "<group>"; };
368AFA5B204D29FB00ABB362 /* WXApiObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WXApiObject.h; path = Wechat/WXApiObject.h; sourceTree = "<group>"; };
368AFA5C204D29FB00ABB362 /* WXApi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WXApi.h; path = Wechat/WXApi.h; sourceTree = "<group>"; };
368AFA5E204D399500ABB362 /* WXApiRequestHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WXApiRequestHandler.h; sourceTree = "<group>"; };
368AFA5F204D399A00ABB362 /* WXApiRequestHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WXApiRequestHandler.m; sourceTree = "<group>"; };
368AFA64204D3A1F00ABB362 /* SendMessageToWXReq+requestWithTextOrMediaMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SendMessageToWXReq+requestWithTextOrMediaMessage.h"; sourceTree = "<group>"; };
368AFA65204D3A2400ABB362 /* SendMessageToWXReq+requestWithTextOrMediaMessage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SendMessageToWXReq+requestWithTextOrMediaMessage.m"; sourceTree = "<group>"; };
368AFA67204D3A2D00ABB362 /* WXMediaMessage+messageConstruct.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WXMediaMessage+messageConstruct.h"; sourceTree = "<group>"; };
368AFA68204D3A3000ABB362 /* WXMediaMessage+messageConstruct.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "WXMediaMessage+messageConstruct.m"; sourceTree = "<group>"; };
368AFA6A204D3A7E00ABB362 /* WXApiResponseHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WXApiResponseHandler.m; sourceTree = "<group>"; };
368AFA6C204D3A8100ABB362 /* WXApiResponseHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WXApiResponseHandler.h; sourceTree = "<group>"; };
368AFA6D204D3A8B00ABB362 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "GetMessageFromWXResp+responseWithTextOrMediaMessage.h"; sourceTree = "<group>"; };
368AFA6E204D3A8D00ABB362 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "GetMessageFromWXResp+responseWithTextOrMediaMessage.m"; sourceTree = "<group>"; };
3652D3BB208EE14E0083981A /* libWeChatSDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libWeChatSDK.a; path = SDK/libWeChatSDK.a; sourceTree = "<group>"; };
3652D3BD208EE14E0083981A /* WechatAuthSDK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WechatAuthSDK.h; path = SDK/WechatAuthSDK.h; sourceTree = "<group>"; };
3652D3BE208EE14E0083981A /* WXApi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WXApi.h; path = SDK/WXApi.h; sourceTree = "<group>"; };
3652D3BF208EE14E0083981A /* WXApiObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WXApiObject.h; path = SDK/WXApiObject.h; sourceTree = "<group>"; };
36761B1220946749001012B9 /* WXMediaMessage+construct.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WXMediaMessage+construct.h"; sourceTree = "<group>"; };
36761B1320946760001012B9 /* WXMediaMessage+construct.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "WXMediaMessage+construct.m"; sourceTree = "<group>"; };
36761B1520946A5F001012B9 /* FormatConversion.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FormatConversion.h; sourceTree = "<group>"; };
36761B1620946ABB001012B9 /* FormatConversion.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FormatConversion.m; sourceTree = "<group>"; };
36761B5820948051001012B9 /* WXApiRequestHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXApiRequestHandler.m; sourceTree = "<group>"; };
36761B5920948051001012B9 /* WXApiResponseHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXApiResponseHandler.h; sourceTree = "<group>"; };
36761B5A20948051001012B9 /* WXApiRequestHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXApiRequestHandler.h; sourceTree = "<group>"; };
36761B5B20948051001012B9 /* WXApiResponseHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXApiResponseHandler.m; sourceTree = "<group>"; };
36761B5E2094810A001012B9 /* SendMessageToWXReq+requestWithMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SendMessageToWXReq+requestWithMessage.h"; sourceTree = "<group>"; };
36761B5F209481D0001012B9 /* SendMessageToWXReq+requestWithMessage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SendMessageToWXReq+requestWithMessage.m"; sourceTree = "<group>"; };
B3E7B5881CC2AC0600A0062D /* RNWechat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNWechat.h; sourceTree = "<group>"; };
B3E7B5891CC2AC0600A0062D /* RNWechat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNWechat.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -56,7 +53,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
368AFA5D204D29FB00ABB362 /* libWeChatSDK.a in Frameworks */,
3652D3C0208EE14E0083981A /* libWeChatSDK.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -74,10 +71,10 @@
36751C7D204EA21300E6C291 /* Handler */ = {
isa = PBXGroup;
children = (
368AFA5E204D399500ABB362 /* WXApiRequestHandler.h */,
368AFA5F204D399A00ABB362 /* WXApiRequestHandler.m */,
368AFA6C204D3A8100ABB362 /* WXApiResponseHandler.h */,
368AFA6A204D3A7E00ABB362 /* WXApiResponseHandler.m */,
36761B5A20948051001012B9 /* WXApiRequestHandler.h */,
36761B5820948051001012B9 /* WXApiRequestHandler.m */,
36761B5920948051001012B9 /* WXApiResponseHandler.h */,
36761B5B20948051001012B9 /* WXApiResponseHandler.m */,
);
path = Handler;
sourceTree = "<group>";
@@ -85,25 +82,25 @@
36751C7E204EA21C00E6C291 /* Helper */ = {
isa = PBXGroup;
children = (
368AFA64204D3A1F00ABB362 /* SendMessageToWXReq+requestWithTextOrMediaMessage.h */,
368AFA65204D3A2400ABB362 /* SendMessageToWXReq+requestWithTextOrMediaMessage.m */,
368AFA6D204D3A8B00ABB362 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.h */,
368AFA6E204D3A8D00ABB362 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.m */,
368AFA67204D3A2D00ABB362 /* WXMediaMessage+messageConstruct.h */,
368AFA68204D3A3000ABB362 /* WXMediaMessage+messageConstruct.m */,
36761B5E2094810A001012B9 /* SendMessageToWXReq+requestWithMessage.h */,
36761B5F209481D0001012B9 /* SendMessageToWXReq+requestWithMessage.m */,
36761B1220946749001012B9 /* WXMediaMessage+construct.h */,
36761B1320946760001012B9 /* WXMediaMessage+construct.m */,
36761B1520946A5F001012B9 /* FormatConversion.h */,
36761B1620946ABB001012B9 /* FormatConversion.m */,
);
path = Helper;
sourceTree = "<group>";
};
368AFA58204D29DF00ABB362 /* Wechat */ = {
368AFA58204D29DF00ABB362 /* SDK */ = {
isa = PBXGroup;
children = (
368AFA59204D29FB00ABB362 /* WechatAuthSDK.h */,
368AFA5C204D29FB00ABB362 /* WXApi.h */,
368AFA5B204D29FB00ABB362 /* WXApiObject.h */,
368AFA5A204D29FB00ABB362 /* libWeChatSDK.a */,
3652D3BD208EE14E0083981A /* WechatAuthSDK.h */,
3652D3BE208EE14E0083981A /* WXApi.h */,
3652D3BF208EE14E0083981A /* WXApiObject.h */,
3652D3BB208EE14E0083981A /* libWeChatSDK.a */,
);
name = Wechat;
name = SDK;
sourceTree = "<group>";
};
58B511D21A9E6C8500147676 = {
@@ -111,11 +108,9 @@
children = (
B3E7B5881CC2AC0600A0062D /* RNWechat.h */,
B3E7B5891CC2AC0600A0062D /* RNWechat.m */,
362DF4D6204FEB38009D01D3 /* Utils.h */,
362DF4D4204FE823009D01D3 /* Utils.m */,
36751C7D204EA21300E6C291 /* Handler */,
36751C7E204EA21C00E6C291 /* Helper */,
368AFA58204D29DF00ABB362 /* Wechat */,
368AFA58204D29DF00ABB362 /* SDK */,
134814211AA4EA7D00B7C361 /* Products */,
);
sourceTree = "<group>";
@@ -176,13 +171,12 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
368AFA69204D3A3000ABB362 /* WXMediaMessage+messageConstruct.m in Sources */,
368AFA6B204D3A7E00ABB362 /* WXApiResponseHandler.m in Sources */,
368AFA6F204D3A8D00ABB362 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.m in Sources */,
368AFA66204D3A2400ABB362 /* SendMessageToWXReq+requestWithTextOrMediaMessage.m in Sources */,
368AFA60204D399A00ABB362 /* WXApiRequestHandler.m in Sources */,
362DF4D5204FE823009D01D3 /* Utils.m in Sources */,
36761B60209481D0001012B9 /* SendMessageToWXReq+requestWithMessage.m in Sources */,
36761B5C20948051001012B9 /* WXApiRequestHandler.m in Sources */,
36761B1420946760001012B9 /* WXMediaMessage+construct.m in Sources */,
36761B1720946ABB001012B9 /* FormatConversion.m in Sources */,
B3E7B58A1CC2AC0600A0062D /* RNWechat.m in Sources */,
36761B5D20948051001012B9 /* WXApiResponseHandler.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -280,6 +274,7 @@
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Wechat",
"$(PROJECT_DIR)/SDK",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = RNWechat;
@@ -297,6 +292,7 @@
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Wechat",
"$(PROJECT_DIR)/SDK",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = RNWechat;

View File

@@ -136,6 +136,51 @@ typedef void(^WXLogBolock)(NSString * log);
#pragma mark - WXMediaMessage
@class WXMediaMessage;
#ifndef BUILD_WITHOUT_PAY
/*! @brief 第三方向微信终端发起支付的消息结构体
*
*
* @see PayResp
*/
@interface PayReq : BaseReq
/** 商家向财付通申请的商家id */
@property (nonatomic, retain) NSString *partnerId;
/** 预支付订单 */
@property (nonatomic, retain) NSString *prepayId;
/** 随机串,防重发 */
@property (nonatomic, retain) NSString *nonceStr;
/** 时间戳,防重发 */
@property (nonatomic, assign) UInt32 timeStamp;
/** 商家根据财付通文档填写的数据和签名 */
@property (nonatomic, retain) NSString *package;
/** 商家根据微信开放平台文档对数据做的签名 */
@property (nonatomic, retain) NSString *sign;
@end
#endif
#ifndef BUILD_WITHOUT_PAY
#pragma mark - PayResp
/*! @brief 微信终端返回给第三方的关于支付结果的结构体
*
*
*/
@interface PayResp : BaseResp
/** 财付通返回给商家的信息 */
@property (nonatomic, retain) NSString *returnKey;
@end
#endif
#pragma mark - SendAuthReq
/*! @brief 第三方程序向微信终端请求认证的消息结构
*

View File

@@ -1,24 +0,0 @@
//
// Utils.h
// RNWechat
//
// Created by dayu dong on 07/03/2018.
// Copyright © 2018 Facebook. All rights reserved.
//
#ifndef Utils_h
#define Utils_h
#import <UIKit/UIKit.h>
@interface Utils : NSObject
+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)size;
+ (NSData *)imageUrlStringToData:(NSString *)imageUrlString;
+ (UIImage *)imageUrlString:(NSString *)imageUrlString toImageWithSize:(CGSize)size;
@end
#endif /* Utils_h */

View File

@@ -1,45 +0,0 @@
//
// Utils.m
// RNWechat
//
// Created by dayu dong on 07/03/2018.
// Copyright © 2018 Facebook. All rights reserved.
//
#import "Utils.h"
@implementation Utils
+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize
{
// UIGraphicsBeginImageContext(newSize);
// In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
// Pass 1.0 to force exact pixel size.
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
+ (NSData *)imageUrlStringToData:(NSString *)imageUrlString
{
if ([imageUrlString isEqualToString:@""]) {
return nil;
}
NSURL *imageUrl = [NSURL URLWithString:imageUrlString];
NSData *imageData = [[NSData alloc] initWithContentsOfURL:imageUrl];
return imageData;
}
+ (UIImage *)imageUrlString:(NSString *)imageUrlString toImageWithSize:(CGSize)size
{
NSData *imageData = [Utils imageUrlStringToData:imageUrlString];
UIImage *image = nil;
if (imageData != nil) {
image = [Utils imageWithImage:[UIImage imageWithData:imageData] scaledToSize:size];
}
return image;
}
@end

View File

@@ -1,18 +1,32 @@
{
"name": "react-native-wechat",
"version": "1.0.2",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"name": "@yyyyu/react-native-wechat",
"author": "yyyyu <g592842897@gmail.com>",
"version": "2.0.0",
"keywords": [
"react-native",
"wechat"
],
"author": "dongdayu",
"description": "react native for wechat.",
"license": "MIT",
"homepage": "https://github.com/yyyyu/react-native-wechat",
"repository": {
"type": "git",
"url": "git@github.com:yyyyu/react-native-wechat.git"
},
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"postinstall": "node scripts/postinstall"
},
"rnpm": {
"commands": {
"postlink": "node node_modules/@yyyyu/react-native-wechat/scripts/postlink"
}
},
"peerDependencies": {
"react-native": "latest"
"react-native": ">0.50.0"
},
"devDependencies": {
"standard": "^11.0.1"
}
}

40
scripts/file.js Normal file
View File

@@ -0,0 +1,40 @@
const fs = require('fs')
function fileInsert (path, insStr, insSign, avoidDupSign) {
fileReadAndWrite(path, function (data) {
if (avoidDupSign && data.indexOf(avoidDupSign) !== -1) return
const position = data.indexOf(insSign)
return data.slice(0, position) + insStr + data.slice(position)
})
}
function fileReplace (path, search, replace) {
fileReadAndWrite(path, function (data) {
return data.replace(new RegExp(search, 'g'), replace)
})
}
function fileReadAndWrite (path, callback) {
if (!fs.existsSync(path)) return
const encoding = 'utf8'
let data = null
try {
data = fs.readFileSync(path, encoding)
} catch (e) {
return console.error(e)
}
const result = callback(data)
try {
fs.writeFileSync(path, result, encoding)
} catch (e) {
console.error(e)
}
}
module.exports = {
fileInsert,
fileReplace
}

18
scripts/postinstall.js Normal file
View File

@@ -0,0 +1,18 @@
const path = require('path')
const file = require('./file')
const nodeModuleDir = path.dirname(__filename) + '/../../..'
const modifies = {
get reactSpec () {
const avoidDupSign = '# Dependency'
return [
nodeModuleDir + '/react-native/React.podspec',
avoidDupSign + '\n s.subspec "Dependency" do |ss|\n ss.source_files = "React/**/*.h"\n end\n\n ',
's.subspec "Core" do |ss|',
avoidDupSign
]
}
}
file.fileInsert(...modifies.reactSpec)

7
scripts/postlink.js Normal file
View File

@@ -0,0 +1,7 @@
const path = require('path')
const file = require('./file')
const projectDir = path.dirname(__filename) + '/../../../..'
file.fileReplace(projectDir + '/android/settings.gradle', ':@yyyyu/react-native-wechat', ':react-native-wechat')
file.fileReplace(projectDir + '/android/app/build.gradle', ':@yyyyu/react-native-wechat', ':react-native-wechat')

View File

@@ -1,83 +1,82 @@
const WXScopes = {
Base: 'snsapi_base', // 获取用户基本信息
UserInfo: 'snsapi_userinfo', // 获取用户个人信息
/**
* 错误代码
*/
export const WXErrCode = {
Success: 0, // 成功
Common: -1, // 普通错误
UserCancel: -2, // 点击取消返回
SentFail: -3, // 发送失败
AuthDeny: -4, // 授权失败
Unsupport: -5, // 不支持
Ban: -6 // 禁止
}
const WXScenes = {
Session: 0, // 聊天界面
/**
* 全部错误代码
*/
export const ErrCode = {
...WXErrCode,
ActiveSuccess: 1, // 发送请求后通过系统唤起(任务列表选择唤起),无法判断成功失败
RequestFailed: -7, // 请求失败
UnRegisteApi: -8, // 未注册接口
UnInstall: -9, // 未安装微信
UnSupportApi: -10, // 不支持 Api
Unknow: -99 // 未知错误
}
/**
* 授权作用域
* https://open.weixin.qq.com/cgi-bin/showdocument?action=doc&id=open1419317851
*/
export const WXScopes = {
Base: 'snsapi_base', // 基本信息
UserInfo: 'snsapi_userinfo' // 个人信息
}
/**
* 会话场景
*/
export const WXScenes = {
Session: 0, // 聊天
Timeline: 1, // 朋友圈
Favorite: 2, // 收藏
Favorite: 2 // 收藏
}
const WXMiniProgramTypes = {
Release: 0, // 正式版
Test: 1, // 开发版
Preview: 2, // 体验版
/**
* 小程序类型
*/
export const WXMiniProgramTypes = {
Release: 0, // 正式版
Test: 1, // 开发版
Preview: 2 // 体验版
}
const WXErrCode = {
Success: 0, // 成功
AppActiveSuccess: 1, // 应用唤起返回无法判断成功失败**非微信提供错误类型**
Common: -1, // 普通错误类型
UserCancel: -2, // 用户点击取消并返回
SentFail: -3, // 发送失败
AuthDeny: -4, // 授权失败
Unsupport: -5, // 微信不支持
/**
* 微信应答类型
*/
export const WXRespType = {
Auth: 'SendAuthResp',
Message: 'SendMessageToWXResp',
Pay: 'PayResp'
}
const UserErrs = {
// 微信错误并附带错误提示
Success: {
errCode: 0,
errMsg: '',
},
Common: {
errCode: -1,
errMsg: '微信普通错误',
},
UserCancel: {
errCode: -2,
errMsg: '用户取消并返回',
},
SentFail: {
errCode: -3,
errMsg: '微信响应发送失败',
},
AuthDeny: {
errCode: -4,
errMsg: '微信响应授权失败',
},
Unsupport: {
errCode: -5,
errMsg: '微信不支持',
},
// 其它可能会产生的错误
AppActiveSuccess: {
errCode: 1,
errMsg: '应用唤起返回无法判断成功失败',
},
Uninstall: {
errCode: -6,
errMsg: '当前设备未安装微信',
},
ApiUnregiste: {
errCode: -7,
errMsg: '微信Api未注册',
},
RequestSentFail: {
errCode: -8,
errMsg: '向微信发送请求失败',
},
Unknow: {
errCode: -9,
errMsg: '未知错误',
},
}
export {
WXScopes,
WXScenes,
WXMiniProgramTypes,
WXErrCode,
UserErrs,
/**
* 错误信息
*/
export const Errors = {
// 微信 sdk
Success: { errCode: ErrCode.Success, errMsg: '' },
Common: { errCode: ErrCode.Common, errMsg: '出错' },
UserCancel: { errCode: ErrCode.UserCancel, errMsg: '取消' },
SentFail: { errCode: ErrCode.UserCancel, errMsg: '请求失败' },
AuthDeny: { errCode: ErrCode.AuthDeny, errMsg: '授权失败' },
Unsupport: { errCode: ErrCode.Unsupport, errMsg: '不支持' },
Ban: { errCode: ErrCode.Ban, errMsg: '禁止' },
// 其它
ActiveSuccess: { errCode: ErrCode.ActiveSuccess, errMsg: '' }, // 发送请求后通过系统唤起(任务列表选择唤起),无法判断成功失败
RequestFailed: { errCode: ErrCode.RequestFailed, errMsg: '发送失败' }, // 发送请求失败
UnRegisteApi: { errCode: ErrCode.UnRegisteApi, errMsg: 'Api未注册' },
UnInstall: { errCode: ErrCode.UnInstall, errMsg: '未安装微信' },
UnSupportApi: { errCode: ErrCode.UnSupportApi, errMsg: '微信不支持Api' },
Unknow: { errCode: ErrCode.Unknow, errMsg: '未知错误' }
}

View File

@@ -1,12 +1,262 @@
import { NativeModules, NativeEventEmitter, AppState } from 'react-native'
import { getWXScope, getWXScene, getWXMiniProgramType } from './util'
import { WXErrCode, UserErrs } from './const'
import { NativeModules, NativeEventEmitter, AppState, Platform } from 'react-native'
import { WXRespType, ErrCode, Errors } from './const'
import { getWXScope, getWXScene, getWXMiniProgramType, resolveImageAsset } from './util'
/**
* 注册
* @param {String} appId
* @param {Boolean} [isDebug=false}]
* @return {Promise}
*/
export const registerApp = ({ appId, isDebug = false }) => {
return RNWechat.registerApp(appId, isDebug)
}
/**
* 检测是否安装微信
* @return {Boolean}
*/
export const isWXAppInstalled = () => RNWechat.isWXAppInstalled()
/**
* 当前版本微信是否支持 OpenApi
* @return {Boolean}
*/
export const isWXAppSupportApi = () => RNWechat.isWXAppSupportApi()
/**
* 获取微信的itunes安装地址 iosOnly
* @return {String}
*/
export const getWXAppInstallUrl = () =>
Platform.OS === 'ios' ? RNWechat.getWXAppInstallUrl() : null
/**
* 打开微信
* @return {Boolean}
*/
export const openWXApp = async () => {
await checkWechatModuleIsEnable()
return RNWechat.openWXApp()
}
/**
* 授权
* @desc 只有 snsapi_userinfo scope 有效
* 是的,你没看错,不需要 appid微信文档太久不更新了
* @param {String} [state=''] 验证微信信息标识
* @return {Object}
*/
export const sendAuthRequest = async ({ state = '' }) => {
await checkWechatModuleIsEnable()
if (
!await RNWechat.sendAuthRequest(getWXScope('userinfo'), state)
) throw new WechatError(Errors.RequestFailed)
return listenAndHandleWechatResponse(WXRespType.Auth)
}
/**
* 文字
* @param {String} text 文字
* @param {'session' | 'timeline' | 'favorite'} [scene='session' }] 场景
* @return {Object}
*/
export const sendText = async ({
text,
scene = 'session'
}) => {
await checkWechatModuleIsEnable()
if (
!await RNWechat.sendText(text, getWXScene(scene))
) throw new WechatError(Errors.RequestFailed)
return listenAndHandleWechatResponse(WXRespType.Message)
}
/**
* 图片
* @param {String | Number} image 图片
* @param {'session' | 'timeline' | 'favorite'} [scene='session' }] 场景
* @return {Object}
*/
export const sendImage = async ({
image,
scene = 'session'
}) => {
await checkWechatModuleIsEnable()
if (
!await RNWechat.sendImage(resolveImageAsset(image), getWXScene(scene))
) throw new WechatError(Errors.RequestFailed)
return listenAndHandleWechatResponse(WXRespType.Message)
}
/**
* 音乐
* @param {String} music 音乐 url
* @param {String} data 音乐数据 url
* @param {String} title 标题
* @param {String} desc 描述
* @param {String | Number} thumb 缩略图
* @param {'session' | 'timeline' | 'favorite'} [scene='session' }] 场景
* @return {Object}
*/
export const sendMusic = async ({
music,
data,
title,
desc,
thumb,
scene = 'session'
}) => {
await checkWechatModuleIsEnable()
if (
!await RNWechat.sendMusic(
music, data, title, desc, resolveImageAsset(thumb), getWXScene(scene))
) throw new WechatError(Errors.RequestFailed)
return listenAndHandleWechatResponse(WXRespType.Message)
}
/**
* 视频
* @param {String} video 视频 url
* @param {String} title 标题
* @param {String} desc 描述
* @param {String | Number} thumb 缩略图
* @param {'session' | 'timeline' | 'favorite'} [scene='session' }] 场景
* @return {Object}
*/
export const sendVideo = async ({
video,
title,
desc,
thumb,
scene = 'session'
}) => {
await checkWechatModuleIsEnable()
if (
!await RNWechat.sendVideo(
video, title, desc, resolveImageAsset(thumb), getWXScene(scene))
) throw new WechatError(Errors.RequestFailed)
return listenAndHandleWechatResponse(WXRespType.Message)
}
/**
* 链接
* @param {String} link 链接
* @param {String} title 标题
* @param {String} desc 描述
* @param {String} thumb 缩略图
* @param {'session' | 'timeline' | 'favorite'} [scene='session'] 场景
* @return {Object}
*/
export const sendLink = async ({
link,
title,
desc,
thumb,
scene = 'session'
}) => {
await checkWechatModuleIsEnable()
if (
!await RNWechat.sendLink(
link, title, desc, resolveImageAsset(thumb), getWXScene(scene))
) throw new WechatError(Errors.RequestFailed)
return listenAndHandleWechatResponse(WXRespType.Message)
}
/**
* 小程序
* @param {String} username 小程序原始 id
* @param {String} path 小程序页面路径
* @param {String} hdThumb 小程序缩略图
* @param {String} title 标题
* @param {String} desc 描述
* @param {String} link 兼容旧版本 url
* @param {String} thumb 兼容旧版本缩略图
* @param {'test' | 'preview' | 'release'} [type='release'] 小程序类型
* @return {Object}
*/
export const sendMiniProgram = async ({
username,
path,
hdThumb,
title,
desc,
link,
thumb,
type = 'release'
}) => {
await checkWechatModuleIsEnable()
if (
!await RNWechat.sendMiniProgram(
username,
getWXMiniProgramType(type),
path,
resolveImageAsset(hdThumb),
title,
desc,
link,
resolveImageAsset(thumb)
)
) throw new WechatError(Errors.RequestFailed)
return listenAndHandleWechatResponse(WXRespType.Message)
}
/**
* 支付
* @param {String} appId 应用 id androidOnly
* @param {String} partnerId 商家 id
* @param {String} prepayId 预支付订单 id
* @param {String} nonceStr 随机串
* @param {String | Number} timestamp 时间戳
* @param {String} packageSign 财付通签名
* @param {String} sign 微信开放平台签名
* @return {Object}
*/
export const pay = async ({
appId,
partnerId,
prepayId,
nonceStr,
timestamp,
packageSign,
sign
}) => {
await checkWechatModuleIsEnable()
if (
!await RNWechat.pay(
appId,
partnerId,
prepayId,
nonceStr,
parseInt(timestamp),
packageSign,
sign
)
) throw new WechatError(Errors.RequestFailed)
return listenAndHandleWechatResponse(WXRespType.Pay)
}
/**
* 判断微信是否可用
* @desc 为了减少不必要的逻辑,在第一次检测通过后,下次检测直接通过,如果用户在调用一次通过后
* 卸载微信,再次调用,会由微信返回错误信息
* 安卓必须要先注册 api 才能调用其它方法,所以判断接口注册情况放在第一个
* @return {Boolean}
*/
let checkWechatModuleIsEnable = async () => {
if (!await RNWechat.isWXApiRegisteSuccess()) throw new WechatError(Errors.UnRegisteApi)
if (!await isWXAppInstalled()) throw new WechatError(Errors.UnInstall)
if (!await isWXAppSupportApi()) throw new WechatError(Errors.UnSupportApi)
checkWechatModuleIsEnable = () => true
return true
}
const { RNWechat } = NativeModules
// wechat event emitter
const rnWechatEmitter = new NativeEventEmitter(RNWechat)
const rnWechatAddEventListener = listenEventType => {
const WXEmitter = new NativeEventEmitter(RNWechat)
const rnWechatEventListener = listenEventType => {
return new Promise(resolve => {
let subscription = null
// 微信返回事件处理
@@ -19,7 +269,7 @@ const rnWechatAddEventListener = listenEventType => {
const handleAppStateChange = nextAppState => {
if (nextAppState !== 'active') return
clearSubscribe()
resolve(UserErrs.AppActiveSuccess)
resolve(Errors.ActiveSuccess)
}
// 清理事件监听
const clearSubscribe = () => {
@@ -27,178 +277,44 @@ const rnWechatAddEventListener = listenEventType => {
AppState.removeEventListener('change', handleAppStateChange)
}
subscription = rnWechatEmitter.addListener('RNWechatEvent', handleWechatEvent)
subscription = WXEmitter.addListener('RNWechatEvent', handleWechatEvent)
AppState.addEventListener('change', handleAppStateChange)
})
}
// wechat response handler
const handleWechatResponse = response => {
// listen wechat response handler
const listenAndHandleWechatResponse = async event => {
const response = await rnWechatEventListener(event)
const { errCode } = response
if (errCode === WXErrCode.Success) {
if (errCode === ErrCode.Success) {
return response
} else if (errCode === WXErrCode.AppActiveSuccess) {
} else if (errCode === ErrCode.ActiveSuccess) {
return response
} else if (errCode === WXErrCode.Common) {
throw UserErrs.Common
} else if (errCode === WXErrCode.UserCancel) {
throw UserErrs.UserCancel
} else if (errCode === WXErrCode.SentFail) {
throw UserErrs.SentFail
} else if (errCode === WXErrCode.AuthDeny) {
throw UserErrs.AuthDeny
} else if (errCode === WXErrCode.Unsupport) {
throw UserErrs.Unsupport
} else {
throw UserErrs.Unknow
} else if (errCode === ErrCode.Common) {
throw new WechatError(Errors.Common)
} else if (errCode === ErrCode.UserCancel) {
throw new WechatError(Errors.UserCancel)
} else if (errCode === ErrCode.SentFail) {
throw new WechatError(Errors.SentFail)
} else if (errCode === ErrCode.AuthDeny) {
throw new WechatError(Errors.AuthDeny)
} else if (errCode === ErrCode.Unsupport) {
throw new WechatError(Errors.Unsupport)
} else if (errCode === ErrCode.Ban) {
throw new WechatError(Errors.Ban)
}
throw new WechatError(Errors.Unknow)
}
export class WechatError extends Error {
constructor ({ errCode, errMsg }) {
super(errMsg)
this.name = 'WechatError'
this.errCode = errCode
this.errMsg = errMsg
Object.setPrototypeOf(this, WechatError.prototype)
}
}
/**
* 判断微信是否可用
* @return {Promise}
*/
let checkWechatEnable = async () => {
let isWXAppInstalled = await RNWechat.isWXAppInstalled()
if (isWXAppInstalled === 'false') {
throw UserErrs.Uninstall
}
let isWXApiRegisteSuccess = await RNWechat.isWXApiRegisteSuccess()
if (isWXApiRegisteSuccess === 'false') {
throw UserErrs.ApiUnregiste
}
checkWechatEnable = () => true
return true
}
/**
* 注册微信
* @param {String} appId
* @param {Boolean} [isDebug=false}]
* @return {Promise}
*/
const registerApp = async ({
appId,
isDebug = false
}) => {
const res = await RNWechat.registerApp(appId, isDebug ? 'true' : 'false')
return res === 'true'
}
/**
* 发送授权请求
* @param {String} appId appId
* @param {String} state 用于验证微信返回信息
* @param {String} [scope='userinfo'] 授权类型
* @return {Promise}
*/
const sendAuthRequestScope = async ({
appId,
state,
scope = 'userinfo',
}) => {
await checkWechatEnable()
const mScope = getWXScope(scope)
const sendRes = await RNWechat.sendAuthRequestScope(mScope, state, appId)
if (sendRes === 'false') {
throw UserErrs.RequestSentFail
}
const response = await rnWechatAddEventListener('SendAuthResp')
return handleWechatResponse(response)
}
/**
* 发送文字
* @param {String} text 文字
* @param {String} [scene='session' }] 场景
* @return {Promise}
*/
const sendText = async ({
text,
scene = 'session',
}) => {
await checkWechatEnable()
const mScene = getWXScene(scene)
const sendRes = await RNWechat.sendText(text, mScene)
if (sendRes === 'false') {
throw UserErrs.RequestSentFail
}
const response = await rnWechatAddEventListener('SendMessageToWXResp')
return handleWechatResponse(response)
}
/**
* 发送链接
* @param {String} url 点击后跳转的 url
* @param {String} title 标题
* @param {String} desc 描述
* @param {String} thumb 缩略图
* @param {String} [scene='session'] 场景
* @return {Promise}
*/
const sendLinkURL = async ({
url,
title,
desc,
thumb,
scene = 'session',
}) => {
await checkWechatEnable()
const mScene = getWXScene(scene)
const sendRes = await RNWechat.sendLinkURL(url, title, desc, thumb, mScene)
if (sendRes === 'false') {
throw UserErrs.RequestSentFail
}
const response = await rnWechatAddEventListener('SendMessageToWXResp')
return handleWechatResponse(response)
}
/**
* 发送小程序或 url
* @param {String} originId 小程序原始 id
* @param {String} miniPgPath 小程序页面路径
* @param {String} title 标题
* @param {String} desc 描述
* @param {String} hdImage 小程序缩略图
* @param {String} url 旧版本替代用 url
* @param {String} thumb 旧版本替代缩略图
* @param {String} [type='release'] 小程序发布类型
* @return {Promise}
*/
const sendMiniProgramWebpageUrl = async ({
originId,
miniPgPath,
title,
desc,
hdImage,
url,
thumb,
type = 'release',
}) => {
await checkWechatEnable()
const mType = getWXMiniProgramType(type)
const sendRes = await RNWechat.sendMiniProgramWebpageUrl(
url,
originId,
miniPgPath,
title,
desc,
thumb,
hdImage,
mType,
)
if (sendRes === 'false') {
throw UserErrs.RequestSentFail
}
const response = await rnWechatAddEventListener('SendMessageToWXResp')
return handleWechatResponse(response)
}
export default {
registerApp,
sendAuthRequestScope,
sendText,
sendLinkURL,
sendMiniProgramWebpageUrl,
}

View File

@@ -1,61 +1,70 @@
import { Image } from 'react-native'
import { WXScopes, WXScenes, WXMiniProgramTypes } from './const'
/**
* 获取场景
* 获取授权类型
* @param {'base' | 'userinfo'} scope
* @return {Number}
*/
const getWXScene = scene => {
switch (scene) {
case 'session':
return WXScenes.Session
break
case 'timeline':
return WXScenes.Timeline
break
case 'favorite':
return WXScenes.Favorite
break
export const getWXScope = scope => {
switch (scope) {
case 'base':
return WXScopes.Base
case 'userinfo':
return WXScopes.UserInfo
default:
return WXScenes.Session
return WXScopes.Base
}
}
/**
* 获取授权类型
* 获取微信分享场景
* @param {'session' | 'timeline' | 'favorite'} scene
* @return {Number}
*/
const getWXScope = scope => {
switch (scope) {
case 'base':
return WXScopes.Base
break
case 'userinfo':
return WXScopes.UserInfo
break
export const getWXScene = scene => {
switch (scene) {
case 'session':
return WXScenes.Session
case 'timeline':
return WXScenes.Timeline
case 'favorite':
return WXScenes.Favorite
default:
return WXScopes.Base
return WXScenes.Session
}
}
/**
* 获取小程序类型
* @param {'test' | 'preview' | 'release'} type
* @return {Number}
*/
const getWXMiniProgramType = type => {
export const getWXMiniProgramType = type => {
switch (type) {
case 'release':
return WXMiniProgramTypes.Release
break
case 'test':
return WXMiniProgramTypes.Test
break
case 'preview':
return WXMiniProgramTypes.Preview
break
default:
return WXMiniProgramTypes.Release
}
}
export {
getWXScope,
getWXScene,
getWXMiniProgramType,
/**
* resolve 图片资源
* @param {String | Number} asset
*/
export const resolveImageAsset = asset => {
switch (typeof asset) {
case 'number':
const result = Image.resolveAssetSource(asset)
if (result && result.__packager_asset) return result.uri
break
case 'string':
return asset
}
return null
}