diff --git a/.gitignore b/.gitignore index 9cadbfe..a86b4d2 100644 --- a/.gitignore +++ b/.gitignore @@ -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 - \ No newline at end of file + +yarn.lock diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..250008a --- /dev/null +++ b/LICENSE @@ -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. diff --git a/README.md b/README.md index 54d5ffc..cc9ae7e 100644 --- a/README.md +++ b/README.md @@ -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 + + - (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 getPackages() { + return Arrays.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 + + + + + + ``` + +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', // 微信开放平台签名 +}) +``` diff --git a/RNWechat.podspec b/RNWechat.podspec new file mode 100644 index 0000000..7d4d847 --- /dev/null +++ b/RNWechat.podspec @@ -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 diff --git a/android/build.gradle b/android/build.gradle index 39f3eb9..883fd35 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,4 +1,3 @@ - buildscript { repositories { jcenter() diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index d743996..53eacea 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -1,5 +1,6 @@ + package="com.rnlib.wechat"> + diff --git a/android/src/main/java/com/rnlib/wechat/RNWechatModule.java b/android/src/main/java/com/rnlib/wechat/RNWechatModule.java new file mode 100644 index 0000000..f484978 --- /dev/null +++ b/android/src/main/java/com/rnlib/wechat/RNWechatModule.java @@ -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); + } +} diff --git a/android/src/main/java/com/ytanglib/wechat/RNWechatPackage.java b/android/src/main/java/com/rnlib/wechat/RNWechatPackage.java similarity index 96% rename from android/src/main/java/com/ytanglib/wechat/RNWechatPackage.java rename to android/src/main/java/com/rnlib/wechat/RNWechatPackage.java index 117794b..48ce8c9 100644 --- a/android/src/main/java/com/ytanglib/wechat/RNWechatPackage.java +++ b/android/src/main/java/com/rnlib/wechat/RNWechatPackage.java @@ -1,4 +1,4 @@ -package com.ytanglib.wechat; +package com.rnlib.wechat; import com.facebook.react.ReactPackage; import com.facebook.react.bridge.JavaScriptModule; diff --git a/android/src/main/java/com/rnlib/wechat/helper/ActivityHelper.java b/android/src/main/java/com/rnlib/wechat/helper/ActivityHelper.java new file mode 100644 index 0000000..d67a319 --- /dev/null +++ b/android/src/main/java/com/rnlib/wechat/helper/ActivityHelper.java @@ -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); + } +} diff --git a/android/src/main/java/com/rnlib/wechat/helper/FormatConversion.java b/android/src/main/java/com/rnlib/wechat/helper/FormatConversion.java new file mode 100644 index 0000000..4254198 --- /dev/null +++ b/android/src/main/java/com/rnlib/wechat/helper/FormatConversion.java @@ -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); + } +} diff --git a/android/src/main/java/com/rnlib/wechat/helper/SendMessageToWXHelper.java b/android/src/main/java/com/rnlib/wechat/helper/SendMessageToWXHelper.java new file mode 100644 index 0000000..f058fde --- /dev/null +++ b/android/src/main/java/com/rnlib/wechat/helper/SendMessageToWXHelper.java @@ -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; + } +} diff --git a/android/src/main/java/com/rnlib/wechat/helper/WXMediaMessageHelper.java b/android/src/main/java/com/rnlib/wechat/helper/WXMediaMessageHelper.java new file mode 100644 index 0000000..0552989 --- /dev/null +++ b/android/src/main/java/com/rnlib/wechat/helper/WXMediaMessageHelper.java @@ -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; + } +} diff --git a/android/src/main/java/com/ytanglib/wechat/RNWechatModule.java b/android/src/main/java/com/ytanglib/wechat/RNWechatModule.java deleted file mode 100644 index 85c2d35..0000000 --- a/android/src/main/java/com/ytanglib/wechat/RNWechatModule.java +++ /dev/null @@ -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); - } -} diff --git a/android/src/main/java/com/ytanglib/wechat/Utils.java b/android/src/main/java/com/ytanglib/wechat/Utils.java deleted file mode 100644 index ec4c22a..0000000 --- a/android/src/main/java/com/ytanglib/wechat/Utils.java +++ /dev/null @@ -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(); - } - -} diff --git a/index.js b/index.js index c88eff8..1dfa3c9 100644 --- a/index.js +++ b/index.js @@ -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 diff --git a/ios/Handler/WXApiRequestHandler.h b/ios/Handler/WXApiRequestHandler.h index e3630f2..52f33a6 100644 --- a/ios/Handler/WXApiRequestHandler.h +++ b/ios/Handler/WXApiRequestHandler.h @@ -1,110 +1,49 @@ -// -// WXApiManager.h -// SDKSample -// -// Created by Jeason on 15/7/14. -// -// - -#import #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 diff --git a/ios/Handler/WXApiRequestHandler.m b/ios/Handler/WXApiRequestHandler.m index 6b98e40..a5b799f 100644 --- a/ios/Handler/WXApiRequestHandler.m +++ b/ios/Handler/WXApiRequestHandler.m @@ -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 diff --git a/ios/Handler/WXApiResponseHandler.h b/ios/Handler/WXApiResponseHandler.h index 689f5de..1ca6f53 100644 --- a/ios/Handler/WXApiResponseHandler.h +++ b/ios/Handler/WXApiResponseHandler.h @@ -1,55 +1,5 @@ -// -// WXApiResponseManager.h -// SDKSample -// -// Created by Jeason on 15/7/14. -// -// - -#import #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 diff --git a/ios/Handler/WXApiResponseHandler.m b/ios/Handler/WXApiResponseHandler.m index ed35578..fbbb1bf 100644 --- a/ios/Handler/WXApiResponseHandler.m +++ b/ios/Handler/WXApiResponseHandler.m @@ -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 diff --git a/ios/Helper/FormatConversion.h b/ios/Helper/FormatConversion.h new file mode 100644 index 0000000..36a5247 --- /dev/null +++ b/ios/Helper/FormatConversion.h @@ -0,0 +1,16 @@ +#ifndef FormatConversion_h +#define FormatConversion_h + +#import + +@interface FormatConversion : NSObject + ++ (NSData *)stringToData:(NSString *)aString; + ++ (NSData *)uiImageToData:(UIImage *)anUIImage; + ++ (UIImage *)imageString:(NSString *)anImageUrlString toUIImageWithSize:(CGSize)aSize; + +@end + +#endif diff --git a/ios/Helper/FormatConversion.m b/ios/Helper/FormatConversion.m new file mode 100644 index 0000000..9477596 --- /dev/null +++ b/ios/Helper/FormatConversion.m @@ -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 diff --git a/ios/Helper/GetMessageFromWXResp+responseWithTextOrMediaMessage.h b/ios/Helper/GetMessageFromWXResp+responseWithTextOrMediaMessage.h deleted file mode 100644 index 3d483a4..0000000 --- a/ios/Helper/GetMessageFromWXResp+responseWithTextOrMediaMessage.h +++ /dev/null @@ -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 diff --git a/ios/Helper/GetMessageFromWXResp+responseWithTextOrMediaMessage.m b/ios/Helper/GetMessageFromWXResp+responseWithTextOrMediaMessage.m deleted file mode 100644 index e943017..0000000 --- a/ios/Helper/GetMessageFromWXResp+responseWithTextOrMediaMessage.m +++ /dev/null @@ -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 diff --git a/ios/Helper/SendMessageToWXReq+requestWithMessage.h b/ios/Helper/SendMessageToWXReq+requestWithMessage.h new file mode 100644 index 0000000..de9b34c --- /dev/null +++ b/ios/Helper/SendMessageToWXReq+requestWithMessage.h @@ -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 diff --git a/ios/Helper/SendMessageToWXReq+requestWithMessage.m b/ios/Helper/SendMessageToWXReq+requestWithMessage.m new file mode 100644 index 0000000..bb3ae59 --- /dev/null +++ b/ios/Helper/SendMessageToWXReq+requestWithMessage.m @@ -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 diff --git a/ios/Helper/SendMessageToWXReq+requestWithTextOrMediaMessage.h b/ios/Helper/SendMessageToWXReq+requestWithTextOrMediaMessage.h deleted file mode 100644 index 10f064b..0000000 --- a/ios/Helper/SendMessageToWXReq+requestWithTextOrMediaMessage.h +++ /dev/null @@ -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 diff --git a/ios/Helper/SendMessageToWXReq+requestWithTextOrMediaMessage.m b/ios/Helper/SendMessageToWXReq+requestWithTextOrMediaMessage.m deleted file mode 100644 index 446f718..0000000 --- a/ios/Helper/SendMessageToWXReq+requestWithTextOrMediaMessage.m +++ /dev/null @@ -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 diff --git a/ios/Helper/WXMediaMessage+construct.h b/ios/Helper/WXMediaMessage+construct.h new file mode 100644 index 0000000..07fa0f5 --- /dev/null +++ b/ios/Helper/WXMediaMessage+construct.h @@ -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 diff --git a/ios/Helper/WXMediaMessage+construct.m b/ios/Helper/WXMediaMessage+construct.m new file mode 100644 index 0000000..23d5d60 --- /dev/null +++ b/ios/Helper/WXMediaMessage+construct.m @@ -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 diff --git a/ios/Helper/WXMediaMessage+messageConstruct.h b/ios/Helper/WXMediaMessage+messageConstruct.h deleted file mode 100644 index 683ab0d..0000000 --- a/ios/Helper/WXMediaMessage+messageConstruct.h +++ /dev/null @@ -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 diff --git a/ios/Helper/WXMediaMessage+messageConstruct.m b/ios/Helper/WXMediaMessage+messageConstruct.m deleted file mode 100644 index 9fa4150..0000000 --- a/ios/Helper/WXMediaMessage+messageConstruct.m +++ /dev/null @@ -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 diff --git a/ios/RNWechat.h b/ios/RNWechat.h index 58d5352..8e42961 100644 --- a/ios/RNWechat.h +++ b/ios/RNWechat.h @@ -1,16 +1,21 @@ +#if __has_include() #import +#else +#import "RCTBridgeModule.h" +#endif +#if __has_include() #import +#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 -@property (nonatomic) BOOL isWXApiRegisteSuccess; - @end diff --git a/ios/RNWechat.m b/ios/RNWechat.m index cb54b54..f3e6a25 100644 --- a/ios/RNWechat.m +++ b/ios/RNWechat.m @@ -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 *)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 diff --git a/ios/RNWechat.podspec b/ios/RNWechat.podspec deleted file mode 100644 index a84d6f9..0000000 --- a/ios/RNWechat.podspec +++ /dev/null @@ -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 diff --git a/ios/RNWechat.xcodeproj/project.pbxproj b/ios/RNWechat.xcodeproj/project.pbxproj index 38dbd1e..15dc687 100644 --- a/ios/RNWechat.xcodeproj/project.pbxproj +++ b/ios/RNWechat.xcodeproj/project.pbxproj @@ -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 = ""; }; - 362DF4D6204FEB38009D01D3 /* Utils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Utils.h; sourceTree = ""; }; - 368AFA59204D29FB00ABB362 /* WechatAuthSDK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WechatAuthSDK.h; path = Wechat/WechatAuthSDK.h; sourceTree = ""; }; - 368AFA5A204D29FB00ABB362 /* libWeChatSDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libWeChatSDK.a; path = Wechat/libWeChatSDK.a; sourceTree = ""; }; - 368AFA5B204D29FB00ABB362 /* WXApiObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WXApiObject.h; path = Wechat/WXApiObject.h; sourceTree = ""; }; - 368AFA5C204D29FB00ABB362 /* WXApi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WXApi.h; path = Wechat/WXApi.h; sourceTree = ""; }; - 368AFA5E204D399500ABB362 /* WXApiRequestHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WXApiRequestHandler.h; sourceTree = ""; }; - 368AFA5F204D399A00ABB362 /* WXApiRequestHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WXApiRequestHandler.m; sourceTree = ""; }; - 368AFA64204D3A1F00ABB362 /* SendMessageToWXReq+requestWithTextOrMediaMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SendMessageToWXReq+requestWithTextOrMediaMessage.h"; sourceTree = ""; }; - 368AFA65204D3A2400ABB362 /* SendMessageToWXReq+requestWithTextOrMediaMessage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SendMessageToWXReq+requestWithTextOrMediaMessage.m"; sourceTree = ""; }; - 368AFA67204D3A2D00ABB362 /* WXMediaMessage+messageConstruct.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WXMediaMessage+messageConstruct.h"; sourceTree = ""; }; - 368AFA68204D3A3000ABB362 /* WXMediaMessage+messageConstruct.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "WXMediaMessage+messageConstruct.m"; sourceTree = ""; }; - 368AFA6A204D3A7E00ABB362 /* WXApiResponseHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WXApiResponseHandler.m; sourceTree = ""; }; - 368AFA6C204D3A8100ABB362 /* WXApiResponseHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WXApiResponseHandler.h; sourceTree = ""; }; - 368AFA6D204D3A8B00ABB362 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "GetMessageFromWXResp+responseWithTextOrMediaMessage.h"; sourceTree = ""; }; - 368AFA6E204D3A8D00ABB362 /* GetMessageFromWXResp+responseWithTextOrMediaMessage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "GetMessageFromWXResp+responseWithTextOrMediaMessage.m"; sourceTree = ""; }; + 3652D3BB208EE14E0083981A /* libWeChatSDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libWeChatSDK.a; path = SDK/libWeChatSDK.a; sourceTree = ""; }; + 3652D3BD208EE14E0083981A /* WechatAuthSDK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WechatAuthSDK.h; path = SDK/WechatAuthSDK.h; sourceTree = ""; }; + 3652D3BE208EE14E0083981A /* WXApi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WXApi.h; path = SDK/WXApi.h; sourceTree = ""; }; + 3652D3BF208EE14E0083981A /* WXApiObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WXApiObject.h; path = SDK/WXApiObject.h; sourceTree = ""; }; + 36761B1220946749001012B9 /* WXMediaMessage+construct.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WXMediaMessage+construct.h"; sourceTree = ""; }; + 36761B1320946760001012B9 /* WXMediaMessage+construct.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "WXMediaMessage+construct.m"; sourceTree = ""; }; + 36761B1520946A5F001012B9 /* FormatConversion.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FormatConversion.h; sourceTree = ""; }; + 36761B1620946ABB001012B9 /* FormatConversion.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FormatConversion.m; sourceTree = ""; }; + 36761B5820948051001012B9 /* WXApiRequestHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXApiRequestHandler.m; sourceTree = ""; }; + 36761B5920948051001012B9 /* WXApiResponseHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXApiResponseHandler.h; sourceTree = ""; }; + 36761B5A20948051001012B9 /* WXApiRequestHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXApiRequestHandler.h; sourceTree = ""; }; + 36761B5B20948051001012B9 /* WXApiResponseHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXApiResponseHandler.m; sourceTree = ""; }; + 36761B5E2094810A001012B9 /* SendMessageToWXReq+requestWithMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SendMessageToWXReq+requestWithMessage.h"; sourceTree = ""; }; + 36761B5F209481D0001012B9 /* SendMessageToWXReq+requestWithMessage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SendMessageToWXReq+requestWithMessage.m"; sourceTree = ""; }; B3E7B5881CC2AC0600A0062D /* RNWechat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNWechat.h; sourceTree = ""; }; B3E7B5891CC2AC0600A0062D /* RNWechat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNWechat.m; sourceTree = ""; }; /* 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 = ""; @@ -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 = ""; }; - 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 = ""; }; 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 = ""; @@ -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; diff --git a/ios/Wechat/README.txt b/ios/SDK/README.txt similarity index 100% rename from ios/Wechat/README.txt rename to ios/SDK/README.txt diff --git a/ios/Wechat/WXApi.h b/ios/SDK/WXApi.h similarity index 100% rename from ios/Wechat/WXApi.h rename to ios/SDK/WXApi.h diff --git a/ios/Wechat/WXApiObject.h b/ios/SDK/WXApiObject.h similarity index 95% rename from ios/Wechat/WXApiObject.h rename to ios/SDK/WXApiObject.h index a6c282a..8ec14c8 100644 --- a/ios/Wechat/WXApiObject.h +++ b/ios/SDK/WXApiObject.h @@ -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 第三方程序向微信终端请求认证的消息结构 * diff --git a/ios/Wechat/WechatAuthSDK.h b/ios/SDK/WechatAuthSDK.h similarity index 100% rename from ios/Wechat/WechatAuthSDK.h rename to ios/SDK/WechatAuthSDK.h diff --git a/ios/Wechat/libWeChatSDK.a b/ios/SDK/libWeChatSDK.a similarity index 83% rename from ios/Wechat/libWeChatSDK.a rename to ios/SDK/libWeChatSDK.a index dbad6eb..49cdb65 100644 Binary files a/ios/Wechat/libWeChatSDK.a and b/ios/SDK/libWeChatSDK.a differ diff --git a/ios/Utils.h b/ios/Utils.h deleted file mode 100644 index 90fd14e..0000000 --- a/ios/Utils.h +++ /dev/null @@ -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 - -@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 */ diff --git a/ios/Utils.m b/ios/Utils.m deleted file mode 100644 index 0bccbef..0000000 --- a/ios/Utils.m +++ /dev/null @@ -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 diff --git a/package.json b/package.json index b78a8ce..ee7e463 100644 --- a/package.json +++ b/package.json @@ -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 ", + "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" } } diff --git a/scripts/file.js b/scripts/file.js new file mode 100644 index 0000000..296a3ac --- /dev/null +++ b/scripts/file.js @@ -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 +} diff --git a/scripts/postinstall.js b/scripts/postinstall.js new file mode 100644 index 0000000..61fcf19 --- /dev/null +++ b/scripts/postinstall.js @@ -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) diff --git a/scripts/postlink.js b/scripts/postlink.js new file mode 100644 index 0000000..763fb5e --- /dev/null +++ b/scripts/postlink.js @@ -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') diff --git a/src/const.js b/src/const.js index f360dba..4bb9e8c 100644 --- a/src/const.js +++ b/src/const.js @@ -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: '未知错误' } } diff --git a/src/index.js b/src/index.js index 5678b75..3aba6ce 100644 --- a/src/index.js +++ b/src/index.js @@ -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, -} diff --git a/src/util.js b/src/util.js index c6546aa..3795554 100644 --- a/src/util.js +++ b/src/util.js @@ -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 }