├── .github
└── ISSUE_TEMPLATE.md
├── .gitignore
├── .npmignore
├── .travis.yml
├── CODE_OF_CONDUCT.md
├── LICENSE
├── RCTWeChat.podspec
├── README.md
├── _config.yml
├── android
├── build.gradle
├── libs
│ └── libammsdk.jar
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── com
│ └── theweflex
│ └── react
│ ├── WeChatModule.java
│ └── WeChatPackage.java
├── docs
├── build-setup-android.md
└── build-setup-ios.md
├── index.d.ts
├── index.js
├── ios
├── RCTWeChat.h
├── RCTWeChat.m
├── RCTWeChat.podspec
├── RCTWeChat.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ ├── yorkie.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ │ │ └── yorkieliu.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── RCTWeChat.xcscheme
│ │ └── RCTWeChatTests.xcscheme
├── RCTWeChatTests
│ ├── Info.plist
│ └── RCTWeChatTests.m
├── WXApi.h
├── WXApiObject.h
├── WechatAuthSDK.h
└── libWeChatSDK.a
├── package-lock.json
├── package.json
├── playground
├── .buckconfig
├── .eslintrc.js
├── .flowconfig
├── .gitattributes
├── .gitignore
├── .watchmanconfig
├── App.js
├── README.md
├── __tests__
│ └── App-test.js
├── android
│ ├── app
│ │ ├── BUCK
│ │ ├── build.gradle
│ │ ├── build_defs.bzl
│ │ ├── proguard-rules.pro
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── playground
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── MainApplication.java
│ │ │ │ └── wxapi
│ │ │ │ ├── WXEntryActivity.java
│ │ │ │ └── WXPayEntryActivity.java
│ │ │ └── res
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ └── values
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── app.json
├── babel.config.js
├── index.js
├── ios
│ ├── Podfile
│ ├── Podfile.lock
│ ├── playground-tvOS
│ │ └── Info.plist
│ ├── playground-tvOSTests
│ │ └── Info.plist
│ ├── playground.xcodeproj
│ │ ├── project.pbxproj
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ ├── playground-tvOS.xcscheme
│ │ │ └── playground.xcscheme
│ ├── playground.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── playground
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Base.lproj
│ │ │ └── LaunchScreen.xib
│ │ ├── Images.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── Info.plist
│ │ └── main.m
│ └── playgroundTests
│ │ ├── Info.plist
│ │ └── playgroundTests.m
├── metro.config.js
├── package.json
└── yarn.lock
├── qrcode_dingding.jpg
├── qrcode_gitter.jpg
├── qrcode_qq.jpg
├── weixin.png
└── yarn.lock
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Bug report'
3 | labels: bug
4 | assignees: octocat
5 | ---
6 |
7 | Please read and follow the issue templates:
8 |
9 | 1. Bug Report or Documentation Issue or Questions and Help?
10 |
11 | 2. Which `react-native-wechat` version are you using?
12 |
13 | 3. What platform does your issue occur on? (Android/iOS/Both)
14 |
15 | 4. Please provide a clear and concise description of what the bug is as precisely as possible,you can:
16 |
17 | 1) post a screenshot to explain in which case you get the issue?
18 | 2) related `logs`?
19 | 3) show us the code you are using?
20 | 4) others.
21 |
22 | ### Your Environment
23 |
24 | | software | version
25 | | ---------------- | -------
26 | | react-native-wechat | ^ version
27 | | react-native | ^ version
28 | | node | ^ version
29 | | npm or yarn | ^ version
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /android/build
4 | /android/RCTWeChat.iml
5 |
6 | # ios
7 | ios/build
8 |
9 | # Xcode
10 | build/
11 | DerivedData/
12 | xcuserdata
13 | Pods/
14 | *.xcuserstate
15 | *.ipa
16 | *.dSYM.zip
17 | *.dSYM
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | /android/build
3 | /android/RCTWeChat.iml
4 |
5 | Example
6 | *.jpg
7 |
8 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "7.1"
4 | sudo: false
5 | cache:
6 | directories:
7 | - $HOME/.yarn-cache
8 | - $HOME/.gradle/caches/
9 | - $HOME/.gradle/wrapper/
10 | env:
11 | - NODE_ENV='test'
12 | install:
13 | - npm install
14 | script:
15 | - npm test
16 | matrix:
17 | include:
18 | - language: android
19 | os: linux
20 | jdk: oraclejdk8
21 | before_cache:
22 | - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
23 | - rm -fr $HOME/.gradle/caches/*/plugin-resolution/
24 | node_js: false
25 | - nvm install 7
26 | android:
27 | components:
28 | - android-23
29 | - build-tools-23.0.1
30 | - language: objective-c
31 | os: osx
32 | osx_image: xcode8.2
33 | node_js: false
34 | xcode_project: ios/RCTWeChat.xcodeproj
35 | xcode_scheme: ios/RCTWeChat
36 | script:
37 | - cd ios
38 | - xcodebuild -scheme RCTWeChat -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO | xcpretty
39 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at yorkiefixer@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Yazhong Liu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/RCTWeChat.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod spec lint RCTWeChat.podspec' to ensure this is a
3 | # valid spec and to remove all comments including this before submitting the spec.
4 | #
5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
7 | #
8 |
9 | Pod::Spec.new do |s|
10 | s.name = "RCTWeChat"
11 | s.version = "1.9.12"
12 | s.summary = "React-Native(iOS/Android) functionalities include WeChat Login, Share, Favorite and Payment {QQ: 336021910}"
13 | s.description = <<-DESC
14 | React-Native(iOS/Android) functionalities include WeChat Login, Share, Favorite and Payment {QQ: 336021910}
15 | DESC
16 | s.author = { "yorkie" => "yorkiefixer@gmail.com" }
17 | s.homepage = "https://github.com/yorkie/react-native-wechat"
18 | s.license = "MIT"
19 | s.platform = :ios, "9.0"
20 | s.source = { :git => "https://github.com/yorkie/react-native-wechat.git", :tag => "master" }
21 | s.source_files = "ios/*.{h,m}"
22 | s.dependency "React"
23 | s.vendored_libraries = "ios/libWeChatSDK.a"
24 | s.requires_arc = true
25 | s.frameworks = 'SystemConfiguration','CoreTelephony'
26 | s.library = 'sqlite3','c++','z'
27 | end
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # React-Native-Wechat
4 |
5 | [React Native] bridging library that integrates WeChat SDKs:
6 |
7 | - [x] iOS SDK 1.7.2
8 | - [x] Android SDK 221
9 |
10 | [react-native-wechat] has the following tracking data in the open source world:
11 |
12 | | NPM | Dependency | Downloads | Build |
13 | |-----|------------|-----------|-------|
14 | | [![NPM version][npm-image]][npm-url] | [![Dependency Status][david-image]][david-url] | [![Downloads][downloads-image]][downloads-url] | [![Build Status][travis-image]][travis-url] |
15 |
16 | ## Table of Contents
17 |
18 | - [Getting Started](#getting-started)
19 | - [API Documentation](#api-documentation)
20 | - [Installation](#installation)
21 | - [Community](#community)
22 | - [Authors](#authors)
23 | - [License](#license)
24 |
25 | ## Getting Started
26 |
27 | - [Build setup on iOS](./docs/build-setup-ios.md)
28 | - [Build setup on Android](./docs/build-setup-android.md)
29 |
30 | ## API Documentation
31 |
32 | [react-native-wechat] uses Promises, therefore you can use `Promise`
33 | or `async/await` to manage your dataflow.
34 |
35 | #### registerApp(appid)
36 |
37 | - `appid` {String} the appid you get from WeChat dashboard
38 | - returns {Boolean} explains if your application is registered done
39 |
40 | This method should be called once globally.
41 |
42 | ```js
43 | import * as WeChat from 'react-native-wechat';
44 |
45 | WeChat.registerApp('appid');
46 | ```
47 |
48 | #### registerAppWithDescription(appid, description)
49 |
50 | - `appid` {String} the appid you get from WeChat dashboard
51 | - `description` {String} the description of your app
52 | - returns {Boolean} explains if your application is registered done
53 |
54 | This method is only available on iOS.
55 |
56 | #### isWXAppInstalled()
57 |
58 | - returns {Boolean} if WeChat is installed.
59 |
60 | Check if the WeChat app is installed on the device.
61 |
62 | #### isWXAppSupportApi()
63 |
64 | - returns {Boolean} Contains the result.
65 |
66 | Check if wechat support open url.
67 |
68 | #### getApiVersion()
69 |
70 | - returns {String} Contains the result.
71 |
72 | Get the WeChat SDK api version.
73 |
74 | #### openWXApp()
75 |
76 | - returns {Boolean}
77 |
78 | Open the WeChat app from your application.
79 |
80 | #### sendAuthRequest([scope[, state]])
81 |
82 | - `scope` {Array|String} Scopes of auth request.
83 | - `state` {String} the state of OAuth2
84 | - returns {Object}
85 |
86 | Send authentication request, and it returns an object with the
87 | following fields:
88 |
89 | | field | type | description |
90 | |---------|--------|-------------------------------------|
91 | | errCode | Number | Error Code |
92 | | errStr | String | Error message if any error occurred |
93 | | openId | String | |
94 | | code | String | Authorization code |
95 | | url | String | The URL string |
96 | | lang | String | The user language |
97 | | country | String | The user country |
98 |
99 | #### class `ShareMetadata`
100 |
101 | - `title` {String} title of this message.
102 | - `type` {Number} type of this message. Can be {news|text|imageUrl|imageFile|imageResource|video|audio|file}
103 | - `thumbImage` {String} Thumb image of the message, which can be a uri or a resource id.
104 | - `description` {String} The description about the sharing.
105 | - `webpageUrl` {String} Required if type equals `news`. The webpage link to share.
106 | - `imageUrl` {String} Provide a remote image if type equals `image`.
107 | - `videoUrl` {String} Provide a remote video if type equals `video`.
108 | - `musicUrl` {String} Provide a remote music if type equals `audio`.
109 | - `filePath` {String} Provide a local file if type equals `file`.
110 | - `fileExtension` {String} Provide the file type if type equals `file`.
111 |
112 | #### shareToTimeline(message)
113 |
114 | - `message` {ShareMetadata} This object saves the metadata for sharing
115 | - returns {Object}
116 |
117 | Share a `ShareMetadata` message to timeline(朋友圈) and returns:
118 |
119 | | name | type | description |
120 | |---------|--------|-------------------------------------|
121 | | errCode | Number | 0 if authorization successed |
122 | | errStr | String | Error message if any error occurred |
123 |
124 | The following examples require the 'react-native-chat' and 'react-native-fs' packages.
125 |
126 | ```js
127 | import * as WeChat from 'react-native-wechat';
128 | import fs from 'react-native-fs';
129 | let resolveAssetSource = require('resolveAssetSource');
130 |
131 | // Code example to share text message:
132 | try {
133 | let result = await WeChat.shareToTimeline({
134 | type: 'text',
135 | description: 'hello, wechat'
136 | });
137 | console.log('share text message to time line successful:', result);
138 | } catch (e) {
139 | if (e instanceof WeChat.WechatError) {
140 | console.error(e.stack);
141 | } else {
142 | throw e;
143 | }
144 | }
145 |
146 | // Code example to share image url:
147 | // Share raw http(s) image from web will always fail with unknown reason, please use image file or image resource instead
148 | try {
149 | let result = await WeChat.shareToTimeline({
150 | type: 'imageUrl',
151 | title: 'web image',
152 | description: 'share web image to time line',
153 | mediaTagName: 'email signature',
154 | messageAction: undefined,
155 | messageExt: undefined,
156 | imageUrl: 'http://www.ncloud.hk/email-signature-262x100.png'
157 | });
158 | console.log('share image url to time line successful:', result);
159 | } catch (e) {
160 | if (e instanceof WeChat.WechatError) {
161 | console.error(e.stack);
162 | } else {
163 | throw e;
164 | }
165 | }
166 |
167 | // Code example to share image file:
168 | try {
169 | let rootPath = fs.DocumentDirectoryPath;
170 | let savePath = rootPath + '/email-signature-262x100.png';
171 | console.log(savePath);
172 |
173 | /*
174 | * savePath on iOS may be:
175 | * /var/mobile/Containers/Data/Application/B1308E13-35F1-41AB-A20D-3117BE8EE8FE/Documents/email-signature-262x100.png
176 | *
177 | * savePath on Android may be:
178 | * /data/data/com.wechatsample/files/email-signature-262x100.png
179 | **/
180 | await fs.downloadFile('http://www.ncloud.hk/email-signature-262x100.png', savePath);
181 | let result = await WeChat.shareToTimeline({
182 | type: 'imageFile',
183 | title: 'image file download from network',
184 | description: 'share image file to time line',
185 | mediaTagName: 'email signature',
186 | messageAction: undefined,
187 | messageExt: undefined,
188 | imageUrl: "file://" + savePath // require the prefix on both iOS and Android platform
189 | });
190 | console.log('share image file to time line successful:', result);
191 | } catch (e) {
192 | if (e instanceof WeChat.WechatError) {
193 | console.error(e.stack);
194 | } else {
195 | throw e;
196 | }
197 | }
198 |
199 | // Code example to share image resource:
200 | try {
201 | let imageResource = require('./email-signature-262x100.png');
202 | let result = await WeChat.shareToTimeline({
203 | type: 'imageResource',
204 | title: 'resource image',
205 | description: 'share resource image to time line',
206 | mediaTagName: 'email signature',
207 | messageAction: undefined,
208 | messageExt: undefined,
209 | imageUrl: resolveAssetSource(imageResource).uri
210 | });
211 | console.log('share resource image to time line successful', result);
212 | }
213 | catch (e) {
214 | if (e instanceof WeChat.WechatError) {
215 | console.error(e.stack);
216 | } else {
217 | throw e;
218 | }
219 | }
220 |
221 | // Code example to download an word file from web, then share it to WeChat session
222 | // only support to share to session but time line
223 | // iOS code use DocumentDirectoryPath
224 | try {
225 | let rootPath = fs.DocumentDirectoryPath;
226 | let fileName = 'signature_method.doc';
227 | /*
228 | * savePath on iOS may be:
229 | * /var/mobile/Containers/Data/Application/B1308E13-35F1-41AB-A20D-3117BE8EE8FE/Documents/signature_method.doc
230 | **/
231 | let savePath = rootPath + '/' + fileName;
232 |
233 | await fs.downloadFile('https://open.weixin.qq.com/zh_CN/htmledition/res/assets/signature_method.doc', savePath);
234 | let result = await WeChat.shareToSession({
235 | type: 'file',
236 | title: fileName, // WeChat app treat title as file name
237 | description: 'share word file to chat session',
238 | mediaTagName: 'word file',
239 | messageAction: undefined,
240 | messageExt: undefined,
241 | filePath: savePath,
242 | fileExtension: '.doc'
243 | });
244 | console.log('share word file to chat session successful', result);
245 | } catch (e) {
246 | if (e instanceof WeChat.WechatError) {
247 | console.error(e.stack);
248 | } else {
249 | throw e;
250 | }
251 | }
252 |
253 | //android code use ExternalDirectoryPath
254 | try {
255 | let rootPath = fs.ExternalDirectoryPath;
256 | let fileName = 'signature_method.doc';
257 | /*
258 | * savePath on Android may be:
259 | * /storage/emulated/0/Android/data/com.wechatsample/files/signature_method.doc
260 | **/
261 | let savePath = rootPath + '/' + fileName;
262 | await fs.downloadFile('https://open.weixin.qq.com/zh_CN/htmledition/res/assets/signature_method.doc', savePath);
263 | let result = await WeChat.shareToSession({
264 | type: 'file',
265 | title: fileName, // WeChat app treat title as file name
266 | description: 'share word file to chat session',
267 | mediaTagName: 'word file',
268 | messageAction: undefined,
269 | messageExt: undefined,
270 | filePath: savePath,
271 | fileExtension: '.doc'
272 | });
273 | console.log('share word file to chat session successful', result);
274 | }
275 | catch (e) {
276 | if (e instanceof WeChat.WechatError) {
277 | console.error(e.stack);
278 | } else {
279 | throw e;
280 | }
281 | }
282 | ```
283 |
284 | #### shareToSession(message)
285 |
286 | - `message` {ShareMetadata} This object saves the metadata for sharing
287 | - returns {Object}
288 |
289 | Similar to `shareToTimeline` but sends the message to a friend or chat group.
290 |
291 | #### pay(payload)
292 |
293 | - `payload` {Object} the payment data
294 | - `partnerId` {String} 商家向财付通申请的商家ID
295 | - `prepayId` {String} 预支付订单ID
296 | - `nonceStr` {String} 随机串
297 | - `timeStamp` {String} 时间戳
298 | - `package` {String} 商家根据财付通文档填写的数据和签名
299 | - `sign` {String} 商家根据微信开放平台文档对数据做的签名
300 | - returns {Object}
301 |
302 | Sends request for proceeding payment, then returns an object:
303 |
304 | | name | type | description |
305 | |---------|--------|-------------------------------------|
306 | | errCode | Number | 0 if authorization successed |
307 | | errStr | String | Error message if any error occurred |
308 |
309 | ## Installation
310 |
311 | ```sh
312 | $ npm install react-native-wechat --save
313 | ```
314 | ## Partners
315 |
316 | [React Native Starter Kit](https://reactnativestarter.com/) - is a mobile starter kit that allows your team to fully focus on development of the features that set your product apart from the competitors instead of building your app from scratch.
317 |
318 | ## Community
319 |
320 | #### IRC
321 |
322 |
323 |
324 | #### Tutorials
325 |
326 | - [react-native-wechat微信组件的使用](http://www.jianshu.com/p/3f424cccb888)
327 | - [超详细React Native实现微信好友/朋友圈分享功能-Android/iOS双平台通用](http://www.jianshu.com/p/ce5439dd1f52)
328 | - [柳轩涤俗 - 微信登录](http://www.cnblogs.com/zhangdw/p/6194345.html)
329 |
330 | #### Who's using it
331 |
332 |
333 |
334 |
335 | ## Authors
336 |
337 | | GitHub | Role | Email |
338 | |---------------|------------|-----------------------|
339 | | [@yorkie] | Author | yorkiefixer@gmail.com |
340 | | [@xing-zheng] | Emeriti | |
341 | | [@tdzl2003] | Emeriti | tdzl2003@gmail.com |
342 |
343 | [@yorkie]: https://github.com/yorkie
344 | [@xing-zheng]: https://github.com/xing-zheng
345 | [@tdzl2003]: https://github.com/tdzl2003
346 |
347 | ## License
348 |
349 | MIT
350 |
351 | [react-native-wechat]: https://github.com/yorkie/react-native-wechat
352 | [npm-image]: https://img.shields.io/npm/v/react-native-wechat.svg?style=flat-square
353 | [npm-url]: https://npmjs.org/package/react-native-wechat
354 | [travis-image]: https://img.shields.io/travis/yorkie/react-native-wechat.svg?style=flat-square
355 | [travis-url]: https://travis-ci.org/yorkie/react-native-wechat
356 | [david-image]: http://img.shields.io/david/yorkie/react-native-wechat.svg?style=flat-square
357 | [david-url]: https://david-dm.org/yorkie/react-native-wechat
358 | [downloads-image]: http://img.shields.io/npm/dm/react-native-wechat.svg?style=flat-square
359 | [downloads-url]: https://npmjs.org/package/react-native-wechat
360 | [React Native]: https://github.com/facebook/react-native
361 | [react-native-cn]: https://github.com/reactnativecn
362 | [WeChat SDK]: https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=1417674108&token=&lang=zh_CN
363 | [Linking Libraries iOS Guidance]: https://developer.apple.com/library/ios/recipes/xcode_help-project_editor/Articles/AddingaLibrarytoaTarget.html
364 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-merlot
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | def safeExtGet(prop, fallback) {
4 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
5 | }
6 |
7 | android {
8 | compileSdkVersion safeExtGet('compileSdkVersion', 23)
9 | buildToolsVersion safeExtGet('buildToolsVersion', '23.0.1')
10 |
11 | defaultConfig {
12 | minSdkVersion safeExtGet('minSdkVersion', 16)
13 | targetSdkVersion safeExtGet('targetSdkVersion', 22)
14 | versionCode 1
15 | versionName "1.0"
16 | ndk {
17 | abiFilters "armeabi-v7a", "x86"
18 | }
19 | }
20 | }
21 |
22 | allprojects {
23 | repositories {
24 | jcenter()
25 | maven { url "$projectDir/../../react-native/android" }
26 | }
27 | }
28 |
29 | dependencies {
30 | api 'com.facebook.react:react-native:+'
31 | api files('libs/libammsdk.jar')
32 | }
33 |
--------------------------------------------------------------------------------
/android/libs/libammsdk.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/android/libs/libammsdk.jar
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/android/src/main/java/com/theweflex/react/WeChatModule.java:
--------------------------------------------------------------------------------
1 | package com.theweflex.react;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.graphics.Bitmap;
6 | import android.net.Uri;
7 | import android.support.annotation.Nullable;
8 |
9 | import com.facebook.common.executors.UiThreadImmediateExecutorService;
10 | import com.facebook.common.internal.Files;
11 | import com.facebook.common.references.CloseableReference;
12 | import com.facebook.common.util.UriUtil;
13 | import com.facebook.datasource.DataSource;
14 | import com.facebook.drawee.backends.pipeline.Fresco;
15 | import com.facebook.imagepipeline.common.ResizeOptions;
16 | import com.facebook.imagepipeline.core.ImagePipeline;
17 | import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
18 | import com.facebook.imagepipeline.image.CloseableImage;
19 | import com.facebook.imagepipeline.request.ImageRequest;
20 | import com.facebook.imagepipeline.request.ImageRequestBuilder;
21 | import com.facebook.react.bridge.Arguments;
22 | import com.facebook.react.bridge.Callback;
23 | import com.facebook.react.bridge.ReactApplicationContext;
24 | import com.facebook.react.bridge.ReactContextBaseJavaModule;
25 | import com.facebook.react.bridge.ReactMethod;
26 | import com.facebook.react.bridge.ReadableMap;
27 | import com.facebook.react.bridge.WritableMap;
28 | import com.facebook.react.modules.core.DeviceEventManagerModule;
29 | import com.tencent.mm.sdk.modelbase.BaseReq;
30 | import com.tencent.mm.sdk.modelbase.BaseResp;
31 | import com.tencent.mm.sdk.modelmsg.SendAuth;
32 | import com.tencent.mm.sdk.modelmsg.SendMessageToWX;
33 | import com.tencent.mm.sdk.modelmsg.WXFileObject;
34 | import com.tencent.mm.sdk.modelmsg.WXImageObject;
35 | import com.tencent.mm.sdk.modelmsg.WXMediaMessage;
36 | import com.tencent.mm.sdk.modelmsg.WXMusicObject;
37 | import com.tencent.mm.sdk.modelmsg.WXTextObject;
38 | import com.tencent.mm.sdk.modelmsg.WXVideoObject;
39 | import com.tencent.mm.sdk.modelmsg.WXWebpageObject;
40 | import com.tencent.mm.sdk.modelpay.PayReq;
41 | import com.tencent.mm.sdk.modelpay.PayResp;
42 | import com.tencent.mm.sdk.openapi.IWXAPI;
43 | import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;
44 | import com.tencent.mm.sdk.openapi.WXAPIFactory;
45 |
46 | import java.io.File;
47 | import java.net.URI;
48 | import java.util.ArrayList;
49 | import java.util.UUID;
50 |
51 | /**
52 | * Created by tdzl2_000 on 2015-10-10.
53 | */
54 | public class WeChatModule extends ReactContextBaseJavaModule implements IWXAPIEventHandler {
55 | private String appId;
56 |
57 | private IWXAPI api = null;
58 | private final static String NOT_REGISTERED = "registerApp required.";
59 | private final static String INVOKE_FAILED = "WeChat API invoke returns false.";
60 | private final static String INVALID_ARGUMENT = "invalid argument.";
61 |
62 | public WeChatModule(ReactApplicationContext context) {
63 | super(context);
64 | }
65 |
66 | @Override
67 | public String getName() {
68 | return "RCTWeChat";
69 | }
70 |
71 | /**
72 | * fix Native module WeChatModule tried to override WeChatModule for module name RCTWeChat.
73 | * If this was your intention, return true from WeChatModule#canOverrideExistingModule() bug
74 | *
75 | * @return
76 | */
77 | public boolean canOverrideExistingModule() {
78 | return true;
79 | }
80 |
81 | private static ArrayList modules = new ArrayList<>();
82 |
83 | @Override
84 | public void initialize() {
85 | super.initialize();
86 | modules.add(this);
87 | }
88 |
89 | @Override
90 | public void onCatalystInstanceDestroy() {
91 | super.onCatalystInstanceDestroy();
92 | if (api != null) {
93 | api = null;
94 | }
95 | modules.remove(this);
96 | }
97 |
98 | public static void handleIntent(Intent intent) {
99 | for (WeChatModule mod : modules) {
100 | mod.api.handleIntent(intent, mod);
101 | }
102 | }
103 |
104 | @ReactMethod
105 | public void registerApp(String appid, Callback callback) {
106 | this.appId = appid;
107 | api = WXAPIFactory.createWXAPI(this.getReactApplicationContext().getBaseContext(), appid, true);
108 | callback.invoke(null, api.registerApp(appid));
109 | }
110 |
111 | @ReactMethod
112 | public void isWXAppInstalled(Callback callback) {
113 | if (api == null) {
114 | callback.invoke(NOT_REGISTERED);
115 | return;
116 | }
117 | callback.invoke(null, api.isWXAppInstalled());
118 | }
119 |
120 | @ReactMethod
121 | public void isWXAppSupportApi(Callback callback) {
122 | if (api == null) {
123 | callback.invoke(NOT_REGISTERED);
124 | return;
125 | }
126 | callback.invoke(null, api.isWXAppSupportAPI());
127 | }
128 |
129 | @ReactMethod
130 | public void getApiVersion(Callback callback) {
131 | if (api == null) {
132 | callback.invoke(NOT_REGISTERED);
133 | return;
134 | }
135 | callback.invoke(null, api.getWXAppSupportAPI());
136 | }
137 |
138 | @ReactMethod
139 | public void openWXApp(Callback callback) {
140 | if (api == null) {
141 | callback.invoke(NOT_REGISTERED);
142 | return;
143 | }
144 | callback.invoke(null, api.openWXApp());
145 | }
146 |
147 | @ReactMethod
148 | public void sendAuthRequest(String scope, String state, Callback callback) {
149 | if (api == null) {
150 | callback.invoke(NOT_REGISTERED);
151 | return;
152 | }
153 | SendAuth.Req req = new SendAuth.Req();
154 | req.scope = scope;
155 | req.state = state;
156 | callback.invoke(null, api.sendReq(req));
157 | }
158 |
159 | @ReactMethod
160 | public void shareToTimeline(ReadableMap data, Callback callback) {
161 | if (api == null) {
162 | callback.invoke(NOT_REGISTERED);
163 | return;
164 | }
165 | _share(SendMessageToWX.Req.WXSceneTimeline, data, callback);
166 | }
167 |
168 | @ReactMethod
169 | public void shareToSession(ReadableMap data, Callback callback) {
170 | if (api == null) {
171 | callback.invoke(NOT_REGISTERED);
172 | return;
173 | }
174 | _share(SendMessageToWX.Req.WXSceneSession, data, callback);
175 | }
176 |
177 | @ReactMethod
178 | public void shareToFavorite(ReadableMap data, Callback callback) {
179 | if (api == null) {
180 | callback.invoke(NOT_REGISTERED);
181 | return;
182 | }
183 | _share(SendMessageToWX.Req.WXSceneFavorite, data, callback);
184 | }
185 |
186 | @ReactMethod
187 | public void pay(ReadableMap data, Callback callback) {
188 | PayReq payReq = new PayReq();
189 | if (data.hasKey("partnerId")) {
190 | payReq.partnerId = data.getString("partnerId");
191 | }
192 | if (data.hasKey("prepayId")) {
193 | payReq.prepayId = data.getString("prepayId");
194 | }
195 | if (data.hasKey("nonceStr")) {
196 | payReq.nonceStr = data.getString("nonceStr");
197 | }
198 | if (data.hasKey("timeStamp")) {
199 | payReq.timeStamp = data.getString("timeStamp");
200 | }
201 | if (data.hasKey("sign")) {
202 | payReq.sign = data.getString("sign");
203 | }
204 | if (data.hasKey("package")) {
205 | payReq.packageValue = data.getString("package");
206 | }
207 | if (data.hasKey("extData")) {
208 | payReq.extData = data.getString("extData");
209 | }
210 | payReq.appId = appId;
211 | callback.invoke(api.sendReq(payReq) ? null : INVOKE_FAILED);
212 | }
213 |
214 | private void _share(final int scene, final ReadableMap data, final Callback callback) {
215 | Uri uri = null;
216 | if (data.hasKey("thumbImage")) {
217 | String imageUrl = data.getString("thumbImage");
218 |
219 | try {
220 | uri = Uri.parse(imageUrl);
221 | // Verify scheme is set, so that relative uri (used by static resources) are not handled.
222 | if (uri.getScheme() == null) {
223 | uri = getResourceDrawableUri(getReactApplicationContext(), imageUrl);
224 | }
225 | } catch (Exception e) {
226 | // ignore malformed uri, then attempt to extract resource ID.
227 | }
228 | }
229 |
230 | if (uri != null) {
231 | this._getImage(uri, new ResizeOptions(100, 100), new ImageCallback() {
232 | @Override
233 | public void invoke(@Nullable Bitmap bitmap) {
234 | WeChatModule.this._share(scene, data, bitmap, callback);
235 | }
236 | });
237 | } else {
238 | this._share(scene, data, null, callback);
239 | }
240 | }
241 |
242 | private void _getImage(Uri uri, ResizeOptions resizeOptions, final ImageCallback imageCallback) {
243 | BaseBitmapDataSubscriber dataSubscriber = new BaseBitmapDataSubscriber() {
244 | @Override
245 | protected void onNewResultImpl(Bitmap bitmap) {
246 | if (bitmap != null) {
247 | if (bitmap.getConfig() != null) {
248 | bitmap = bitmap.copy(bitmap.getConfig(), true);
249 | imageCallback.invoke(bitmap);
250 | } else {
251 | bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
252 | imageCallback.invoke(bitmap);
253 | }
254 | } else {
255 | imageCallback.invoke(null);
256 | }
257 | }
258 |
259 | @Override
260 | protected void onFailureImpl(DataSource> dataSource) {
261 | imageCallback.invoke(null);
262 | }
263 | };
264 |
265 | ImageRequestBuilder builder = ImageRequestBuilder.newBuilderWithSource(uri);
266 | if (resizeOptions != null) {
267 | builder = builder.setResizeOptions(resizeOptions);
268 | }
269 | ImageRequest imageRequest = builder.build();
270 |
271 | ImagePipeline imagePipeline = Fresco.getImagePipeline();
272 | DataSource> dataSource = imagePipeline.fetchDecodedImage(imageRequest, null);
273 | dataSource.subscribe(dataSubscriber, UiThreadImmediateExecutorService.getInstance());
274 | }
275 |
276 | private static Uri getResourceDrawableUri(Context context, String name) {
277 | if (name == null || name.isEmpty()) {
278 | return null;
279 | }
280 | name = name.toLowerCase().replace("-", "_");
281 | int resId = context.getResources().getIdentifier(
282 | name,
283 | "drawable",
284 | context.getPackageName());
285 |
286 | if (resId == 0) {
287 | return null;
288 | } else {
289 | return new Uri.Builder()
290 | .scheme(UriUtil.LOCAL_RESOURCE_SCHEME)
291 | .path(String.valueOf(resId))
292 | .build();
293 | }
294 | }
295 |
296 | private void _share(final int scene, final ReadableMap data, final Bitmap thumbImage, final Callback callback) {
297 | if (!data.hasKey("type")) {
298 | callback.invoke(INVALID_ARGUMENT);
299 | return;
300 | }
301 | String type = data.getString("type");
302 |
303 | WXMediaMessage.IMediaObject mediaObject = null;
304 | if (type.equals("news")) {
305 | mediaObject = _jsonToWebpageMedia(data);
306 | } else if (type.equals("text")) {
307 | mediaObject = _jsonToTextMedia(data);
308 | } else if (type.equals("imageUrl") || type.equals("imageResource")) {
309 | __jsonToImageUrlMedia(data, new MediaObjectCallback() {
310 | @Override
311 | public void invoke(@Nullable WXMediaMessage.IMediaObject mediaObject) {
312 | if (mediaObject == null) {
313 | callback.invoke(INVALID_ARGUMENT);
314 | } else {
315 | WeChatModule.this._share(scene, data, thumbImage, mediaObject, callback);
316 | }
317 | }
318 | });
319 | return;
320 | } else if (type.equals("imageFile")) {
321 | __jsonToImageFileMedia(data, new MediaObjectCallback() {
322 | @Override
323 | public void invoke(@Nullable WXMediaMessage.IMediaObject mediaObject) {
324 | if (mediaObject == null) {
325 | callback.invoke(INVALID_ARGUMENT);
326 | } else {
327 | WeChatModule.this._share(scene, data, thumbImage, mediaObject, callback);
328 | }
329 | }
330 | });
331 | return;
332 | } else if (type.equals("video")) {
333 | mediaObject = __jsonToVideoMedia(data);
334 | } else if (type.equals("audio")) {
335 | mediaObject = __jsonToMusicMedia(data);
336 | } else if (type.equals("file")) {
337 | mediaObject = __jsonToFileMedia(data);
338 | }
339 |
340 | if (mediaObject == null) {
341 | callback.invoke(INVALID_ARGUMENT);
342 | } else {
343 | _share(scene, data, thumbImage, mediaObject, callback);
344 | }
345 | }
346 |
347 | private void _share(int scene, ReadableMap data, Bitmap thumbImage, WXMediaMessage.IMediaObject mediaObject, Callback callback) {
348 |
349 | WXMediaMessage message = new WXMediaMessage();
350 | message.mediaObject = mediaObject;
351 |
352 | if (thumbImage != null) {
353 | message.setThumbImage(thumbImage);
354 | }
355 |
356 | if (data.hasKey("title")) {
357 | message.title = data.getString("title");
358 | }
359 | if (data.hasKey("description")) {
360 | message.description = data.getString("description");
361 | }
362 | if (data.hasKey("mediaTagName")) {
363 | message.mediaTagName = data.getString("mediaTagName");
364 | }
365 | if (data.hasKey("messageAction")) {
366 | message.messageAction = data.getString("messageAction");
367 | }
368 | if (data.hasKey("messageExt")) {
369 | message.messageExt = data.getString("messageExt");
370 | }
371 |
372 | SendMessageToWX.Req req = new SendMessageToWX.Req();
373 | req.message = message;
374 | req.scene = scene;
375 | req.transaction = UUID.randomUUID().toString();
376 | callback.invoke(null, api.sendReq(req));
377 | }
378 |
379 | private WXTextObject _jsonToTextMedia(ReadableMap data) {
380 | if (!data.hasKey("description")) {
381 | return null;
382 | }
383 |
384 | WXTextObject ret = new WXTextObject();
385 | ret.text = data.getString("description");
386 | return ret;
387 | }
388 |
389 | private WXWebpageObject _jsonToWebpageMedia(ReadableMap data) {
390 | if (!data.hasKey("webpageUrl")) {
391 | return null;
392 | }
393 |
394 | WXWebpageObject ret = new WXWebpageObject();
395 | ret.webpageUrl = data.getString("webpageUrl");
396 | if (data.hasKey("extInfo")) {
397 | ret.extInfo = data.getString("extInfo");
398 | }
399 | return ret;
400 | }
401 |
402 | private void __jsonToImageMedia(String imageUrl, final MediaObjectCallback callback) {
403 | Uri imageUri;
404 | try {
405 | imageUri = Uri.parse(imageUrl);
406 | // Verify scheme is set, so that relative uri (used by static resources) are not handled.
407 | if (imageUri.getScheme() == null) {
408 | imageUri = getResourceDrawableUri(getReactApplicationContext(), imageUrl);
409 | }
410 | } catch (Exception e) {
411 | imageUri = null;
412 | }
413 |
414 | if (imageUri == null) {
415 | callback.invoke(null);
416 | return;
417 | }
418 |
419 | this._getImage(imageUri, null, new ImageCallback() {
420 | @Override
421 | public void invoke(@Nullable Bitmap bitmap) {
422 | callback.invoke(bitmap == null ? null : new WXImageObject(bitmap));
423 | }
424 | });
425 | }
426 |
427 | private void __jsonToImageUrlMedia(ReadableMap data, MediaObjectCallback callback) {
428 | if (!data.hasKey("imageUrl")) {
429 | callback.invoke(null);
430 | return;
431 | }
432 | String imageUrl = data.getString("imageUrl");
433 | __jsonToImageMedia(imageUrl, callback);
434 | }
435 |
436 | private void __jsonToImageFileMedia(ReadableMap data, MediaObjectCallback callback) {
437 | if (!data.hasKey("imageUrl")) {
438 | callback.invoke(null);
439 | return;
440 | }
441 |
442 | String imageUrl = data.getString("imageUrl");
443 | if (!imageUrl.toLowerCase().startsWith("file://")) {
444 | imageUrl = "file://" + imageUrl;
445 | }
446 | __jsonToImageMedia(imageUrl, callback);
447 | }
448 |
449 | private WXMusicObject __jsonToMusicMedia(ReadableMap data) {
450 | if (!data.hasKey("musicUrl")) {
451 | return null;
452 | }
453 |
454 | WXMusicObject ret = new WXMusicObject();
455 | ret.musicUrl = data.getString("musicUrl");
456 | return ret;
457 | }
458 |
459 | private WXVideoObject __jsonToVideoMedia(ReadableMap data) {
460 | if (!data.hasKey("videoUrl")) {
461 | return null;
462 | }
463 |
464 | WXVideoObject ret = new WXVideoObject();
465 | ret.videoUrl = data.getString("videoUrl");
466 | return ret;
467 | }
468 |
469 | private WXFileObject __jsonToFileMedia(ReadableMap data) {
470 | if (!data.hasKey("filePath")) {
471 | return null;
472 | }
473 | return new WXFileObject(data.getString("filePath"));
474 | }
475 |
476 | // TODO: 实现sendRequest、sendSuccessResponse、sendErrorCommonResponse、sendErrorUserCancelResponse
477 |
478 | @Override
479 | public void onReq(BaseReq baseReq) {
480 |
481 | }
482 |
483 | @Override
484 | public void onResp(BaseResp baseResp) {
485 | WritableMap map = Arguments.createMap();
486 | map.putInt("errCode", baseResp.errCode);
487 | map.putString("errStr", baseResp.errStr);
488 | map.putString("openId", baseResp.openId);
489 | map.putString("transaction", baseResp.transaction);
490 |
491 | if (baseResp instanceof SendAuth.Resp) {
492 | SendAuth.Resp resp = (SendAuth.Resp) (baseResp);
493 |
494 | map.putString("type", "SendAuth.Resp");
495 | map.putString("code", resp.code);
496 | map.putString("state", resp.state);
497 | map.putString("url", resp.url);
498 | map.putString("lang", resp.lang);
499 | map.putString("country", resp.country);
500 | } else if (baseResp instanceof SendMessageToWX.Resp) {
501 | SendMessageToWX.Resp resp = (SendMessageToWX.Resp) (baseResp);
502 | map.putString("type", "SendMessageToWX.Resp");
503 | } else if (baseResp instanceof PayResp) {
504 | PayResp resp = (PayResp) (baseResp);
505 | map.putString("type", "PayReq.Resp");
506 | map.putString("returnKey", resp.returnKey);
507 | }
508 |
509 | this.getReactApplicationContext()
510 | .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
511 | .emit("WeChat_Resp", map);
512 | }
513 |
514 | private interface ImageCallback {
515 | void invoke(@Nullable Bitmap bitmap);
516 | }
517 |
518 | private interface MediaObjectCallback {
519 | void invoke(@Nullable WXMediaMessage.IMediaObject mediaObject);
520 | }
521 |
522 | }
523 |
--------------------------------------------------------------------------------
/android/src/main/java/com/theweflex/react/WeChatPackage.java:
--------------------------------------------------------------------------------
1 | package com.theweflex.react;
2 |
3 | import com.facebook.react.ReactPackage;
4 | import com.facebook.react.bridge.JavaScriptModule;
5 | import com.facebook.react.bridge.NativeModule;
6 | import com.facebook.react.bridge.ReactApplicationContext;
7 | import com.facebook.react.uimanager.ViewManager;
8 |
9 | import java.util.Arrays;
10 | import java.util.Collections;
11 | import java.util.List;
12 |
13 | /**
14 | * Created by tdzl2_000 on 2015-10-10.
15 | */
16 | public class WeChatPackage implements ReactPackage {
17 | @Override
18 | public List createNativeModules(ReactApplicationContext reactContext) {
19 | return Arrays.asList(new NativeModule[]{
20 | // Modules from third-party
21 | new WeChatModule(reactContext),
22 | });
23 | }
24 |
25 | public List> createJSModules() {
26 | return Collections.emptyList();
27 | }
28 |
29 | @Override
30 | public List createViewManagers(ReactApplicationContext reactContext) {
31 | return Collections.emptyList();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/docs/build-setup-android.md:
--------------------------------------------------------------------------------
1 | # Build Setup for Android
2 |
3 | Copy lines to `android/settings.gradle`:
4 |
5 | ```gradle
6 | include ':RCTWeChat'
7 | project(':RCTWeChat').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-wechat/android')
8 | ```
9 |
10 | Copy lines to `android/app/build.gradle`
11 |
12 | ```gradle
13 | dependencies {
14 | implementation project(':RCTWeChat') // Add this line
15 | }
16 | ```
17 |
18 | Copy lines to `proguard-rules.pro`:
19 |
20 | ```pro
21 | -keep class com.tencent.mm.sdk.** {
22 | *;
23 | }
24 | ```
25 |
26 | Then update `MainActivity.java` or `MainApplication.java`:
27 |
28 | ```java
29 | import com.theweflex.react.WeChatPackage; // Add this line
30 |
31 | @Override
32 | protected List getPackages() {
33 | @SuppressWarnings("UnnecessaryLocalVariable")
34 | List packages = new PackageList(this).getPackages();
35 | // Packages that cannot be autolinked yet can be added manually here, for example:
36 | // packages.add(new MyReactNativePackage());
37 | packages.add(new WeChatPackage()); // Add this line
38 | return packages;
39 | }
40 | ```
41 |
42 | **Integrating with login and share**
43 |
44 | If you are going to integrate login or share functions, you need to
45 | create a package named 'wxapi' in your application package and a class
46 | named `WXEntryActivity` in it.
47 |
48 | ```java
49 | package your.package.wxapi;
50 |
51 | import android.app.Activity;
52 | import android.os.Bundle;
53 | import com.theweflex.react.WeChatModule;
54 |
55 | public class WXEntryActivity extends Activity {
56 | @Override
57 | protected void onCreate(Bundle savedInstanceState) {
58 | super.onCreate(savedInstanceState);
59 | WeChatModule.handleIntent(getIntent());
60 | finish();
61 | }
62 | }
63 | ```
64 |
65 | Then add the following node to `AndroidManifest.xml`:
66 |
67 | ```xml
68 |
69 |
70 |
75 |
76 |
77 | ```
78 |
79 | **Integrating the WeChat Payment**
80 |
81 | If you are going to integrate payment functionality by using this library, then
82 | create a package named also `wxapi` in your application package and a class named
83 | `WXPayEntryActivity`, this is used to bypass the response to JS level:
84 |
85 | ```java
86 | package your.package.wxapi;
87 |
88 | import android.app.Activity;
89 | import android.os.Bundle;
90 | import com.theweflex.react.WeChatModule;
91 |
92 | public class WXPayEntryActivity extends Activity {
93 | @Override
94 | protected void onCreate(Bundle savedInstanceState) {
95 | super.onCreate(savedInstanceState);
96 | WeChatModule.handleIntent(getIntent());
97 | finish();
98 | }
99 | }
100 | ```
101 |
102 | Then add the following node to `AndroidManifest.xml`:
103 |
104 | ```xml
105 |
106 |
107 |
112 |
113 |
114 | ```
115 |
--------------------------------------------------------------------------------
/docs/build-setup-ios.md:
--------------------------------------------------------------------------------
1 | # Build Setup for iOS
2 |
3 | Add the following libraries to your "Link Binary with Libraries" in Targets > Build Phases :
4 |
5 | - [x] `SystemConfiguration.framework`
6 | - [x] `CoreTelephony.framework`
7 | - [x] `libsqlite3.0`
8 | - [x] `libc++`
9 | - [x] `libz`
10 |
11 | Add "URL Schema" as your app id for "URL type" in Targets > info, See
12 | the following screenshot for the view on your XCode:
13 |
14 | 
15 |
16 | On iOS 9+, add `wechat` and `weixin` into `LSApplicationQueriesSchemes` in
17 | `Targets` > `info` > `Custom iOS Target Properties`. Or edit `Info.plist`
18 | then add:
19 |
20 | ```xml
21 | LSApplicationQueriesSchemes
22 |
23 | weixin
24 | wechat
25 |
26 | ```
27 |
28 | Then copy the following in `AppDelegate.m`:
29 |
30 | ```objc
31 | #import
32 |
33 | // ios 8.x or older
34 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
35 | sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
36 | {
37 | return [RCTLinkingManager application:application openURL:url
38 | sourceApplication:sourceApplication annotation:annotation];
39 | }
40 |
41 | // ios 9.0+
42 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
43 | options:(NSDictionary *)options
44 | {
45 | return [RCTLinkingManager application:application openURL:url options:options];
46 | }
47 | ```
48 |
--------------------------------------------------------------------------------
/index.d.ts:
--------------------------------------------------------------------------------
1 | declare module "react-native-wechat" {
2 | export function registerApp(appId: string): Promise;
3 | export function registerAppWithDescription(
4 | appId: string,
5 | desc: string
6 | ): Promise;
7 | export function isWXAppInstalled(): Promise;
8 | export function isWXAppSupportApi(): Promise;
9 | export function getApiVersion(): Promise;
10 | export function openWXApp(): Promise;
11 | export interface AuthResponse {
12 | errCode?: number;
13 | errStr?: string;
14 | openId?: string;
15 | code?: string;
16 | url?: string;
17 | lang?: string;
18 | country?: string;
19 | }
20 | export function sendAuthRequest(
21 | scope: string | string[],
22 | state?: string
23 | ): Promise;
24 | export interface ShareMetadata {
25 | type:
26 | | "news"
27 | | "text"
28 | | "imageUrl"
29 | | "imageFile"
30 | | "imageResource"
31 | | "video"
32 | | "audio"
33 | | "file";
34 | thumbImage?: string;
35 | title?: string;
36 | description?: string;
37 | webpageUrl?: string;
38 | imageUrl?: string;
39 | videoUrl?: string;
40 | musicUrl?: string;
41 | filePath?: string;
42 | fileExtension?: string;
43 | }
44 | export function shareToTimeline(
45 | message: ShareMetadata
46 | ): Promise<{ errCode?: number; errStr?: string }>;
47 | export function shareToSession(
48 | message: ShareMetadata
49 | ): Promise<{ errCode?: number; errStr?: string }>;
50 | export interface PaymentLoad {
51 | partnerId: string;
52 | prepayId: string;
53 | nonceStr: string;
54 | timeStamp: string;
55 | package: string;
56 | sign: string;
57 | }
58 | export function pay(
59 | payload: PaymentLoad
60 | ): Promise<{ errCode?: number; errStr?: string }>;
61 | }
62 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { DeviceEventEmitter, NativeModules, Platform } from 'react-native';
4 | import { EventEmitter } from 'events';
5 |
6 | let isAppRegistered = false;
7 | const { WeChat } = NativeModules;
8 |
9 | // Event emitter to dispatch request and response from WeChat.
10 | const emitter = new EventEmitter();
11 |
12 | DeviceEventEmitter.addListener('WeChat_Resp', resp => {
13 | emitter.emit(resp.type, resp);
14 | });
15 |
16 | function wrapRegisterApp(nativeFunc) {
17 | if (!nativeFunc) {
18 | return undefined;
19 | }
20 | return (...args) => {
21 | if (isAppRegistered) {
22 | // FIXME(Yorkie): we ignore this error if AppRegistered is true.
23 | return Promise.resolve(true);
24 | }
25 | isAppRegistered = true;
26 | return new Promise((resolve, reject) => {
27 | nativeFunc.apply(null, [
28 | ...args,
29 | (error, result) => {
30 | if (!error) {
31 | return resolve(result);
32 | }
33 | if (typeof error === 'string') {
34 | return reject(new Error(error));
35 | }
36 | reject(error);
37 | },
38 | ]);
39 | });
40 | };
41 | }
42 |
43 | function wrapApi(nativeFunc) {
44 | if (!nativeFunc) {
45 | return undefined;
46 | }
47 | return (...args) => {
48 | if (!isAppRegistered) {
49 | return Promise.reject(new Error('registerApp required.'));
50 | }
51 | return new Promise((resolve, reject) => {
52 | nativeFunc.apply(null, [
53 | ...args,
54 | (error, result) => {
55 | if (!error) {
56 | return resolve(result);
57 | }
58 | if (typeof error === 'string') {
59 | return reject(new Error(error));
60 | }
61 | reject(error);
62 | },
63 | ]);
64 | });
65 | };
66 | }
67 |
68 | /**
69 | * `addListener` inherits from `events` module
70 | * @method addListener
71 | * @param {String} eventName - the event name
72 | * @param {Function} trigger - the function when event is fired
73 | */
74 | export const addListener = emitter.addListener.bind(emitter);
75 |
76 | /**
77 | * `once` inherits from `events` module
78 | * @method once
79 | * @param {String} eventName - the event name
80 | * @param {Function} trigger - the function when event is fired
81 | */
82 | export const once = emitter.once.bind(emitter);
83 |
84 | /**
85 | * `removeAllListeners` inherits from `events` module
86 | * @method removeAllListeners
87 | * @param {String} eventName - the event name
88 | */
89 | export const removeAllListeners = emitter.removeAllListeners.bind(emitter);
90 |
91 | /**
92 | * @method registerApp
93 | * @param {String} appid - the app id
94 | * @return {Promise}
95 | */
96 | export const registerApp = wrapRegisterApp(WeChat.registerApp);
97 |
98 | /**
99 | * @method registerAppWithDescription
100 | * @param {String} appid - the app id
101 | * @param {String} appdesc - the app description
102 | * @return {Promise}
103 | */
104 | export const registerAppWithDescription = wrapRegisterApp(
105 | WeChat.registerAppWithDescription,
106 | );
107 |
108 | /**
109 | * Return if the wechat app is installed in the device.
110 | * @method isWXAppInstalled
111 | * @return {Promise}
112 | */
113 | export const isWXAppInstalled = wrapApi(WeChat.isWXAppInstalled);
114 |
115 | /**
116 | * Return if the wechat application supports the api
117 | * @method isWXAppSupportApi
118 | * @return {Promise}
119 | */
120 | export const isWXAppSupportApi = wrapApi(WeChat.isWXAppSupportApi);
121 |
122 | /**
123 | * Get the wechat app installed url
124 | * @method getWXAppInstallUrl
125 | * @return {String} the wechat app installed url
126 | */
127 | export const getWXAppInstallUrl = wrapApi(WeChat.getWXAppInstallUrl);
128 |
129 | /**
130 | * Get the wechat api version
131 | * @method getApiVersion
132 | * @return {String} the api version string
133 | */
134 | export const getApiVersion = wrapApi(WeChat.getApiVersion);
135 |
136 | /**
137 | * Open wechat app
138 | * @method openWXApp
139 | * @return {Promise}
140 | */
141 | export const openWXApp = wrapApi(WeChat.openWXApp);
142 |
143 | // wrap the APIs
144 | const nativeShareToTimeline = wrapApi(WeChat.shareToTimeline);
145 | const nativeShareToSession = wrapApi(WeChat.shareToSession);
146 | const nativeShareToFavorite = wrapApi(WeChat.shareToFavorite);
147 | const nativeSendAuthRequest = wrapApi(WeChat.sendAuthRequest);
148 |
149 | /**
150 | * @method sendAuthRequest
151 | * @param {Array} scopes - the scopes for authentication.
152 | * @return {Promise}
153 | */
154 | export function sendAuthRequest(scopes, state) {
155 | return new Promise((resolve, reject) => {
156 | WeChat.sendAuthRequest(scopes, state, () => {});
157 | emitter.once('SendAuth.Resp', resp => {
158 | if (resp.errCode === 0) {
159 | resolve(resp);
160 | } else {
161 | reject(new WechatError(resp));
162 | }
163 | });
164 | });
165 | }
166 |
167 | /**
168 | * Share something to timeline/moments/朋友圈
169 | * @method shareToTimeline
170 | * @param {Object} data
171 | * @param {String} data.thumbImage - Thumb image of the message, which can be a uri or a resource id.
172 | * @param {String} data.type - Type of this message. Could be {news|text|imageUrl|imageFile|imageResource|video|audio|file}
173 | * @param {String} data.webpageUrl - Required if type equals news. The webpage link to share.
174 | * @param {String} data.imageUrl - Provide a remote image if type equals image.
175 | * @param {String} data.videoUrl - Provide a remote video if type equals video.
176 | * @param {String} data.musicUrl - Provide a remote music if type equals audio.
177 | * @param {String} data.filePath - Provide a local file if type equals file.
178 | * @param {String} data.fileExtension - Provide the file type if type equals file.
179 | */
180 | export function shareToTimeline(data) {
181 | return new Promise((resolve, reject) => {
182 | nativeShareToTimeline(data);
183 | emitter.once('SendMessageToWX.Resp', resp => {
184 | if (resp.errCode === 0) {
185 | resolve(resp);
186 | } else {
187 | reject(new WechatError(resp));
188 | }
189 | });
190 | });
191 | }
192 |
193 | /**
194 | * Share something to a friend or group
195 | * @method shareToSession
196 | * @param {Object} data
197 | * @param {String} data.thumbImage - Thumb image of the message, which can be a uri or a resource id.
198 | * @param {String} data.type - Type of this message. Could be {news|text|imageUrl|imageFile|imageResource|video|audio|file}
199 | * @param {String} data.webpageUrl - Required if type equals news. The webpage link to share.
200 | * @param {String} data.imageUrl - Provide a remote image if type equals image.
201 | * @param {String} data.videoUrl - Provide a remote video if type equals video.
202 | * @param {String} data.musicUrl - Provide a remote music if type equals audio.
203 | * @param {String} data.filePath - Provide a local file if type equals file.
204 | * @param {String} data.fileExtension - Provide the file type if type equals file.
205 | */
206 | export function shareToSession(data) {
207 | return new Promise((resolve, reject) => {
208 | nativeShareToSession(data);
209 | emitter.once('SendMessageToWX.Resp', resp => {
210 | if (resp.errCode === 0) {
211 | resolve(resp);
212 | } else {
213 | reject(new WechatError(resp));
214 | }
215 | });
216 | });
217 | }
218 |
219 | /**
220 | * Share something to favorite
221 | * @method shareToFavorite
222 | * @param {Object} data
223 | * @param {String} data.thumbImage - Thumb image of the message, which can be a uri or a resource id.
224 | * @param {String} data.type - Type of this message. Could be {news|text|imageUrl|imageFile|imageResource|video|audio|file}
225 | * @param {String} data.webpageUrl - Required if type equals news. The webpage link to share.
226 | * @param {String} data.imageUrl - Provide a remote image if type equals image.
227 | * @param {String} data.videoUrl - Provide a remote video if type equals video.
228 | * @param {String} data.musicUrl - Provide a remote music if type equals audio.
229 | * @param {String} data.filePath - Provide a local file if type equals file.
230 | * @param {String} data.fileExtension - Provide the file type if type equals file.
231 | */
232 | export function shareToFavorite(data) {
233 | return new Promise((resolve, reject) => {
234 | nativeShareToFavorite(data);
235 | emitter.once('SendMessageToWX.Resp', resp => {
236 | if (resp.errCode === 0) {
237 | resolve(resp);
238 | } else {
239 | reject(new WechatError(resp));
240 | }
241 | });
242 | });
243 | }
244 |
245 | /**
246 | * wechat pay
247 | * @param {Object} data
248 | * @param {String} data.partnerId
249 | * @param {String} data.prepayId
250 | * @param {String} data.nonceStr
251 | * @param {String} data.timeStamp
252 | * @param {String} data.package
253 | * @param {String} data.sign
254 | * @returns {Promise}
255 | */
256 | export function pay(data) {
257 | // FIXME(Yorkie): see https://github.com/yorkie/react-native-wechat/issues/203
258 | // Here the server-side returns params in lowercase, but here SDK requires timeStamp
259 | // for compatibility, we make this correction for users.
260 | function correct(actual, fixed) {
261 | if (!data[fixed] && data[actual]) {
262 | data[fixed] = data[actual];
263 | delete data[actual];
264 | }
265 | }
266 | correct('prepayid', 'prepayId');
267 | correct('noncestr', 'nonceStr');
268 | correct('partnerid', 'partnerId');
269 | correct('timestamp', 'timeStamp');
270 |
271 | // FIXME(94cstyles)
272 | // Android requires the type of the timeStamp field to be a string
273 | if (Platform.OS === 'android') data.timeStamp = String(data.timeStamp)
274 |
275 | return new Promise((resolve, reject) => {
276 | WeChat.pay(data, result => {
277 | if (result) reject(result);
278 | });
279 | emitter.once('PayReq.Resp', resp => {
280 | if (resp.errCode === 0) {
281 | resolve(resp);
282 | } else {
283 | reject(new WechatError(resp));
284 | }
285 | });
286 | });
287 | }
288 |
289 | /**
290 | * promises will reject with this error when API call finish with an errCode other than zero.
291 | */
292 | export class WechatError extends Error {
293 | constructor(resp) {
294 | const message = resp.errStr || resp.errCode.toString();
295 | super(message);
296 | this.name = 'WechatError';
297 | this.code = resp.errCode;
298 |
299 | // avoid babel's limition about extending Error class
300 | // https://github.com/babel/babel/issues/3083
301 | if (typeof Object.setPrototypeOf === 'function') {
302 | Object.setPrototypeOf(this, WechatError.prototype);
303 | } else {
304 | this.__proto__ = WechatError.prototype;
305 | }
306 | }
307 | }
308 |
309 |
--------------------------------------------------------------------------------
/ios/RCTWeChat.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCTWeChat.h
3 | // RCTWeChat
4 | //
5 | // Created by Yorkie Liu on 10/16/15.
6 | // Copyright © 2015 WeFlex. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | #import
13 | #import "WXApi.h"
14 |
15 | // define share type constants
16 | #define RCTWXShareTypeNews @"news"
17 | #define RCTWXShareTypeThumbImageUrl @"thumbImage"
18 | #define RCTWXShareTypeImageUrl @"imageUrl"
19 | #define RCTWXShareTypeImageFile @"imageFile"
20 | #define RCTWXShareTypeImageResource @"imageResource"
21 | #define RCTWXShareTypeText @"text"
22 | #define RCTWXShareTypeVideo @"video"
23 | #define RCTWXShareTypeAudio @"audio"
24 | #define RCTWXShareTypeFile @"file"
25 |
26 | #define RCTWXShareType @"type"
27 | #define RCTWXShareTitle @"title"
28 | #define RCTWXShareDescription @"description"
29 | #define RCTWXShareWebpageUrl @"webpageUrl"
30 | #define RCTWXShareImageUrl @"imageUrl"
31 |
32 | #define RCTWXEventName @"WeChat_Resp"
33 |
34 | @interface RCTWeChat : NSObject
35 |
36 | @property NSString* appId;
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/ios/RCTWeChat.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCTWeChat.m
3 | // RCTWeChat
4 | //
5 | // Created by Yorkie Liu on 10/16/15.
6 | // Copyright © 2015 WeFlex. All rights reserved.
7 | //
8 |
9 | #import "RCTWeChat.h"
10 | #import "WXApiObject.h"
11 | #import
12 | #import
13 | #import
14 | #import
15 |
16 | // Define error messages
17 | #define NOT_REGISTERED (@"registerApp required.")
18 | #define INVOKE_FAILED (@"WeChat API invoke returns false.")
19 |
20 | @implementation RCTWeChat
21 |
22 | @synthesize bridge = _bridge;
23 |
24 | RCT_EXPORT_MODULE()
25 |
26 | - (instancetype)init
27 | {
28 | self = [super init];
29 | if (self) {
30 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleOpenURL:) name:@"RCTOpenURLNotification" object:nil];
31 | }
32 | return self;
33 | }
34 |
35 | - (void)dealloc
36 | {
37 | [[NSNotificationCenter defaultCenter] removeObserver:self];
38 | }
39 |
40 | - (BOOL)handleOpenURL:(NSNotification *)aNotification
41 | {
42 | NSString * aURLString = [aNotification userInfo][@"url"];
43 | NSURL * aURL = [NSURL URLWithString:aURLString];
44 |
45 | if ([WXApi handleOpenURL:aURL delegate:self])
46 | {
47 | return YES;
48 | } else {
49 | return NO;
50 | }
51 | }
52 |
53 | - (dispatch_queue_t)methodQueue
54 | {
55 | return dispatch_get_main_queue();
56 | }
57 |
58 | + (BOOL)requiresMainQueueSetup {
59 | return YES;
60 | }
61 |
62 | RCT_EXPORT_METHOD(registerApp:(NSString *)appid
63 | :(RCTResponseSenderBlock)callback)
64 | {
65 | self.appId = appid;
66 | callback(@[[WXApi registerApp:appid] ? [NSNull null] : INVOKE_FAILED]);
67 | }
68 |
69 | RCT_EXPORT_METHOD(registerAppWithDescription:(NSString *)appid
70 | :(NSString *)appdesc
71 | :(RCTResponseSenderBlock)callback)
72 | {
73 | callback(@[[WXApi registerApp:appid withDescription:appdesc] ? [NSNull null] : INVOKE_FAILED]);
74 | }
75 |
76 | RCT_EXPORT_METHOD(isWXAppInstalled:(RCTResponseSenderBlock)callback)
77 | {
78 | callback(@[[NSNull null], @([WXApi isWXAppInstalled])]);
79 | }
80 |
81 | RCT_EXPORT_METHOD(isWXAppSupportApi:(RCTResponseSenderBlock)callback)
82 | {
83 | callback(@[[NSNull null], @([WXApi isWXAppSupportApi])]);
84 | }
85 |
86 | RCT_EXPORT_METHOD(getWXAppInstallUrl:(RCTResponseSenderBlock)callback)
87 | {
88 | callback(@[[NSNull null], [WXApi getWXAppInstallUrl]]);
89 | }
90 |
91 | RCT_EXPORT_METHOD(getApiVersion:(RCTResponseSenderBlock)callback)
92 | {
93 | callback(@[[NSNull null], [WXApi getApiVersion]]);
94 | }
95 |
96 | RCT_EXPORT_METHOD(openWXApp:(RCTResponseSenderBlock)callback)
97 | {
98 | callback(@[([WXApi openWXApp] ? [NSNull null] : INVOKE_FAILED)]);
99 | }
100 |
101 | RCT_EXPORT_METHOD(sendRequest:(NSString *)openid
102 | :(RCTResponseSenderBlock)callback)
103 | {
104 | BaseReq* req = [[BaseReq alloc] init];
105 | req.openID = openid;
106 | callback(@[[WXApi sendReq:req] ? [NSNull null] : INVOKE_FAILED]);
107 | }
108 |
109 | RCT_EXPORT_METHOD(sendAuthRequest:(NSString *)scope
110 | :(NSString *)state
111 | :(RCTResponseSenderBlock)callback)
112 | {
113 | SendAuthReq* req = [[SendAuthReq alloc] init];
114 | req.scope = scope;
115 | req.state = state;
116 | BOOL success = [WXApi sendReq:req];
117 | callback(@[success ? [NSNull null] : INVOKE_FAILED]);
118 | }
119 |
120 | RCT_EXPORT_METHOD(sendSuccessResponse:(RCTResponseSenderBlock)callback)
121 | {
122 | BaseResp* resp = [[BaseResp alloc] init];
123 | resp.errCode = WXSuccess;
124 | callback(@[[WXApi sendResp:resp] ? [NSNull null] : INVOKE_FAILED]);
125 | }
126 |
127 | RCT_EXPORT_METHOD(sendErrorCommonResponse:(NSString *)message
128 | :(RCTResponseSenderBlock)callback)
129 | {
130 | BaseResp* resp = [[BaseResp alloc] init];
131 | resp.errCode = WXErrCodeCommon;
132 | resp.errStr = message;
133 | callback(@[[WXApi sendResp:resp] ? [NSNull null] : INVOKE_FAILED]);
134 | }
135 |
136 | RCT_EXPORT_METHOD(sendErrorUserCancelResponse:(NSString *)message
137 | :(RCTResponseSenderBlock)callback)
138 | {
139 | BaseResp* resp = [[BaseResp alloc] init];
140 | resp.errCode = WXErrCodeUserCancel;
141 | resp.errStr = message;
142 | callback(@[[WXApi sendResp:resp] ? [NSNull null] : INVOKE_FAILED]);
143 | }
144 |
145 | RCT_EXPORT_METHOD(shareToTimeline:(NSDictionary *)data
146 | :(RCTResponseSenderBlock)callback)
147 | {
148 | [self shareToWeixinWithData:data scene:WXSceneTimeline callback:callback];
149 | }
150 |
151 | RCT_EXPORT_METHOD(shareToSession:(NSDictionary *)data
152 | :(RCTResponseSenderBlock)callback)
153 | {
154 | [self shareToWeixinWithData:data scene:WXSceneSession callback:callback];
155 | }
156 |
157 | RCT_EXPORT_METHOD(shareToFavorite:(NSDictionary *)data
158 | :(RCTResponseSenderBlock)callback)
159 | {
160 | [self shareToWeixinWithData:data scene:WXSceneFavorite callback:callback];
161 | }
162 |
163 | RCT_EXPORT_METHOD(pay:(NSDictionary *)data
164 | :(RCTResponseSenderBlock)callback)
165 | {
166 | PayReq* req = [PayReq new];
167 | req.partnerId = data[@"partnerId"];
168 | req.prepayId = data[@"prepayId"];
169 | req.nonceStr = data[@"nonceStr"];
170 | req.timeStamp = [data[@"timeStamp"] unsignedIntValue];
171 | req.package = data[@"package"];
172 | req.sign = data[@"sign"];
173 | BOOL success = [WXApi sendReq:req];
174 | callback(@[success ? [NSNull null] : INVOKE_FAILED]);
175 | }
176 |
177 | - (void)shareToWeixinWithData:(NSDictionary *)aData
178 | thumbImage:(UIImage *)aThumbImage
179 | scene:(int)aScene
180 | callBack:(RCTResponseSenderBlock)callback
181 | {
182 | NSString *type = aData[RCTWXShareType];
183 |
184 | if ([type isEqualToString:RCTWXShareTypeText]) {
185 | NSString *text = aData[RCTWXShareDescription];
186 | [self shareToWeixinWithTextMessage:aScene Text:text callBack:callback];
187 | } else {
188 | NSString * title = aData[RCTWXShareTitle];
189 | NSString * description = aData[RCTWXShareDescription];
190 | NSString * mediaTagName = aData[@"mediaTagName"];
191 | NSString * messageAction = aData[@"messageAction"];
192 | NSString * messageExt = aData[@"messageExt"];
193 |
194 | if (type.length <= 0 || [type isEqualToString:RCTWXShareTypeNews]) {
195 | NSString * webpageUrl = aData[RCTWXShareWebpageUrl];
196 | if (webpageUrl.length <= 0) {
197 | callback(@[@"webpageUrl required"]);
198 | return;
199 | }
200 |
201 | WXWebpageObject* webpageObject = [WXWebpageObject object];
202 | webpageObject.webpageUrl = webpageUrl;
203 |
204 | [self shareToWeixinWithMediaMessage:aScene
205 | Title:title
206 | Description:description
207 | Object:webpageObject
208 | MessageExt:messageExt
209 | MessageAction:messageAction
210 | ThumbImage:aThumbImage
211 | MediaTag:mediaTagName
212 | callBack:callback];
213 |
214 | } else if ([type isEqualToString:RCTWXShareTypeAudio]) {
215 | WXMusicObject *musicObject = [WXMusicObject new];
216 | musicObject.musicUrl = aData[@"musicUrl"];
217 | musicObject.musicLowBandUrl = aData[@"musicLowBandUrl"];
218 | musicObject.musicDataUrl = aData[@"musicDataUrl"];
219 | musicObject.musicLowBandDataUrl = aData[@"musicLowBandDataUrl"];
220 |
221 | [self shareToWeixinWithMediaMessage:aScene
222 | Title:title
223 | Description:description
224 | Object:musicObject
225 | MessageExt:messageExt
226 | MessageAction:messageAction
227 | ThumbImage:aThumbImage
228 | MediaTag:mediaTagName
229 | callBack:callback];
230 |
231 | } else if ([type isEqualToString:RCTWXShareTypeVideo]) {
232 | WXVideoObject *videoObject = [WXVideoObject new];
233 | videoObject.videoUrl = aData[@"videoUrl"];
234 | videoObject.videoLowBandUrl = aData[@"videoLowBandUrl"];
235 |
236 | [self shareToWeixinWithMediaMessage:aScene
237 | Title:title
238 | Description:description
239 | Object:videoObject
240 | MessageExt:messageExt
241 | MessageAction:messageAction
242 | ThumbImage:aThumbImage
243 | MediaTag:mediaTagName
244 | callBack:callback];
245 |
246 | } else if ([type isEqualToString:RCTWXShareTypeImageUrl] ||
247 | [type isEqualToString:RCTWXShareTypeImageFile] ||
248 | [type isEqualToString:RCTWXShareTypeImageResource]) {
249 | NSURL *url = [NSURL URLWithString:aData[RCTWXShareImageUrl]];
250 | NSURLRequest *imageRequest = [NSURLRequest requestWithURL:url];
251 | [self.bridge.imageLoader loadImageWithURLRequest:imageRequest callback:^(NSError *error, UIImage *image) {
252 | if (image == nil){
253 | callback(@[@"fail to load image resource"]);
254 | } else {
255 | WXImageObject *imageObject = [WXImageObject object];
256 | imageObject.imageData = UIImagePNGRepresentation(image);
257 |
258 | [self shareToWeixinWithMediaMessage:aScene
259 | Title:title
260 | Description:description
261 | Object:imageObject
262 | MessageExt:messageExt
263 | MessageAction:messageAction
264 | ThumbImage:aThumbImage
265 | MediaTag:mediaTagName
266 | callBack:callback];
267 |
268 | }
269 | }];
270 | } else if ([type isEqualToString:RCTWXShareTypeFile]) {
271 | NSString * filePath = aData[@"filePath"];
272 | NSString * fileExtension = aData[@"fileExtension"];
273 |
274 | WXFileObject *fileObject = [WXFileObject object];
275 | fileObject.fileData = [NSData dataWithContentsOfFile:filePath];
276 | fileObject.fileExtension = fileExtension;
277 |
278 | [self shareToWeixinWithMediaMessage:aScene
279 | Title:title
280 | Description:description
281 | Object:fileObject
282 | MessageExt:messageExt
283 | MessageAction:messageAction
284 | ThumbImage:aThumbImage
285 | MediaTag:mediaTagName
286 | callBack:callback];
287 |
288 | } else {
289 | callback(@[@"message type unsupported"]);
290 | }
291 | }
292 | }
293 |
294 |
295 | - (void)shareToWeixinWithData:(NSDictionary *)aData scene:(int)aScene callback:(RCTResponseSenderBlock)aCallBack
296 | {
297 | NSString *imageUrl = aData[RCTWXShareTypeThumbImageUrl];
298 | if (imageUrl.length && _bridge.imageLoader) {
299 | NSURL *url = [NSURL URLWithString:imageUrl];
300 | NSURLRequest *imageRequest = [NSURLRequest requestWithURL:url];
301 | [_bridge.imageLoader loadImageWithURLRequest:imageRequest size:CGSizeMake(100, 100) scale:1 clipped:FALSE resizeMode:RCTResizeModeStretch progressBlock:nil partialLoadBlock:nil
302 | completionBlock:^(NSError *error, UIImage *image) {
303 | [self shareToWeixinWithData:aData thumbImage:image scene:aScene callBack:aCallBack];
304 | }];
305 | } else {
306 | [self shareToWeixinWithData:aData thumbImage:nil scene:aScene callBack:aCallBack];
307 | }
308 |
309 | }
310 |
311 | - (void)shareToWeixinWithTextMessage:(int)aScene
312 | Text:(NSString *)text
313 | callBack:(RCTResponseSenderBlock)callback
314 | {
315 | SendMessageToWXReq* req = [SendMessageToWXReq new];
316 | req.bText = YES;
317 | req.scene = aScene;
318 | req.text = text;
319 |
320 | BOOL success = [WXApi sendReq:req];
321 | callback(@[success ? [NSNull null] : INVOKE_FAILED]);
322 | }
323 |
324 | - (void)shareToWeixinWithMediaMessage:(int)aScene
325 | Title:(NSString *)title
326 | Description:(NSString *)description
327 | Object:(id)mediaObject
328 | MessageExt:(NSString *)messageExt
329 | MessageAction:(NSString *)action
330 | ThumbImage:(UIImage *)thumbImage
331 | MediaTag:(NSString *)tagName
332 | callBack:(RCTResponseSenderBlock)callback
333 | {
334 | WXMediaMessage *message = [WXMediaMessage message];
335 | message.title = title;
336 | message.description = description;
337 | message.mediaObject = mediaObject;
338 | message.messageExt = messageExt;
339 | message.messageAction = action;
340 | message.mediaTagName = tagName;
341 | [message setThumbImage:thumbImage];
342 |
343 | SendMessageToWXReq* req = [SendMessageToWXReq new];
344 | req.bText = NO;
345 | req.scene = aScene;
346 | req.message = message;
347 |
348 | BOOL success = [WXApi sendReq:req];
349 | callback(@[success ? [NSNull null] : INVOKE_FAILED]);
350 | }
351 |
352 | #pragma mark - wx callback
353 |
354 | -(void) onReq:(BaseReq*)req
355 | {
356 | // TODO(Yorkie)
357 | }
358 |
359 | -(void) onResp:(BaseResp*)resp
360 | {
361 | if([resp isKindOfClass:[SendMessageToWXResp class]])
362 | {
363 | SendMessageToWXResp *r = (SendMessageToWXResp *)resp;
364 |
365 | NSMutableDictionary *body = @{@"errCode":@(r.errCode)}.mutableCopy;
366 | body[@"errStr"] = r.errStr;
367 | body[@"lang"] = r.lang;
368 | body[@"country"] =r.country;
369 | body[@"type"] = @"SendMessageToWX.Resp";
370 | [self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body];
371 | } else if ([resp isKindOfClass:[SendAuthResp class]]) {
372 | SendAuthResp *r = (SendAuthResp *)resp;
373 | NSMutableDictionary *body = @{@"errCode":@(r.errCode)}.mutableCopy;
374 | body[@"errStr"] = r.errStr;
375 | body[@"state"] = r.state;
376 | body[@"lang"] = r.lang;
377 | body[@"country"] =r.country;
378 | body[@"type"] = @"SendAuth.Resp";
379 |
380 | if (resp.errCode == WXSuccess) {
381 | if (self.appId && r) {
382 | // ios第一次获取不到appid会卡死,加个判断OK
383 | [body addEntriesFromDictionary:@{@"appid":self.appId, @"code":r.code}];
384 | [self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body];
385 | }
386 | }
387 | else {
388 | [self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body];
389 | }
390 | } else if ([resp isKindOfClass:[PayResp class]]) {
391 | PayResp *r = (PayResp *)resp;
392 | NSMutableDictionary *body = @{@"errCode":@(r.errCode)}.mutableCopy;
393 | body[@"errStr"] = r.errStr;
394 | body[@"type"] = @(r.type);
395 | body[@"returnKey"] =r.returnKey;
396 | body[@"type"] = @"PayReq.Resp";
397 | [self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body];
398 | }
399 | }
400 |
401 | @end
402 |
--------------------------------------------------------------------------------
/ios/RCTWeChat.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod spec lint RCTPili.podspec' to ensure this is a
3 | # valid spec and to remove all comments including this before submitting the spec.
4 | #
5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
7 | #
8 |
9 | Pod::Spec.new do |s|
10 | s.name = "RCTWeChat"
11 | s.version = "0.1.0"
12 | s.summary = "React-Native(iOS/Android) functionalities include WeChat Login, Share, Favorite and Payment {QQ: 336021910}"
13 |
14 | # This description is used to generate tags and improve search results.
15 | # * Think: What does it do? Why did you write it? What is the focus?
16 | # * Try to keep it short, snappy and to the point.
17 | # * Write the description between the DESC delimiters below.
18 | # * Finally, don't worry about the indent, CocoaPods strips it!
19 | s.description = <<-DESC
20 | React-Native(iOS/Android) functionalities include WeChat Login, Share, Favorite and Payment {QQ: 336021910}
21 | DESC
22 |
23 | s.homepage = "https://github.com/weflex/react-native-wechat"
24 | s.license = "MIT"
25 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" }
26 | s.author = { "weflex" => "336021910@qq.com" }
27 | s.platform = :ios, "7.0"
28 | s.source = { :git => "https://github.com/weflex/react-native-wechat.git", :tag => "master" }
29 | s.source_files = "**/*.{h,m}"
30 | s.requires_arc = true
31 |
32 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
33 | s.dependency "React"
34 | s.vendored_libraries = "libWeChatSDK.a"
35 | s.ios.frameworks = 'SystemConfiguration','CoreTelephony','XCTest'
36 | s.ios.library = 'sqlite3','c++','z'
37 |
38 | end
39 |
--------------------------------------------------------------------------------
/ios/RCTWeChat.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/RCTWeChat.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/RCTWeChat.xcodeproj/project.xcworkspace/xcuserdata/yorkie.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/ios/RCTWeChat.xcodeproj/project.xcworkspace/xcuserdata/yorkie.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ios/RCTWeChat.xcodeproj/project.xcworkspace/xcuserdata/yorkieliu.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/ios/RCTWeChat.xcodeproj/project.xcworkspace/xcuserdata/yorkieliu.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ios/RCTWeChat.xcodeproj/xcshareddata/xcschemes/RCTWeChat.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
55 |
61 |
62 |
63 |
64 |
65 |
66 |
72 |
73 |
79 |
80 |
81 |
82 |
84 |
85 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/ios/RCTWeChat.xcodeproj/xcshareddata/xcschemes/RCTWeChatTests.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
65 |
71 |
72 |
73 |
74 |
78 |
79 |
80 |
81 |
82 |
83 |
89 |
90 |
96 |
97 |
98 |
99 |
101 |
102 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/ios/RCTWeChatTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ios/RCTWeChatTests/RCTWeChatTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCTWeChatTests.m
3 | // RCTWeChatTests
4 | //
5 | // Created by Yorkie on 12/07/2017.
6 | // Copyright © 2017 WeFlex. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface RCTWeChatTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation RCTWeChatTests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 | // Put setup code here. This method is called before the invocation of each test method in the class.
20 | }
21 |
22 | - (void)tearDown {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | [super tearDown];
25 | }
26 |
27 | - (void)testExample {
28 | // This is an example of a functional test case.
29 | // Use XCTAssert and related functions to verify your tests produce the correct results.
30 | }
31 |
32 | - (void)testPerformanceExample {
33 | // This is an example of a performance test case.
34 | [self measureBlock:^{
35 | // Put the code you want to measure the time of here.
36 | }];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/ios/WXApi.h:
--------------------------------------------------------------------------------
1 | //
2 | // WXApi.h
3 | // 所有Api接口
4 | //
5 | // Created by Wechat on 12-2-28.
6 | // Copyright (c) 2012年 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "WXApiObject.h"
11 |
12 |
13 | #pragma mark - WXApiDelegate
14 | /*! @brief 接收并处理来自微信终端程序的事件消息
15 | *
16 | * 接收并处理来自微信终端程序的事件消息,期间微信界面会切换到第三方应用程序。
17 | * WXApiDelegate 会在handleOpenURL:delegate:中使用并触发。
18 | */
19 | @protocol WXApiDelegate
20 | @optional
21 |
22 | /*! @brief 收到一个来自微信的请求,第三方应用程序处理完后调用sendResp向微信发送结果
23 | *
24 | * 收到一个来自微信的请求,异步处理完成后必须调用sendResp发送处理结果给微信。
25 | * 可能收到的请求有GetMessageFromWXReq、ShowMessageFromWXReq等。
26 | * @param req 具体请求内容,是自动释放的
27 | */
28 | -(void) onReq:(BaseReq*)req;
29 |
30 |
31 |
32 | /*! @brief 发送一个sendReq后,收到微信的回应
33 | *
34 | * 收到一个来自微信的处理结果。调用一次sendReq后会收到onResp。
35 | * 可能收到的处理结果有SendMessageToWXResp、SendAuthResp等。
36 | * @param resp具体的回应内容,是自动释放的
37 | */
38 | -(void) onResp:(BaseResp*)resp;
39 |
40 | @end
41 |
42 |
43 |
44 | #pragma mark - WXApi
45 |
46 | /*! @brief 微信Api接口函数类
47 | *
48 | * 该类封装了微信终端SDK的所有接口
49 | */
50 | @interface WXApi : NSObject
51 |
52 | /*! @brief WXApi的成员函数,向微信终端程序注册第三方应用。
53 | *
54 | * 需要在每次启动第三方应用程序时调用。第一次调用后,会在微信的可用应用列表中出现。
55 | * iOS7及以上系统需要调起一次微信才会出现在微信的可用应用列表中。
56 | * @attention 请保证在主线程中调用此函数
57 | * @param appid 微信开发者ID
58 | * @param typeFlag 应用支持打开的文件类型
59 | * @return 成功返回YES,失败返回NO。
60 | */
61 | +(BOOL) registerApp:(NSString *)appid;
62 |
63 |
64 | /*! @brief WXApi的成员函数,向微信终端程序注册第三方应用。
65 | *
66 | * 需要在每次启动第三方应用程序时调用。第一次调用后,会在微信的可用应用列表中出现。
67 | * @see registerApp
68 | * @param appid 微信开发者ID
69 | * @param appdesc 应用附加信息,长度不超过1024字节
70 | * @return 成功返回YES,失败返回NO。
71 | */
72 | +(BOOL) registerApp:(NSString *)appid withDescription:(NSString *)appdesc;
73 |
74 |
75 | /*! @brief WXApi的成员函数,向微信终端程序注册应用支持打开的文件类型。
76 | *
77 | * 需要在每次启动第三方应用程序时调用。调用后并第一次成功分享数据到微信后,会在微信的可用应用列表中出现。
78 | * @see registerApp
79 | * @param typeFlag 应用支持打开的数据类型, enAppSupportContentFlag枚举类型 “|” 操作后结果
80 | */
81 | +(void) registerAppSupportContentFlag:(UInt64)typeFlag;
82 |
83 |
84 |
85 | /*! @brief 处理微信通过URL启动App时传递的数据
86 | *
87 | * 需要在 application:openURL:sourceApplication:annotation:或者application:handleOpenURL中调用。
88 | * @param url 微信启动第三方应用时传递过来的URL
89 | * @param delegate WXApiDelegate对象,用来接收微信触发的消息。
90 | * @return 成功返回YES,失败返回NO。
91 | */
92 | +(BOOL) handleOpenURL:(NSURL *) url delegate:(id) delegate;
93 |
94 |
95 |
96 | /*! @brief 检查微信是否已被用户安装
97 | *
98 | * @return 微信已安装返回YES,未安装返回NO。
99 | */
100 | +(BOOL) isWXAppInstalled;
101 |
102 |
103 |
104 | /*! @brief 判断当前微信的版本是否支持OpenApi
105 | *
106 | * @return 支持返回YES,不支持返回NO。
107 | */
108 | +(BOOL) isWXAppSupportApi;
109 |
110 |
111 |
112 | /*! @brief 获取微信的itunes安装地址
113 | *
114 | * @return 微信的安装地址字符串。
115 | */
116 | +(NSString *) getWXAppInstallUrl;
117 |
118 |
119 |
120 | /*! @brief 获取当前微信SDK的版本号
121 | *
122 | * @return 返回当前微信SDK的版本号
123 | */
124 | +(NSString *) getApiVersion;
125 |
126 |
127 |
128 | /*! @brief 打开微信
129 | *
130 | * @return 成功返回YES,失败返回NO。
131 | */
132 | +(BOOL) openWXApp;
133 |
134 |
135 |
136 | /*! @brief 发送请求到微信,等待微信返回onResp
137 | *
138 | * 函数调用后,会切换到微信的界面。第三方应用程序等待微信返回onResp。微信在异步处理完成后一定会调用onResp。支持以下类型
139 | * SendAuthReq、SendMessageToWXReq、PayReq等。
140 | * @param req 具体的发送请求,在调用函数后,请自己释放。
141 | * @return 成功返回YES,失败返回NO。
142 | */
143 | +(BOOL) sendReq:(BaseReq*)req;
144 |
145 | /*! @brief 发送Auth请求到微信,支持用户没安装微信,等待微信返回onResp
146 | *
147 | * 函数调用后,会切换到微信的界面。第三方应用程序等待微信返回onResp。微信在异步处理完成后一定会调用onResp。支持SendAuthReq类型。
148 | * @param req 具体的发送请求,在调用函数后,请自己释放。
149 | * @param viewController 当前界面对象。
150 | * @param delegate WXApiDelegate对象,用来接收微信触发的消息。
151 | * @return 成功返回YES,失败返回NO。
152 | */
153 | +(BOOL) sendAuthReq:(SendAuthReq*)req viewController:(UIViewController*)viewController delegate:(id)delegate;
154 |
155 |
156 | /*! @brief 收到微信onReq的请求,发送对应的应答给微信,并切换到微信界面
157 | *
158 | * 函数调用后,会切换到微信的界面。第三方应用程序收到微信onReq的请求,异步处理该请求,完成后必须调用该函数。可能发送的相应有
159 | * GetMessageFromWXResp、ShowMessageFromWXResp等。
160 | * @param resp 具体的应答内容,调用函数后,请自己释放
161 | * @return 成功返回YES,失败返回NO。
162 | */
163 | +(BOOL) sendResp:(BaseResp*)resp;
164 |
165 |
166 | @end
167 |
--------------------------------------------------------------------------------
/ios/WXApiObject.h:
--------------------------------------------------------------------------------
1 | //
2 | // MMApiObject.h
3 | // Api对象,包含所有接口和对象数据定义
4 | //
5 | // Created by Wechat on 12-2-28.
6 | // Copyright (c) 2012年 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /*! @brief 错误码
12 | *
13 | */
14 | enum WXErrCode {
15 | WXSuccess = 0, /**< 成功 */
16 | WXErrCodeCommon = -1, /**< 普通错误类型 */
17 | WXErrCodeUserCancel = -2, /**< 用户点击取消并返回 */
18 | WXErrCodeSentFail = -3, /**< 发送失败 */
19 | WXErrCodeAuthDeny = -4, /**< 授权失败 */
20 | WXErrCodeUnsupport = -5, /**< 微信不支持 */
21 | };
22 |
23 |
24 |
25 | /*! @brief 请求发送场景
26 | *
27 | */
28 | enum WXScene {
29 | WXSceneSession = 0, /**< 聊天界面 */
30 | WXSceneTimeline = 1, /**< 朋友圈 */
31 | WXSceneFavorite = 2, /**< 收藏 */
32 | };
33 |
34 |
35 |
36 | enum WXAPISupport {
37 | WXAPISupportSession = 0,
38 | };
39 |
40 |
41 |
42 | /*! @brief 跳转profile类型
43 | *
44 | */
45 | enum WXBizProfileType{
46 | WXBizProfileType_Normal = 0, //**< 普通公众号 */
47 | WXBizProfileType_Device = 1, //**< 硬件公众号 */
48 | };
49 |
50 |
51 |
52 | /*! @brief 跳转mp网页类型
53 | *
54 | */
55 | enum WXMPWebviewType {
56 | WXMPWebviewType_Ad = 0, /**< 广告网页 **/
57 | };
58 |
59 |
60 | /*! @brief 应用支持接收微信的文件类型
61 | *
62 | */
63 | typedef NS_ENUM(UInt64, enAppSupportContentFlag)
64 | {
65 | MMAPP_SUPPORT_NOCONTENT = 0x0,
66 | MMAPP_SUPPORT_TEXT = 0x1,
67 | MMAPP_SUPPORT_PICTURE = 0x2,
68 | MMAPP_SUPPORT_LOCATION = 0x4,
69 | MMAPP_SUPPORT_VIDEO = 0x8,
70 | MMAPP_SUPPORT_AUDIO = 0x10,
71 | MMAPP_SUPPORT_WEBPAGE = 0x20,
72 |
73 | // Suport File Type
74 | MMAPP_SUPPORT_DOC = 0x40, // doc
75 | MMAPP_SUPPORT_DOCX = 0x80, // docx
76 | MMAPP_SUPPORT_PPT = 0x100, // ppt
77 | MMAPP_SUPPORT_PPTX = 0x200, // pptx
78 | MMAPP_SUPPORT_XLS = 0x400, // xls
79 | MMAPP_SUPPORT_XLSX = 0x800, // xlsx
80 | MMAPP_SUPPORT_PDF = 0x1000, // pdf
81 | };
82 |
83 | #pragma mark - BaseReq
84 | /*! @brief 该类为微信终端SDK所有请求类的基类
85 | *
86 | */
87 | @interface BaseReq : NSObject
88 |
89 | /** 请求类型 */
90 | @property (nonatomic, assign) int type;
91 | /** 由用户微信号和AppID组成的唯一标识,发送请求时第三方程序必须填写,用于校验微信用户是否换号登录*/
92 | @property (nonatomic, retain) NSString* openID;
93 |
94 | @end
95 |
96 |
97 |
98 | #pragma mark - BaseResp
99 | /*! @brief 该类为微信终端SDK所有响应类的基类
100 | *
101 | */
102 | @interface BaseResp : NSObject
103 | /** 错误码 */
104 | @property (nonatomic, assign) int errCode;
105 | /** 错误提示字符串 */
106 | @property (nonatomic, retain) NSString *errStr;
107 | /** 响应类型 */
108 | @property (nonatomic, assign) int type;
109 |
110 | @end
111 |
112 |
113 |
114 | #pragma mark - WXMediaMessage
115 | @class WXMediaMessage;
116 |
117 | /*! @brief 第三方向微信终端发起支付的消息结构体
118 | *
119 | * 第三方向微信终端发起支付的消息结构体,微信终端处理后会向第三方返回处理结果
120 | * @see PayResp
121 | */
122 | @interface PayReq : BaseReq
123 |
124 | /** 商家向财付通申请的商家id */
125 | @property (nonatomic, retain) NSString *partnerId;
126 | /** 预支付订单 */
127 | @property (nonatomic, retain) NSString *prepayId;
128 | /** 随机串,防重发 */
129 | @property (nonatomic, retain) NSString *nonceStr;
130 | /** 时间戳,防重发 */
131 | @property (nonatomic, assign) UInt32 timeStamp;
132 | /** 商家根据财付通文档填写的数据和签名 */
133 | @property (nonatomic, retain) NSString *package;
134 | /** 商家根据微信开放平台文档对数据做的签名 */
135 | @property (nonatomic, retain) NSString *sign;
136 |
137 | @end
138 |
139 |
140 |
141 | #pragma mark - PayResp
142 | /*! @brief 微信终端返回给第三方的关于支付结果的结构体
143 | *
144 | * 微信终端返回给第三方的关于支付结果的结构体
145 | */
146 | @interface PayResp : BaseResp
147 |
148 | /** 财付通返回给商家的信息 */
149 | @property (nonatomic, retain) NSString *returnKey;
150 |
151 | @end
152 |
153 |
154 |
155 | /*! @brief 第三方向微信终端发起拆企业红包的消息结构体
156 | *
157 | * 第三方向微信终端发起拆企业红包的消息结构体,微信终端处理后会向第三方返回处理结果
158 | * @see HBReq
159 | */
160 | @interface HBReq : BaseReq
161 |
162 | /** 随机串,防重发 */
163 | @property (nonatomic, retain) NSString *nonceStr;
164 | /** 时间戳,防重发 */
165 | @property (nonatomic, assign) UInt32 timeStamp;
166 | /** 商家根据微信企业红包开发文档填写的数据和签名 */
167 | @property (nonatomic, retain) NSString *package;
168 | /** 商家根据微信企业红包开发文档对数据做的签名 */
169 | @property (nonatomic, retain) NSString *sign;
170 |
171 | @end
172 |
173 |
174 |
175 | #pragma mark - HBResp
176 | /*! @brief 微信终端返回给第三方的关于拆企业红包结果的结构体
177 | *
178 | * 微信终端返回给第三方的关于拆企业红包结果的结构体
179 | */
180 | @interface HBResp : BaseResp
181 |
182 | @end
183 |
184 |
185 |
186 |
187 | #pragma mark - SendAuthReq
188 | /*! @brief 第三方程序向微信终端请求认证的消息结构
189 | *
190 | * 第三方程序要向微信申请认证,并请求某些权限,需要调用WXApi的sendReq成员函数,
191 | * 向微信终端发送一个SendAuthReq消息结构。微信终端处理完后会向第三方程序发送一个处理结果。
192 | * @see SendAuthResp
193 | */
194 | @interface SendAuthReq : BaseReq
195 | /** 第三方程序要向微信申请认证,并请求某些权限,需要调用WXApi的sendReq成员函数,向微信终端发送一个SendAuthReq消息结构。微信终端处理完后会向第三方程序发送一个处理结果。
196 | * @see SendAuthResp
197 | * @note scope字符串长度不能超过1K
198 | */
199 | @property (nonatomic, retain) NSString* scope;
200 | /** 第三方程序本身用来标识其请求的唯一性,最后跳转回第三方程序时,由微信终端回传。
201 | * @note state字符串长度不能超过1K
202 | */
203 | @property (nonatomic, retain) NSString* state;
204 | @end
205 |
206 |
207 |
208 | #pragma mark - SendAuthResp
209 | /*! @brief 微信处理完第三方程序的认证和权限申请后向第三方程序回送的处理结果。
210 | *
211 | * 第三方程序要向微信申请认证,并请求某些权限,需要调用WXApi的sendReq成员函数,向微信终端发送一个SendAuthReq消息结构。
212 | * 微信终端处理完后会向第三方程序发送一个SendAuthResp。
213 | * @see onResp
214 | */
215 | @interface SendAuthResp : BaseResp
216 | @property (nonatomic, retain) NSString* code;
217 | /** 第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传
218 | * @note state字符串长度不能超过1K
219 | */
220 | @property (nonatomic, retain) NSString* state;
221 | @property (nonatomic, retain) NSString* lang;
222 | @property (nonatomic, retain) NSString* country;
223 | @end
224 |
225 |
226 |
227 | #pragma mark - SendMessageToWXReq
228 | /*! @brief 第三方程序发送消息至微信终端程序的消息结构体
229 | *
230 | * 第三方程序向微信发送信息需要传入SendMessageToWXReq结构体,信息类型包括文本消息和多媒体消息,
231 | * 分别对应于text和message成员。调用该方法后,微信处理完信息会向第三方程序发送一个处理结果。
232 | * @see SendMessageToWXResp
233 | */
234 | @interface SendMessageToWXReq : BaseReq
235 | /** 发送消息的文本内容
236 | * @note 文本长度必须大于0且小于10K
237 | */
238 | @property (nonatomic, retain) NSString* text;
239 | /** 发送消息的多媒体内容
240 | * @see WXMediaMessage
241 | */
242 | @property (nonatomic, retain) WXMediaMessage* message;
243 | /** 发送消息的类型,包括文本消息和多媒体消息两种,两者只能选择其一,不能同时发送文本和多媒体消息 */
244 | @property (nonatomic, assign) BOOL bText;
245 | /** 发送的目标场景,可以选择发送到会话(WXSceneSession)或者朋友圈(WXSceneTimeline)。 默认发送到会话。
246 | * @see WXScene
247 | */
248 | @property (nonatomic, assign) int scene;
249 |
250 | @end
251 |
252 |
253 |
254 | #pragma mark - SendMessageToWXResp
255 | /*! @brief 微信终端向第三方程序返回的SendMessageToWXReq处理结果。
256 | *
257 | * 第三方程序向微信终端发送SendMessageToWXReq后,微信发送回来的处理结果,该结果用SendMessageToWXResp表示。
258 | */
259 | @interface SendMessageToWXResp : BaseResp
260 | @property(nonatomic, retain) NSString* lang;
261 | @property(nonatomic, retain) NSString* country;
262 | @end
263 |
264 |
265 |
266 | #pragma mark - GetMessageFromWXReq
267 | /*! @brief 微信终端向第三方程序请求提供内容的消息结构体。
268 | *
269 | * 微信终端向第三方程序请求提供内容,微信终端会向第三方程序发送GetMessageFromWXReq消息结构体,
270 | * 需要第三方程序调用sendResp返回一个GetMessageFromWXResp消息结构体。
271 | */
272 | @interface GetMessageFromWXReq : BaseReq
273 | @property (nonatomic, retain) NSString* lang;
274 | @property (nonatomic, retain) NSString* country;
275 | @end
276 |
277 |
278 |
279 | #pragma mark - GetMessageFromWXResp
280 | /*! @brief 微信终端向第三方程序请求提供内容,第三方程序向微信终端返回的消息结构体。
281 | *
282 | * 微信终端向第三方程序请求提供内容,第三方程序调用sendResp向微信终端返回一个GetMessageFromWXResp消息结构体。
283 | */
284 | @interface GetMessageFromWXResp : BaseResp
285 | /** 向微信终端提供的文本内容
286 | @note 文本长度必须大于0且小于10K
287 | */
288 | @property (nonatomic, retain) NSString* text;
289 | /** 向微信终端提供的多媒体内容。
290 | * @see WXMediaMessage
291 | */
292 | @property (nonatomic, retain) WXMediaMessage* message;
293 | /** 向微信终端提供内容的消息类型,包括文本消息和多媒体消息两种,两者只能选择其一,不能同时发送文本和多媒体消息 */
294 | @property (nonatomic, assign) BOOL bText;
295 | @end
296 |
297 |
298 |
299 | #pragma mark - ShowMessageFromWXReq
300 | /*! @brief 微信通知第三方程序,要求第三方程序显示的消息结构体。
301 | *
302 | * 微信需要通知第三方程序显示或处理某些内容时,会向第三方程序发送ShowMessageFromWXReq消息结构体。
303 | * 第三方程序处理完内容后调用sendResp向微信终端发送ShowMessageFromWXResp。
304 | */
305 | @interface ShowMessageFromWXReq : BaseReq
306 | /** 微信终端向第三方程序发送的要求第三方程序处理的多媒体内容
307 | * @see WXMediaMessage
308 | */
309 | @property (nonatomic, retain) WXMediaMessage* message;
310 | @property (nonatomic, retain) NSString* lang;
311 | @property (nonatomic, retain) NSString* country;
312 | @end
313 |
314 |
315 |
316 | #pragma mark - ShowMessageFromWXResp
317 | /*! @brief 微信通知第三方程序,要求第三方程序显示或处理某些消息,第三方程序处理完后向微信终端发送的处理结果。
318 | *
319 | * 微信需要通知第三方程序显示或处理某些内容时,会向第三方程序发送ShowMessageFromWXReq消息结构体。
320 | * 第三方程序处理完内容后调用sendResp向微信终端发送ShowMessageFromWXResp。
321 | */
322 | @interface ShowMessageFromWXResp : BaseResp
323 | @end
324 |
325 |
326 |
327 | #pragma mark - LaunchFromWXReq
328 | /*! @brief 微信终端打开第三方程序携带的消息结构体
329 | *
330 | * 微信向第三方发送的结构体,第三方不需要返回
331 | */
332 | @interface LaunchFromWXReq : BaseReq
333 | @property (nonatomic, retain) WXMediaMessage* message;
334 | @property (nonatomic, retain) NSString* lang;
335 | @property (nonatomic, retain) NSString* country;
336 | @end
337 |
338 | #pragma mark - OpenTempSessionReq
339 | /* ! @brief 第三方通知微信,打开临时会话
340 | *
341 | * 第三方通知微信,打开临时会话
342 | */
343 | @interface OpenTempSessionReq : BaseReq
344 | /** 需要打开的用户名
345 | * @attention 长度不能超过512字节
346 | */
347 | @property (nonatomic, retain) NSString* username;
348 | /** 开发者自定义参数,拉起临时会话后会发给开发者后台,可以用于识别场景
349 | * @attention 长度不能超过32位
350 | */
351 | @property (nonatomic, retain) NSString* sessionFrom;
352 | @end
353 |
354 | #pragma mark - OpenWebviewReq
355 | /* ! @brief 第三方通知微信启动内部浏览器,打开指定网页
356 | *
357 | * 第三方通知微信启动内部浏览器,打开指定Url对应的网页
358 | */
359 | @interface OpenWebviewReq : BaseReq
360 | /** 需要打开的网页对应的Url
361 | * @attention 长度不能超过1024
362 | */
363 | @property(nonatomic,retain)NSString* url;
364 |
365 | @end
366 |
367 | #pragma mark - OpenWebviewResp
368 | /*! @brief 微信终端向第三方程序返回的OpenWebviewReq处理结果
369 | *
370 | * 第三方程序向微信终端发送OpenWebviewReq后,微信发送回来的处理结果,该结果用OpenWebviewResp表示
371 | */
372 | @interface OpenWebviewResp : BaseResp
373 |
374 | @end
375 |
376 |
377 | #pragma mark - OpenTempSessionResp
378 | /*! @brief 微信终端向第三方程序返回的OpenTempSessionReq处理结果。
379 | *
380 | * 第三方程序向微信终端发送OpenTempSessionReq后,微信发送回来的处理结果,该结果用OpenTempSessionResp表示。
381 | */
382 | @interface OpenTempSessionResp : BaseResp
383 |
384 | @end
385 |
386 | #pragma mark - OpenRankListReq
387 | /* ! @brief 第三方通知微信,打开硬件排行榜
388 | *
389 | * 第三方通知微信,打开硬件排行榜
390 | */
391 | @interface OpenRankListReq : BaseReq
392 |
393 | @end
394 |
395 | #pragma mark - OpenRanklistResp
396 | /*! @brief 微信终端向第三方程序返回的OpenRankListReq处理结果。
397 | *
398 | * 第三方程序向微信终端发送OpenRankListReq后,微信发送回来的处理结果,该结果用OpenRankListResp表示。
399 | */
400 | @interface OpenRankListResp : BaseResp
401 |
402 | @end
403 |
404 | #pragma mark - JumpToBizProfileReq
405 | /* ! @brief 第三方通知微信,打开指定微信号profile页面
406 | *
407 | * 第三方通知微信,打开指定微信号profile页面
408 | */
409 | @interface JumpToBizProfileReq : BaseReq
410 | /** 跳转到该公众号的profile
411 | * @attention 长度不能超过512字节
412 | */
413 | @property (nonatomic, retain) NSString* username;
414 | /** 如果用户加了该公众号为好友,extMsg会上传到服务器
415 | * @attention 长度不能超过1024字节
416 | */
417 | @property (nonatomic, retain) NSString* extMsg;
418 | /**
419 | * 跳转的公众号类型
420 | * @see WXBizProfileType
421 | */
422 | @property (nonatomic, assign) int profileType;
423 | @end
424 |
425 |
426 |
427 | #pragma mark - JumpToBizWebviewReq
428 | /* ! @brief 第三方通知微信,打开指定usrname的profile网页版
429 | *
430 | */
431 | @interface JumpToBizWebviewReq : BaseReq
432 | /** 跳转的网页类型,目前只支持广告页
433 | * @see WXMPWebviewType
434 | */
435 | @property(nonatomic, assign) int webType;
436 | /** 跳转到该公众号的profile网页版
437 | * @attention 长度不能超过512字节
438 | */
439 | @property(nonatomic, retain) NSString* tousrname;
440 | /** 如果用户加了该公众号为好友,extMsg会上传到服务器
441 | * @attention 长度不能超过1024字节
442 | */
443 | @property(nonatomic, retain) NSString* extMsg;
444 |
445 | @end
446 |
447 | #pragma mark - WXCardItem
448 |
449 | @interface WXCardItem : NSObject
450 | /** 卡id
451 | * @attention 长度不能超过1024字节
452 | */
453 | @property (nonatomic,retain) NSString* cardId;
454 | /** ext信息
455 | * @attention 长度不能超过2024字节
456 | */
457 | @property (nonatomic,retain) NSString* extMsg;
458 | /**
459 | * @attention 卡的状态,req不需要填。resp:0为未添加,1为已添加。
460 | */
461 | @property (nonatomic,assign) UInt32 cardState;
462 | /**
463 | * @attention req不需要填,chooseCard返回的。
464 | */
465 | @property (nonatomic,retain) NSString* encryptCode;
466 | /**
467 | * @attention req不需要填,chooseCard返回的。
468 | */
469 | @property (nonatomic,retain) NSString* appID;
470 | @end;
471 |
472 | #pragma mark - AddCardToWXCardPackageReq
473 | /* ! @brief 请求添加卡券至微信卡包
474 | *
475 | */
476 |
477 | @interface AddCardToWXCardPackageReq : BaseReq
478 | /** 卡列表
479 | * @attention 个数不能超过40个 类型WXCardItem
480 | */
481 | @property (nonatomic,retain) NSArray* cardAry;
482 |
483 | @end
484 |
485 |
486 | #pragma mark - AddCardToWXCardPackageResp
487 | /** ! @brief 微信返回第三方添加卡券结果
488 | *
489 | */
490 |
491 | @interface AddCardToWXCardPackageResp : BaseResp
492 | /** 卡列表
493 | * @attention 个数不能超过40个 类型WXCardItem
494 | */
495 | @property (nonatomic,retain) NSArray* cardAry;
496 | @end
497 |
498 | #pragma mark - WXChooseCardReq
499 | /* ! @brief 请求从微信选取卡券
500 | *
501 | */
502 |
503 | @interface WXChooseCardReq : BaseReq
504 | @property(nonatomic, strong) NSString *appID;
505 | @property(nonatomic, assign) UInt32 shopID;
506 | @property(nonatomic, assign) UInt32 canMultiSelect;
507 | @property(nonatomic, strong) NSString *cardType;
508 | @property(nonatomic, strong) NSString *cardTpID;
509 | @property(nonatomic, strong) NSString *signType;
510 | @property(nonatomic, strong) NSString *cardSign;
511 | @property(nonatomic, assign) UInt32 timeStamp;
512 | @property(nonatomic, strong) NSString *nonceStr;
513 | @end
514 |
515 |
516 | #pragma mark - WXChooseCardResp
517 | /** ! @brief 微信返回第三方请求选择卡券结果
518 | *
519 | */
520 |
521 | @interface WXChooseCardResp : BaseResp
522 | @property (nonatomic,retain) NSArray* cardAry;
523 | @end
524 |
525 | #pragma mark - WXMediaMessage
526 |
527 | /*! @brief 多媒体消息结构体
528 | *
529 | * 用于微信终端和第三方程序之间传递消息的多媒体消息内容
530 | */
531 | @interface WXMediaMessage : NSObject
532 |
533 | +(WXMediaMessage *) message;
534 |
535 | /** 标题
536 | * @note 长度不能超过512字节
537 | */
538 | @property (nonatomic, retain) NSString *title;
539 | /** 描述内容
540 | * @note 长度不能超过1K
541 | */
542 | @property (nonatomic, retain) NSString *description;
543 | /** 缩略图数据
544 | * @note 大小不能超过32K
545 | */
546 | @property (nonatomic, retain) NSData *thumbData;
547 | /**
548 | * @note 长度不能超过64字节
549 | */
550 | @property (nonatomic, retain) NSString *mediaTagName;
551 | /**
552 | *
553 | */
554 | @property (nonatomic, retain) NSString *messageExt;
555 | @property (nonatomic, retain) NSString *messageAction;
556 | /**
557 | * 多媒体数据对象,可以为WXImageObject,WXMusicObject,WXVideoObject,WXWebpageObject等。
558 | */
559 | @property (nonatomic, retain) id mediaObject;
560 |
561 | /*! @brief 设置消息缩略图的方法
562 | *
563 | * @param image 缩略图
564 | * @note 大小不能超过32K
565 | */
566 | - (void) setThumbImage:(UIImage *)image;
567 |
568 | @end
569 |
570 |
571 |
572 | #pragma mark - WXImageObject
573 | /*! @brief 多媒体消息中包含的图片数据对象
574 | *
575 | * 微信终端和第三方程序之间传递消息中包含的图片数据对象。
576 | * @note imageData成员不能为空
577 | * @see WXMediaMessage
578 | */
579 | @interface WXImageObject : NSObject
580 | /*! @brief 返回一个WXImageObject对象
581 | *
582 | * @note 返回的WXImageObject对象是自动释放的
583 | */
584 | +(WXImageObject *) object;
585 |
586 | /** 图片真实数据内容
587 | * @note 大小不能超过10M
588 | */
589 | @property (nonatomic, retain) NSData *imageData;
590 |
591 | @end
592 |
593 |
594 | #pragma mark - WXMusicObject
595 | /*! @brief 多媒体消息中包含的音乐数据对象
596 | *
597 | * 微信终端和第三方程序之间传递消息中包含的音乐数据对象。
598 | * @note musicUrl和musicLowBandUrl成员不能同时为空。
599 | * @see WXMediaMessage
600 | */
601 | @interface WXMusicObject : NSObject
602 | /*! @brief 返回一个WXMusicObject对象
603 | *
604 | * @note 返回的WXMusicObject对象是自动释放的
605 | */
606 | +(WXMusicObject *) object;
607 |
608 | /** 音乐网页的url地址
609 | * @note 长度不能超过10K
610 | */
611 | @property (nonatomic, retain) NSString *musicUrl;
612 | /** 音乐lowband网页的url地址
613 | * @note 长度不能超过10K
614 | */
615 | @property (nonatomic, retain) NSString *musicLowBandUrl;
616 | /** 音乐数据url地址
617 | * @note 长度不能超过10K
618 | */
619 | @property (nonatomic, retain) NSString *musicDataUrl;
620 |
621 | /**音乐lowband数据url地址
622 | * @note 长度不能超过10K
623 | */
624 | @property (nonatomic, retain) NSString *musicLowBandDataUrl;
625 |
626 | @end
627 |
628 |
629 |
630 | #pragma mark - WXVideoObject
631 | /*! @brief 多媒体消息中包含的视频数据对象
632 | *
633 | * 微信终端和第三方程序之间传递消息中包含的视频数据对象。
634 | * @note videoUrl和videoLowBandUrl不能同时为空。
635 | * @see WXMediaMessage
636 | */
637 | @interface WXVideoObject : NSObject
638 | /*! @brief 返回一个WXVideoObject对象
639 | *
640 | * @note 返回的WXVideoObject对象是自动释放的
641 | */
642 | +(WXVideoObject *) object;
643 |
644 | /** 视频网页的url地址
645 | * @note 长度不能超过10K
646 | */
647 | @property (nonatomic, retain) NSString *videoUrl;
648 | /** 视频lowband网页的url地址
649 | * @note 长度不能超过10K
650 | */
651 | @property (nonatomic, retain) NSString *videoLowBandUrl;
652 |
653 | @end
654 |
655 |
656 |
657 | #pragma mark - WXWebpageObject
658 | /*! @brief 多媒体消息中包含的网页数据对象
659 | *
660 | * 微信终端和第三方程序之间传递消息中包含的网页数据对象。
661 | * @see WXMediaMessage
662 | */
663 | @interface WXWebpageObject : NSObject
664 | /*! @brief 返回一个WXWebpageObject对象
665 | *
666 | * @note 返回的WXWebpageObject对象是自动释放的
667 | */
668 | +(WXWebpageObject *) object;
669 |
670 | /** 网页的url地址
671 | * @note 不能为空且长度不能超过10K
672 | */
673 | @property (nonatomic, retain) NSString *webpageUrl;
674 |
675 | @end
676 |
677 |
678 |
679 | #pragma mark - WXAppExtendObject
680 | /*! @brief 多媒体消息中包含的App扩展数据对象
681 | *
682 | * 第三方程序向微信终端发送包含WXAppExtendObject的多媒体消息,
683 | * 微信需要处理该消息时,会调用该第三方程序来处理多媒体消息内容。
684 | * @note url,extInfo和fileData不能同时为空
685 | * @see WXMediaMessage
686 | */
687 | @interface WXAppExtendObject : NSObject
688 | /*! @brief 返回一个WXAppExtendObject对象
689 | *
690 | * @note 返回的WXAppExtendObject对象是自动释放的
691 | */
692 | +(WXAppExtendObject *) object;
693 |
694 | /** 若第三方程序不存在,微信终端会打开该url所指的App下载地址
695 | * @note 长度不能超过10K
696 | */
697 | @property (nonatomic, retain) NSString *url;
698 | /** 第三方程序自定义简单数据,微信终端会回传给第三方程序处理
699 | * @note 长度不能超过2K
700 | */
701 | @property (nonatomic, retain) NSString *extInfo;
702 | /** App文件数据,该数据发送给微信好友,微信好友需要点击后下载数据,微信终端会回传给第三方程序处理
703 | * @note 大小不能超过10M
704 | */
705 | @property (nonatomic, retain) NSData *fileData;
706 |
707 | @end
708 |
709 |
710 |
711 | #pragma mark - WXEmoticonObject
712 | /*! @brief 多媒体消息中包含的表情数据对象
713 | *
714 | * 微信终端和第三方程序之间传递消息中包含的表情数据对象。
715 | * @see WXMediaMessage
716 | */
717 | @interface WXEmoticonObject : NSObject
718 |
719 | /*! @brief 返回一个WXEmoticonObject对象
720 | *
721 | * @note 返回的WXEmoticonObject对象是自动释放的
722 | */
723 | +(WXEmoticonObject *) object;
724 |
725 | /** 表情真实数据内容
726 | * @note 大小不能超过10M
727 | */
728 | @property (nonatomic, retain) NSData *emoticonData;
729 |
730 | @end
731 |
732 |
733 |
734 | #pragma mark - WXFileObject
735 | /*! @brief 多媒体消息中包含的文件数据对象
736 | *
737 | * @see WXMediaMessage
738 | */
739 | @interface WXFileObject : NSObject
740 |
741 | /*! @brief 返回一个WXFileObject对象
742 | *
743 | * @note 返回的WXFileObject对象是自动释放的
744 | */
745 | +(WXFileObject *) object;
746 |
747 | /** 文件后缀名
748 | * @note 长度不超过64字节
749 | */
750 | @property (nonatomic, retain) NSString *fileExtension;
751 |
752 | /** 文件真实数据内容
753 | * @note 大小不能超过10M
754 | */
755 | @property (nonatomic, retain) NSData *fileData;
756 |
757 | @end
758 |
759 |
760 | #pragma mark - WXLocationObject
761 | /*! @brief 多媒体消息中包含的地理位置数据对象
762 | *
763 | * 微信终端和第三方程序之间传递消息中包含的地理位置数据对象。
764 | * @see WXMediaMessage
765 | */
766 | @interface WXLocationObject : NSObject
767 |
768 | /*! @brief 返回一个WXLocationObject对象
769 | *
770 | * @note 返回的WXLocationObject对象是自动释放的
771 | */
772 | +(WXLocationObject *) object;
773 |
774 | /** 地理位置信息
775 | * @note 经纬度
776 | */
777 | @property (nonatomic, assign) double lng; //经度
778 | @property (nonatomic, assign) double lat; //纬度
779 |
780 | @end
781 |
782 |
783 | #pragma mark - WXTextObject
784 | /*! @brief 多媒体消息中包含的文本数据对象
785 | *
786 | * 微信终端和第三方程序之间传递消息中包含的文本数据对象。
787 | * @see WXMediaMessage
788 | */
789 | @interface WXTextObject : NSObject
790 |
791 | /*! @brief 返回一个WXTextObject对象
792 | *
793 | * @note 返回的WXTextObject对象是自动释放的
794 | */
795 | +(WXTextObject *) object;
796 |
797 | /** 地理位置信息
798 | * @note 文本内容
799 | */
800 | @property (nonatomic, retain) NSString *contentText;
801 |
802 | @end
803 |
804 |
--------------------------------------------------------------------------------
/ios/WechatAuthSDK.h:
--------------------------------------------------------------------------------
1 | //
2 | // WechatAuthSDK.h
3 | // WechatAuthSDK
4 | //
5 | // Created by 李凯 on 13-11-29.
6 | // Copyright (c) 2013年 Tencent. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | enum AuthErrCode {
13 | WechatAuth_Err_Ok = 0, //Auth成功
14 | WechatAuth_Err_NormalErr = -1, //普通错误
15 | WechatAuth_Err_NetworkErr = -2, //网络错误
16 | WechatAuth_Err_GetQrcodeFailed = -3, //获取二维码失败
17 | WechatAuth_Err_Cancel = -4, //用户取消授权
18 | WechatAuth_Err_Timeout = -5, //超时
19 | };
20 |
21 | @protocol WechatAuthAPIDelegate
22 | @optional
23 |
24 | - (void)onAuthGotQrcode:(UIImage *)image; //得到二维码
25 | - (void)onQrcodeScanned; //二维码被扫描
26 | - (void)onAuthFinish:(int)errCode AuthCode:(NSString *)authCode; //成功登录
27 |
28 | @end
29 |
30 | @interface WechatAuthSDK : NSObject{
31 | NSString *_sdkVersion;
32 | __weak id _delegate;
33 | }
34 |
35 | @property(nonatomic, weak) id delegate;
36 | @property(nonatomic, readonly) NSString *sdkVersion; //authSDK版本号
37 |
38 | /*! @brief 发送登录请求,等待WechatAuthAPIDelegate回调
39 | *
40 | * @param appId 微信开发者ID
41 | * @param nonceStr 一个随机的尽量不重复的字符串,用来使得每次的signature不同
42 | * @param timeStamp 时间戳
43 | * @param scope 应用授权作用域,拥有多个作用域用逗号(,)分隔
44 | * @param signature 签名
45 | * @param schemeData 会在扫码后拼在scheme后
46 | * @return 成功返回YES,失败返回NO
47 | 注:该实现只保证同时只有一个Auth在运行,Auth未完成或未Stop再次调用Auth接口时会返回NO。
48 | */
49 |
50 | - (BOOL)Auth:(NSString *)appId
51 | nonceStr:(NSString *)nonceStr
52 | timeStamp:(NSString*)timeStamp
53 | scope:(NSString *)scope
54 | signature:(NSString *)signature
55 | schemeData:(NSString *)schemeData;
56 |
57 |
58 | /*! @brief 暂停登录请求
59 | *
60 | * @return 成功返回YES,失败返回NO。
61 | */
62 | - (BOOL)StopAuth;
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/ios/libWeChatSDK.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/ios/libWeChatSDK.a
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-wechat",
3 | "version": "1.9.12",
4 | "description": "react-native library for wechat app",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+ssh://git@github.com/weflex/react-native-wechat.git"
12 | },
13 | "keywords": [
14 | "wechat",
15 | "react",
16 | "react-native",
17 | "react-component",
18 | "ios"
19 | ],
20 | "dependencies": {
21 | "events": "1.0.2"
22 | },
23 | "peerDependencies": {
24 | "react-native": ">=0.40"
25 | },
26 | "author": "Yorkie Liu ",
27 | "contributors": [
28 | {
29 | "name": "Yorkie Liu",
30 | "email": "yorkiefixer@gmail.com"
31 | },
32 | {
33 | "name": "Deng Yun",
34 | "email": "tdzl2003@gmail.com"
35 | }
36 | ],
37 | "license": "MIT",
38 | "bugs": {
39 | "url": "https://github.com/weflex/react-native-wechat/issues"
40 | },
41 | "homepage": "https://github.com/weflex/react-native-wechat#readme"
42 | }
43 |
--------------------------------------------------------------------------------
/playground/.buckconfig:
--------------------------------------------------------------------------------
1 |
2 | [android]
3 | target = Google Inc.:Google APIs:23
4 |
5 | [maven_repositories]
6 | central = https://repo1.maven.org/maven2
7 |
--------------------------------------------------------------------------------
/playground/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | extends: '@react-native-community',
4 | };
5 |
--------------------------------------------------------------------------------
/playground/.flowconfig:
--------------------------------------------------------------------------------
1 | [ignore]
2 | ; We fork some components by platform
3 | .*/*[.]android.js
4 |
5 | ; Ignore "BUCK" generated dirs
6 | /\.buckd/
7 |
8 | ; Ignore unexpected extra "@providesModule"
9 | .*/node_modules/.*/node_modules/fbjs/.*
10 |
11 | ; Ignore duplicate module providers
12 | ; For RN Apps installed via npm, "Libraries" folder is inside
13 | ; "node_modules/react-native" but in the source repo it is in the root
14 | node_modules/react-native/Libraries/react-native/React.js
15 |
16 | ; Ignore polyfills
17 | node_modules/react-native/Libraries/polyfills/.*
18 |
19 | ; These should not be required directly
20 | ; require from fbjs/lib instead: require('fbjs/lib/warning')
21 | node_modules/warning/.*
22 |
23 | ; Flow doesn't support platforms
24 | .*/Libraries/Utilities/HMRLoadingView.js
25 |
26 | [untyped]
27 | .*/node_modules/@react-native-community/cli/.*/.*
28 |
29 | [include]
30 |
31 | [libs]
32 | node_modules/react-native/Libraries/react-native/react-native-interface.js
33 | node_modules/react-native/flow/
34 |
35 | [options]
36 | emoji=true
37 |
38 | esproposal.optional_chaining=enable
39 | esproposal.nullish_coalescing=enable
40 |
41 | module.file_ext=.js
42 | module.file_ext=.json
43 | module.file_ext=.ios.js
44 |
45 | module.system=haste
46 | module.system.haste.use_name_reducers=true
47 | # get basename
48 | module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1'
49 | # strip .js or .js.flow suffix
50 | module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1'
51 | # strip .ios suffix
52 | module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1'
53 | module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1'
54 | module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1'
55 | module.system.haste.paths.blacklist=.*/__tests__/.*
56 | module.system.haste.paths.blacklist=.*/__mocks__/.*
57 | module.system.haste.paths.whitelist=/node_modules/react-native/Libraries/.*
58 | module.system.haste.paths.whitelist=/node_modules/react-native/RNTester/.*
59 | module.system.haste.paths.whitelist=/node_modules/react-native/IntegrationTests/.*
60 | module.system.haste.paths.blacklist=/node_modules/react-native/Libraries/react-native/react-native-implementation.js
61 | module.system.haste.paths.blacklist=/node_modules/react-native/Libraries/Animated/src/polyfills/.*
62 |
63 | munge_underscores=true
64 |
65 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
66 |
67 | suppress_type=$FlowIssue
68 | suppress_type=$FlowFixMe
69 | suppress_type=$FlowFixMeProps
70 | suppress_type=$FlowFixMeState
71 |
72 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)
73 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+
74 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
75 |
76 | [lints]
77 | sketchy-null-number=warn
78 | sketchy-null-mixed=warn
79 | sketchy-number=warn
80 | untyped-type-import=warn
81 | nonstrict-import=warn
82 | deprecated-type=warn
83 | unsafe-getters-setters=warn
84 | inexact-spread=warn
85 | unnecessary-invariant=warn
86 | signature-verification-failure=warn
87 | deprecated-utility=error
88 |
89 | [strict]
90 | deprecated-type
91 | nonstrict-import
92 | sketchy-null
93 | unclear-type
94 | unsafe-getters-setters
95 | untyped-import
96 | untyped-type-import
97 |
98 | [version]
99 | ^0.98.0
100 |
--------------------------------------------------------------------------------
/playground/.gitattributes:
--------------------------------------------------------------------------------
1 | *.pbxproj -text
2 |
--------------------------------------------------------------------------------
/playground/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | project.xcworkspace
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 |
33 | # node.js
34 | #
35 | node_modules/
36 | npm-debug.log
37 | yarn-error.log
38 |
39 | # BUCK
40 | buck-out/
41 | \.buckd/
42 | *.keystore
43 |
44 | # fastlane
45 | #
46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
47 | # screenshots whenever they are needed.
48 | # For more information about the recommended setup visit:
49 | # https://docs.fastlane.tools/best-practices/source-control/
50 |
51 | */fastlane/report.xml
52 | */fastlane/Preview.html
53 | */fastlane/screenshots
54 |
55 | # Bundle artifact
56 | *.jsbundle
57 |
58 | # CocoaPods
59 | /ios/Pods/
60 |
--------------------------------------------------------------------------------
/playground/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/playground/App.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Sample React Native App
3 | * https://github.com/facebook/react-native
4 | *
5 | * @format
6 | * @flow
7 | */
8 |
9 | import React, { Fragment, Component } from 'react';
10 | import {
11 | TouchableOpacity,
12 | SafeAreaView,
13 | ScrollView,
14 | StyleSheet,
15 | StatusBar,
16 | Platform,
17 | View,
18 | Text,
19 | Alert
20 | } from 'react-native';
21 |
22 | import {
23 | Header,
24 | Colors
25 | } from 'react-native/Libraries/NewAppScreen';
26 |
27 | import * as WeChat from 'react-native-wechat';
28 |
29 | export default class App extends Component {
30 | shareOptions = {
31 | title: 'playground',
32 | description: '微信分享测试',
33 | thumbImage: 'https://i.loli.net/2019/09/03/62FauzAY37gsEXV.png',
34 | type: 'news',
35 | webpageUrl: 'https://github.com/yorkie/react-native-wechat'
36 | }
37 | constructor(props) {
38 | super(props);
39 | this.state = {
40 | apiVersion: null,
41 | isWXAppInstalled: false,
42 | wxAppInstallUrl: null,
43 | isWXAppSupportApi: false
44 | }
45 | }
46 | handleOpenApp () {
47 | if (this.state.isWXAppInstalled) {
48 | return WeChat.openWXApp();
49 | } else {
50 | Alert.alert('没有安装微信,请安装之后重试');
51 | }
52 | }
53 | handleShareToSession () {
54 | if (this.state.isWXAppInstalled) {
55 | WeChat.shareToSession(this.shareOptions).catch((error) => {
56 | Alert.alert(error.message);
57 | });
58 | } else {
59 | Alert.alert('没有安装微信,请安装之后重试');
60 | }
61 | }
62 | handleShareToMoment () {
63 | if (this.state.isWXAppInstalled) {
64 | WeChat.shareToTimeline(this.shareOptions).catch((error) => {
65 | Alert.alert(error.message);
66 | });
67 | } else {
68 | Alert.alert('没有安装微信,请安装之后重试');
69 | }
70 | }
71 | async componentDidMount() {
72 | try {
73 | WeChat.registerApp('your wexin AppID'); // Replace with your AppID
74 | this.setState({
75 | apiVersion: await WeChat.getApiVersion(),
76 | wxAppInstallUrl: Platform.OS === 'ios' ? await WeChat.getWXAppInstallUrl(): null,
77 | isWXAppSupportApi: await WeChat.isWXAppSupportApi(),
78 | isWXAppInstalled: await WeChat.isWXAppInstalled()
79 | });
80 | } catch (e) {
81 | console.error(e);
82 | }
83 | }
84 | render() {
85 | const { apiVersion } = this.state;
86 | return (
87 |
88 |
89 |
90 |
93 |
94 |
95 |
96 |
97 | ApiVersion: { apiVersion }
98 |
99 | this.handleOpenApp()}>
100 | 打开微信
101 |
102 | this.handleShareToSession()}>
103 | 分享至微信好友
104 |
105 | this.handleShareToMoment()}>
106 | 分享至朋友圈
107 |
108 |
109 |
110 |
111 |
112 |
113 | );
114 | }
115 | };
116 |
117 | const styles = StyleSheet.create({
118 | scrollView: {
119 | backgroundColor: Colors.lighter
120 | },
121 | body: {
122 | backgroundColor: Colors.white
123 | },
124 | sectionContainer: {
125 | marginTop: 32,
126 | paddingHorizontal: 24
127 | },
128 | highlight: {
129 | fontSize: 24,
130 | fontWeight: '600',
131 | color: Colors.black,
132 | textAlign: 'center'
133 | },
134 | button: {
135 | flex: 1,
136 | margin: 10,
137 | borderWidth: 1,
138 | borderRadius: 30,
139 | paddingVertical: 12,
140 | alignItems: 'center',
141 | justifyContent: 'center',
142 | borderColor: Colors.black
143 | }
144 | });
145 |
--------------------------------------------------------------------------------
/playground/README.md:
--------------------------------------------------------------------------------
1 | # Playground for react-native-wechat
2 |
3 | Make sure you have the development environment set up with this [Tutorial](https://facebook.github.io/react-native/docs/getting-started) at first.
4 |
5 | 首先确保已经按[教程](https://facebook.github.io/react-native/docs/getting-started)配置好 React Native 本地开发环境。
6 |
7 | ## How to run
8 |
9 | ```sh
10 | $ git clone this repo
11 | $ cd playground
12 | $ yarn install or npm install
13 | ```
14 |
15 | Ensure emulator is ready or mobile device is connected to your machine:
16 |
17 | 运行前先开启模拟器或连接真机调试。
18 |
19 | ```sh
20 | $ npm run start or react-native start --reset-cache
21 | ```
22 |
23 | iOS:
24 |
25 | ```sh
26 | $ cd ios && pod install
27 | ```
28 |
29 | Add the following libraries to your "Link Binary with Libraries" in Targets > Build Phases in Xcode :
30 |
31 | 点击 Xcode 左侧 Targets > Build Phases 中的 Link Binary with Libraries 选项添加以下库:
32 |
33 |
34 | - [x] `SystemConfiguration.framework`
35 | - [x] `CoreTelephony.framework`
36 | - [x] `libsqlite3.0`
37 | - [x] `libc++`
38 | - [x] `libz`
39 |
40 | ```sh
41 | $ react-native run-ios
42 | ```
43 |
44 | Android:
45 |
46 | ```sh
47 | $ react-native run-android
48 | ```
49 |
--------------------------------------------------------------------------------
/playground/__tests__/App-test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 |
5 | import 'react-native';
6 | import React from 'react';
7 | import App from '../App';
8 |
9 | // Note: test renderer must be required after react-native.
10 | import renderer from 'react-test-renderer';
11 |
12 | it('renders correctly', () => {
13 | renderer.create();
14 | });
15 |
--------------------------------------------------------------------------------
/playground/android/app/BUCK:
--------------------------------------------------------------------------------
1 | # To learn about Buck see [Docs](https://buckbuild.com/).
2 | # To run your application with Buck:
3 | # - install Buck
4 | # - `npm start` - to start the packager
5 | # - `cd android`
6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
8 | # - `buck install -r android/app` - compile, install and run application
9 | #
10 |
11 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets")
12 |
13 | lib_deps = []
14 |
15 | create_aar_targets(glob(["libs/*.aar"]))
16 |
17 | create_jar_targets(glob(["libs/*.jar"]))
18 |
19 | android_library(
20 | name = "all-libs",
21 | exported_deps = lib_deps,
22 | )
23 |
24 | android_library(
25 | name = "app-code",
26 | srcs = glob([
27 | "src/main/java/**/*.java",
28 | ]),
29 | deps = [
30 | ":all-libs",
31 | ":build_config",
32 | ":res",
33 | ],
34 | )
35 |
36 | android_build_config(
37 | name = "build_config",
38 | package = "com.playground",
39 | )
40 |
41 | android_resource(
42 | name = "res",
43 | package = "com.playground",
44 | res = "src/main/res",
45 | )
46 |
47 | android_binary(
48 | name = "app",
49 | keystore = "//android/keystores:debug",
50 | manifest = "src/main/AndroidManifest.xml",
51 | package_type = "debug",
52 | deps = [
53 | ":app-code",
54 | ],
55 | )
56 |
--------------------------------------------------------------------------------
/playground/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.application"
2 |
3 | import com.android.build.OutputFile
4 |
5 | /**
6 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
7 | * and bundleReleaseJsAndAssets).
8 | * These basically call `react-native bundle` with the correct arguments during the Android build
9 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
10 | * bundle directly from the development server. Below you can see all the possible configurations
11 | * and their defaults. If you decide to add a configuration block, make sure to add it before the
12 | * `apply from: "../../node_modules/react-native/react.gradle"` line.
13 | *
14 | * project.ext.react = [
15 | * // the name of the generated asset file containing your JS bundle
16 | * bundleAssetName: "index.android.bundle",
17 | *
18 | * // the entry file for bundle generation
19 | * entryFile: "index.android.js",
20 | *
21 | * // https://facebook.github.io/react-native/docs/performance#enable-the-ram-format
22 | * bundleCommand: "ram-bundle",
23 | *
24 | * // whether to bundle JS and assets in debug mode
25 | * bundleInDebug: false,
26 | *
27 | * // whether to bundle JS and assets in release mode
28 | * bundleInRelease: true,
29 | *
30 | * // whether to bundle JS and assets in another build variant (if configured).
31 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
32 | * // The configuration property can be in the following formats
33 | * // 'bundleIn${productFlavor}${buildType}'
34 | * // 'bundleIn${buildType}'
35 | * // bundleInFreeDebug: true,
36 | * // bundleInPaidRelease: true,
37 | * // bundleInBeta: true,
38 | *
39 | * // whether to disable dev mode in custom build variants (by default only disabled in release)
40 | * // for example: to disable dev mode in the staging build type (if configured)
41 | * devDisabledInStaging: true,
42 | * // The configuration property can be in the following formats
43 | * // 'devDisabledIn${productFlavor}${buildType}'
44 | * // 'devDisabledIn${buildType}'
45 | *
46 | * // the root of your project, i.e. where "package.json" lives
47 | * root: "../../",
48 | *
49 | * // where to put the JS bundle asset in debug mode
50 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
51 | *
52 | * // where to put the JS bundle asset in release mode
53 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release",
54 | *
55 | * // where to put drawable resources / React Native assets, e.g. the ones you use via
56 | * // require('./image.png')), in debug mode
57 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
58 | *
59 | * // where to put drawable resources / React Native assets, e.g. the ones you use via
60 | * // require('./image.png')), in release mode
61 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
62 | *
63 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means
64 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
65 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle
66 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
67 | * // for example, you might want to remove it from here.
68 | * inputExcludes: ["android/**", "ios/**"],
69 | *
70 | * // override which node gets called and with what additional arguments
71 | * nodeExecutableAndArgs: ["node"],
72 | *
73 | * // supply additional arguments to the packager
74 | * extraPackagerArgs: []
75 | * ]
76 | */
77 |
78 | project.ext.react = [
79 | entryFile: "index.js"
80 | ]
81 |
82 | apply from: "../../node_modules/react-native/react.gradle"
83 |
84 | /**
85 | * Set this to true to create two separate APKs instead of one:
86 | * - An APK that only works on ARM devices
87 | * - An APK that only works on x86 devices
88 | * The advantage is the size of the APK is reduced by about 4MB.
89 | * Upload all the APKs to the Play Store and people will download
90 | * the correct one based on the CPU architecture of their device.
91 | */
92 | def enableSeparateBuildPerCPUArchitecture = false
93 |
94 | /**
95 | * Run Proguard to shrink the Java bytecode in release builds.
96 | */
97 | def enableProguardInReleaseBuilds = false
98 |
99 | /**
100 | * Use international variant JavaScriptCore
101 | * International variant includes ICU i18n library and necessary data allowing to use
102 | * e.g. Date.toLocaleString and String.localeCompare that give correct results
103 | * when using with locales other than en-US.
104 | * Note that this variant is about 6MiB larger per architecture than default.
105 | */
106 | def useIntlJsc = false
107 |
108 | android {
109 | compileSdkVersion rootProject.ext.compileSdkVersion
110 |
111 | compileOptions {
112 | sourceCompatibility JavaVersion.VERSION_1_8
113 | targetCompatibility JavaVersion.VERSION_1_8
114 | }
115 |
116 | defaultConfig {
117 | applicationId "com.playground"
118 | minSdkVersion rootProject.ext.minSdkVersion
119 | targetSdkVersion rootProject.ext.targetSdkVersion
120 | versionCode 1
121 | versionName "1.0"
122 | }
123 | splits {
124 | abi {
125 | reset()
126 | enable enableSeparateBuildPerCPUArchitecture
127 | universalApk false // If true, also generate a universal APK
128 | include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
129 | }
130 | }
131 | signingConfigs {
132 | debug {
133 | storeFile file('debug.keystore')
134 | storePassword 'android'
135 | keyAlias 'androiddebugkey'
136 | keyPassword 'android'
137 | }
138 | }
139 | buildTypes {
140 | debug {
141 | signingConfig signingConfigs.debug
142 | }
143 | release {
144 | // Caution! In production, you need to generate your own keystore file.
145 | // see https://facebook.github.io/react-native/docs/signed-apk-android.
146 | signingConfig signingConfigs.debug
147 | minifyEnabled enableProguardInReleaseBuilds
148 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
149 | }
150 | }
151 | // applicationVariants are e.g. debug, release
152 | applicationVariants.all { variant ->
153 | variant.outputs.each { output ->
154 | // For each separate APK per architecture, set a unique version code as described here:
155 | // https://developer.android.com/studio/build/configure-apk-splits.html
156 | def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
157 | def abi = output.getFilter(OutputFile.ABI)
158 | if (abi != null) { // null for the universal-debug, universal-release variants
159 | output.versionCodeOverride =
160 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
161 | }
162 | }
163 | }
164 | }
165 |
166 | dependencies {
167 | implementation fileTree(dir: "libs", include: ["*.jar"])
168 | implementation "com.facebook.react:react-native:+" // From node_modules
169 | implementation project(':RCTWeChat')
170 |
171 | // JSC from node_modules
172 | if (useIntlJsc) {
173 | implementation 'org.webkit:android-jsc-intl:+'
174 | } else {
175 | implementation 'org.webkit:android-jsc:+'
176 | }
177 | }
178 |
179 | // Run this once to be able to run the application with BUCK
180 | // puts all compile dependencies into folder libs for BUCK to use
181 | task copyDownloadableDepsToLibs(type: Copy) {
182 | from configurations.compile
183 | into 'libs'
184 | }
185 |
186 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
187 |
--------------------------------------------------------------------------------
/playground/android/app/build_defs.bzl:
--------------------------------------------------------------------------------
1 | """Helper definitions to glob .aar and .jar targets"""
2 |
3 | def create_aar_targets(aarfiles):
4 | for aarfile in aarfiles:
5 | name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")]
6 | lib_deps.append(":" + name)
7 | android_prebuilt_aar(
8 | name = name,
9 | aar = aarfile,
10 | )
11 |
12 | def create_jar_targets(jarfiles):
13 | for jarfile in jarfiles:
14 | name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")]
15 | lib_deps.append(":" + name)
16 | prebuilt_jar(
17 | name = name,
18 | binary_jar = jarfile,
19 | )
20 |
--------------------------------------------------------------------------------
/playground/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | -keep class com.tencent.mm.sdk.** {
13 | *;
14 | }
15 |
--------------------------------------------------------------------------------
/playground/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/playground/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
29 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/playground/android/app/src/main/java/com/playground/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.playground;
2 |
3 | import com.facebook.react.ReactActivity;
4 |
5 | public class MainActivity extends ReactActivity {
6 |
7 | /**
8 | * Returns the name of the main component registered from JavaScript.
9 | * This is used to schedule rendering of the component.
10 | */
11 | @Override
12 | protected String getMainComponentName() {
13 | return "playground";
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/playground/android/app/src/main/java/com/playground/MainApplication.java:
--------------------------------------------------------------------------------
1 | package com.playground;
2 |
3 | import android.app.Application;
4 |
5 | import com.facebook.react.PackageList;
6 | import com.facebook.react.ReactApplication;
7 | import com.facebook.react.ReactNativeHost;
8 | import com.facebook.react.ReactPackage;
9 | import com.facebook.soloader.SoLoader;
10 | import com.theweflex.react.WeChatPackage;
11 |
12 | import java.util.List;
13 |
14 | public class MainApplication extends Application implements ReactApplication {
15 |
16 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
17 | @Override
18 | public boolean getUseDeveloperSupport() {
19 | return BuildConfig.DEBUG;
20 | }
21 |
22 | @Override
23 | protected List getPackages() {
24 | @SuppressWarnings("UnnecessaryLocalVariable")
25 | List packages = new PackageList(this).getPackages();
26 | // Packages that cannot be autolinked yet can be added manually here, for example:
27 | // packages.add(new MyReactNativePackage());
28 | packages.add(new WeChatPackage());
29 | return packages;
30 | }
31 |
32 | @Override
33 | protected String getJSMainModuleName() {
34 | return "index";
35 | }
36 | };
37 |
38 | @Override
39 | public ReactNativeHost getReactNativeHost() {
40 | return mReactNativeHost;
41 | }
42 |
43 | @Override
44 | public void onCreate() {
45 | super.onCreate();
46 | SoLoader.init(this, /* native exopackage */ false);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/playground/android/app/src/main/java/com/playground/wxapi/WXEntryActivity.java:
--------------------------------------------------------------------------------
1 | package com.playground.wxapi;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import com.theweflex.react.WeChatModule;
6 |
7 | public class WXEntryActivity extends Activity {
8 | @Override
9 | protected void onCreate(Bundle savedInstanceState) {
10 | super.onCreate(savedInstanceState);
11 | WeChatModule.handleIntent(getIntent());
12 | finish();
13 | }
14 | }
--------------------------------------------------------------------------------
/playground/android/app/src/main/java/com/playground/wxapi/WXPayEntryActivity.java:
--------------------------------------------------------------------------------
1 | package com.playground.wxapi;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import com.theweflex.react.WeChatModule;
6 |
7 | public class WXPayEntryActivity extends Activity {
8 | @Override
9 | protected void onCreate(Bundle savedInstanceState) {
10 | super.onCreate(savedInstanceState);
11 | WeChatModule.handleIntent(getIntent());
12 | finish();
13 | }
14 | }
--------------------------------------------------------------------------------
/playground/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/playground/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/playground/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/playground/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/playground/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/playground/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/playground/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/playground/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/playground/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/playground/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/playground/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/playground/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/playground/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/playground/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/playground/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/playground/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/playground/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/playground/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/playground/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/playground/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/playground/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | playground
3 |
4 |
--------------------------------------------------------------------------------
/playground/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/playground/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext {
5 | buildToolsVersion = "28.0.3"
6 | minSdkVersion = 16
7 | compileSdkVersion = 28
8 | targetSdkVersion = 28
9 | supportLibVersion = "28.0.0"
10 | }
11 | repositories {
12 | google()
13 | jcenter()
14 | }
15 | dependencies {
16 | classpath("com.android.tools.build:gradle:3.4.1")
17 |
18 | // NOTE: Do not place your application dependencies here; they belong
19 | // in the individual module build.gradle files
20 | }
21 | }
22 |
23 | allprojects {
24 | repositories {
25 | mavenLocal()
26 | maven {
27 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
28 | url("$rootDir/../node_modules/react-native/android")
29 | }
30 | maven {
31 | // Android JSC is installed from npm
32 | url("$rootDir/../node_modules/jsc-android/dist")
33 | }
34 |
35 | google()
36 | jcenter()
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/playground/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | android.useAndroidX=true
21 | android.enableJetifier=true
22 |
--------------------------------------------------------------------------------
/playground/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/playground/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/playground/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/playground/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 | # Determine the Java command to use to start the JVM.
86 | if [ -n "$JAVA_HOME" ] ; then
87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
88 | # IBM's JDK on AIX uses strange locations for the executables
89 | JAVACMD="$JAVA_HOME/jre/sh/java"
90 | else
91 | JAVACMD="$JAVA_HOME/bin/java"
92 | fi
93 | if [ ! -x "$JAVACMD" ] ; then
94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
95 |
96 | Please set the JAVA_HOME variable in your environment to match the
97 | location of your Java installation."
98 | fi
99 | else
100 | JAVACMD="java"
101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
102 |
103 | Please set the JAVA_HOME variable in your environment to match the
104 | location of your Java installation."
105 | fi
106 |
107 | # Increase the maximum file descriptors if we can.
108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
109 | MAX_FD_LIMIT=`ulimit -H -n`
110 | if [ $? -eq 0 ] ; then
111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
112 | MAX_FD="$MAX_FD_LIMIT"
113 | fi
114 | ulimit -n $MAX_FD
115 | if [ $? -ne 0 ] ; then
116 | warn "Could not set maximum file descriptor limit: $MAX_FD"
117 | fi
118 | else
119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
120 | fi
121 | fi
122 |
123 | # For Darwin, add options to specify how the application appears in the dock
124 | if $darwin; then
125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
126 | fi
127 |
128 | # For Cygwin, switch paths to Windows format before running java
129 | if $cygwin ; then
130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
132 | JAVACMD=`cygpath --unix "$JAVACMD"`
133 |
134 | # We build the pattern for arguments to be converted via cygpath
135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
136 | SEP=""
137 | for dir in $ROOTDIRSRAW ; do
138 | ROOTDIRS="$ROOTDIRS$SEP$dir"
139 | SEP="|"
140 | done
141 | OURCYGPATTERN="(^($ROOTDIRS))"
142 | # Add a user-defined pattern to the cygpath arguments
143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
145 | fi
146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
147 | i=0
148 | for arg in "$@" ; do
149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
151 |
152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
154 | else
155 | eval `echo args$i`="\"$arg\""
156 | fi
157 | i=$((i+1))
158 | done
159 | case $i in
160 | (0) set -- ;;
161 | (1) set -- "$args0" ;;
162 | (2) set -- "$args0" "$args1" ;;
163 | (3) set -- "$args0" "$args1" "$args2" ;;
164 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
165 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
166 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
167 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
168 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
169 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
170 | esac
171 | fi
172 |
173 | # Escape application args
174 | save () {
175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
176 | echo " "
177 | }
178 | APP_ARGS=$(save "$@")
179 |
180 | # Collect all arguments for the java command, following the shell quoting and substitution rules
181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
182 |
183 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
184 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
185 | cd "$(dirname "$0")"
186 | fi
187 |
188 | exec "$JAVACMD" "$@"
189 |
--------------------------------------------------------------------------------
/playground/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem http://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
34 |
35 | @rem Find java.exe
36 | if defined JAVA_HOME goto findJavaFromJavaHome
37 |
38 | set JAVA_EXE=java.exe
39 | %JAVA_EXE% -version >NUL 2>&1
40 | if "%ERRORLEVEL%" == "0" goto init
41 |
42 | echo.
43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
44 | echo.
45 | echo Please set the JAVA_HOME variable in your environment to match the
46 | echo location of your Java installation.
47 |
48 | goto fail
49 |
50 | :findJavaFromJavaHome
51 | set JAVA_HOME=%JAVA_HOME:"=%
52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
53 |
54 | if exist "%JAVA_EXE%" goto init
55 |
56 | echo.
57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
58 | echo.
59 | echo Please set the JAVA_HOME variable in your environment to match the
60 | echo location of your Java installation.
61 |
62 | goto fail
63 |
64 | :init
65 | @rem Get command-line arguments, handling Windows variants
66 |
67 | if not "%OS%" == "Windows_NT" goto win9xME_args
68 |
69 | :win9xME_args
70 | @rem Slurp the command line arguments.
71 | set CMD_LINE_ARGS=
72 | set _SKIP=2
73 |
74 | :win9xME_args_slurp
75 | if "x%~1" == "x" goto execute
76 |
77 | set CMD_LINE_ARGS=%*
78 |
79 | :execute
80 | @rem Setup the command line
81 |
82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
83 |
84 | @rem Execute Gradle
85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
86 |
87 | :end
88 | @rem End local scope for the variables with windows NT shell
89 | if "%ERRORLEVEL%"=="0" goto mainEnd
90 |
91 | :fail
92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
93 | rem the _cmd.exe /c_ return code!
94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
95 | exit /b 1
96 |
97 | :mainEnd
98 | if "%OS%"=="Windows_NT" endlocal
99 |
100 | :omega
101 |
--------------------------------------------------------------------------------
/playground/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'playground'
2 | include ':RCTWeChat'
3 | project(':RCTWeChat').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-wechat/android')
4 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
5 | include ':app'
6 |
--------------------------------------------------------------------------------
/playground/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "playground",
3 | "displayName": "playground"
4 | }
--------------------------------------------------------------------------------
/playground/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['module:metro-react-native-babel-preset'],
3 | };
4 |
--------------------------------------------------------------------------------
/playground/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 |
5 | import { AppRegistry } from 'react-native';
6 | import App from './App';
7 | import { name as appName } from './app.json';
8 |
9 | AppRegistry.registerComponent(appName, () => App);
10 |
--------------------------------------------------------------------------------
/playground/ios/Podfile:
--------------------------------------------------------------------------------
1 | platform :ios, '9.0'
2 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
3 |
4 | target 'playground' do
5 | # Pods for playground
6 | pod 'React', :path => '../node_modules/react-native/'
7 | pod 'React-Core', :path => '../node_modules/react-native/React'
8 | pod 'React-DevSupport', :path => '../node_modules/react-native/React'
9 | pod 'React-fishhook', :path => '../node_modules/react-native/Libraries/fishhook'
10 | pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
11 | pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
12 | pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
13 | pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
14 | pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
15 | pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
16 | pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
17 | pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
18 | pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
19 | pod 'React-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket'
20 |
21 | pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
22 | pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
23 | pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
24 | pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
25 | pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
26 |
27 | pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
28 | pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
29 | pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
30 |
31 | target 'playgroundTests' do
32 | inherit! :search_paths
33 | # Pods for testing
34 | end
35 |
36 | use_native_modules!
37 | end
38 |
39 | target 'playground-tvOS' do
40 | # Pods for playground-tvOS
41 |
42 | target 'playground-tvOSTests' do
43 | inherit! :search_paths
44 | # Pods for testing
45 | end
46 |
47 | end
48 |
--------------------------------------------------------------------------------
/playground/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - boost-for-react-native (1.63.0)
3 | - DoubleConversion (1.1.6)
4 | - Folly (2018.10.22.00):
5 | - boost-for-react-native
6 | - DoubleConversion
7 | - Folly/Default (= 2018.10.22.00)
8 | - glog
9 | - Folly/Default (2018.10.22.00):
10 | - boost-for-react-native
11 | - DoubleConversion
12 | - glog
13 | - glog (0.3.5)
14 | - RCTWeChat (1.9.12):
15 | - React
16 | - React (0.60.0):
17 | - React-Core (= 0.60.0)
18 | - React-DevSupport (= 0.60.0)
19 | - React-RCTActionSheet (= 0.60.0)
20 | - React-RCTAnimation (= 0.60.0)
21 | - React-RCTBlob (= 0.60.0)
22 | - React-RCTImage (= 0.60.0)
23 | - React-RCTLinking (= 0.60.0)
24 | - React-RCTNetwork (= 0.60.0)
25 | - React-RCTSettings (= 0.60.0)
26 | - React-RCTText (= 0.60.0)
27 | - React-RCTVibration (= 0.60.0)
28 | - React-RCTWebSocket (= 0.60.0)
29 | - React-Core (0.60.0):
30 | - Folly (= 2018.10.22.00)
31 | - React-cxxreact (= 0.60.0)
32 | - React-jsiexecutor (= 0.60.0)
33 | - yoga (= 0.60.0.React)
34 | - React-cxxreact (0.60.0):
35 | - boost-for-react-native (= 1.63.0)
36 | - DoubleConversion
37 | - Folly (= 2018.10.22.00)
38 | - glog
39 | - React-jsinspector (= 0.60.0)
40 | - React-DevSupport (0.60.0):
41 | - React-Core (= 0.60.0)
42 | - React-RCTWebSocket (= 0.60.0)
43 | - React-fishhook (0.60.0)
44 | - React-jsi (0.60.0):
45 | - boost-for-react-native (= 1.63.0)
46 | - DoubleConversion
47 | - Folly (= 2018.10.22.00)
48 | - glog
49 | - React-jsi/Default (= 0.60.0)
50 | - React-jsi/Default (0.60.0):
51 | - boost-for-react-native (= 1.63.0)
52 | - DoubleConversion
53 | - Folly (= 2018.10.22.00)
54 | - glog
55 | - React-jsiexecutor (0.60.0):
56 | - DoubleConversion
57 | - Folly (= 2018.10.22.00)
58 | - glog
59 | - React-cxxreact (= 0.60.0)
60 | - React-jsi (= 0.60.0)
61 | - React-jsinspector (0.60.0)
62 | - React-RCTActionSheet (0.60.0):
63 | - React-Core (= 0.60.0)
64 | - React-RCTAnimation (0.60.0):
65 | - React-Core (= 0.60.0)
66 | - React-RCTBlob (0.60.0):
67 | - React-Core (= 0.60.0)
68 | - React-RCTNetwork (= 0.60.0)
69 | - React-RCTWebSocket (= 0.60.0)
70 | - React-RCTImage (0.60.0):
71 | - React-Core (= 0.60.0)
72 | - React-RCTNetwork (= 0.60.0)
73 | - React-RCTLinking (0.60.0):
74 | - React-Core (= 0.60.0)
75 | - React-RCTNetwork (0.60.0):
76 | - React-Core (= 0.60.0)
77 | - React-RCTSettings (0.60.0):
78 | - React-Core (= 0.60.0)
79 | - React-RCTText (0.60.0):
80 | - React-Core (= 0.60.0)
81 | - React-RCTVibration (0.60.0):
82 | - React-Core (= 0.60.0)
83 | - React-RCTWebSocket (0.60.0):
84 | - React-Core (= 0.60.0)
85 | - React-fishhook (= 0.60.0)
86 | - yoga (0.60.0.React)
87 |
88 | DEPENDENCIES:
89 | - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
90 | - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
91 | - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
92 | - RCTWeChat (from `../node_modules/react-native-wechat`)
93 | - React (from `../node_modules/react-native/`)
94 | - React-Core (from `../node_modules/react-native/React`)
95 | - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
96 | - React-DevSupport (from `../node_modules/react-native/React`)
97 | - React-fishhook (from `../node_modules/react-native/Libraries/fishhook`)
98 | - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
99 | - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
100 | - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
101 | - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
102 | - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
103 | - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`)
104 | - React-RCTImage (from `../node_modules/react-native/Libraries/Image`)
105 | - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`)
106 | - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`)
107 | - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`)
108 | - React-RCTText (from `../node_modules/react-native/Libraries/Text`)
109 | - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
110 | - React-RCTWebSocket (from `../node_modules/react-native/Libraries/WebSocket`)
111 | - yoga (from `../node_modules/react-native/ReactCommon/yoga`)
112 |
113 | SPEC REPOS:
114 | https://github.com/cocoapods/specs.git:
115 | - boost-for-react-native
116 |
117 | EXTERNAL SOURCES:
118 | DoubleConversion:
119 | :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
120 | Folly:
121 | :podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec"
122 | glog:
123 | :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
124 | RCTWeChat:
125 | :path: "../node_modules/react-native-wechat"
126 | React:
127 | :path: "../node_modules/react-native/"
128 | React-Core:
129 | :path: "../node_modules/react-native/React"
130 | React-cxxreact:
131 | :path: "../node_modules/react-native/ReactCommon/cxxreact"
132 | React-DevSupport:
133 | :path: "../node_modules/react-native/React"
134 | React-fishhook:
135 | :path: "../node_modules/react-native/Libraries/fishhook"
136 | React-jsi:
137 | :path: "../node_modules/react-native/ReactCommon/jsi"
138 | React-jsiexecutor:
139 | :path: "../node_modules/react-native/ReactCommon/jsiexecutor"
140 | React-jsinspector:
141 | :path: "../node_modules/react-native/ReactCommon/jsinspector"
142 | React-RCTActionSheet:
143 | :path: "../node_modules/react-native/Libraries/ActionSheetIOS"
144 | React-RCTAnimation:
145 | :path: "../node_modules/react-native/Libraries/NativeAnimation"
146 | React-RCTBlob:
147 | :path: "../node_modules/react-native/Libraries/Blob"
148 | React-RCTImage:
149 | :path: "../node_modules/react-native/Libraries/Image"
150 | React-RCTLinking:
151 | :path: "../node_modules/react-native/Libraries/LinkingIOS"
152 | React-RCTNetwork:
153 | :path: "../node_modules/react-native/Libraries/Network"
154 | React-RCTSettings:
155 | :path: "../node_modules/react-native/Libraries/Settings"
156 | React-RCTText:
157 | :path: "../node_modules/react-native/Libraries/Text"
158 | React-RCTVibration:
159 | :path: "../node_modules/react-native/Libraries/Vibration"
160 | React-RCTWebSocket:
161 | :path: "../node_modules/react-native/Libraries/WebSocket"
162 | yoga:
163 | :path: "../node_modules/react-native/ReactCommon/yoga"
164 |
165 | SPEC CHECKSUMS:
166 | boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
167 | DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2
168 | Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
169 | glog: 1f3da668190260b06b429bb211bfbee5cd790c28
170 | RCTWeChat: edb02d76aaf9b2e698e515e3c57bf143a290d9d7
171 | React: 4b3c068e793e96672dcd186a2b572fac43e4b031
172 | React-Core: 3dc86b22920597f813c62a96db3165950b64826b
173 | React-cxxreact: 0dacb291e59b81e7c3f22a2118bee853ba8a60d2
174 | React-DevSupport: 4eb4135386acd10c2586cc9c759bf96b4dac035e
175 | React-fishhook: 86ca737527bb9d860efbb943c11c729a5b69aa3d
176 | React-jsi: 8e128c4d0d8febc2977ef617d1c09bb54326069c
177 | React-jsiexecutor: 7a3554f703a58963ec80b860144ea0f0e9b910e1
178 | React-jsinspector: d4ed52225912efe0019bb7f1a225aec20f23049a
179 | React-RCTActionSheet: b27ff3cf3a68f917c46d2b94abf938b625b96570
180 | React-RCTAnimation: 9e4708e5bd65fca8285ce7c0aa076f3f4fa5c2f8
181 | React-RCTBlob: 6eafcc3a24f33785692a7be24918ade607bc8719
182 | React-RCTImage: 46b965d7225b428ea11580ead08a4318aef1d6be
183 | React-RCTLinking: d65b9f56cf0b8e171575a86764df7bb019ac28d6
184 | React-RCTNetwork: 783ee2f430740e58f724e46adc79fe7feff64202
185 | React-RCTSettings: aa28315aadfbfaf94206d865673ae509f1e97c07
186 | React-RCTText: 685fca2e13b024271048e7e247ef24476f28a41e
187 | React-RCTVibration: 4ee1cf208ab17a50fafb1c16ffe28fe594a64e4f
188 | React-RCTWebSocket: fca087d583724aa0e5fef7d911f0f2a28d0f2736
189 | yoga: 616fde658be980aa60a2158835170f3f9c2d04b4
190 |
191 | PODFILE CHECKSUM: 7a7e8cd3eb67dfaa229dd770d0629c67ab0b2f2b
192 |
193 | COCOAPODS: 1.7.5
194 |
--------------------------------------------------------------------------------
/playground/ios/playground-tvOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | NSAppTransportSecurity
26 |
27 | NSExceptionDomains
28 |
29 | localhost
30 |
31 | NSExceptionAllowsInsecureHTTPLoads
32 |
33 |
34 |
35 |
36 | NSLocationWhenInUseUsageDescription
37 |
38 | UILaunchStoryboardName
39 | LaunchScreen
40 | UIRequiredDeviceCapabilities
41 |
42 | armv7
43 |
44 | UISupportedInterfaceOrientations
45 |
46 | UIInterfaceOrientationPortrait
47 | UIInterfaceOrientationLandscapeLeft
48 | UIInterfaceOrientationLandscapeRight
49 |
50 | UIViewControllerBasedStatusBarAppearance
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/playground/ios/playground-tvOSTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/playground/ios/playground.xcodeproj/xcshareddata/xcschemes/playground-tvOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
43 |
49 |
50 |
51 |
52 |
53 |
58 |
59 |
61 |
67 |
68 |
69 |
70 |
71 |
77 |
78 |
79 |
80 |
81 |
82 |
92 |
94 |
100 |
101 |
102 |
103 |
104 |
105 |
111 |
113 |
119 |
120 |
121 |
122 |
124 |
125 |
128 |
129 |
130 |
--------------------------------------------------------------------------------
/playground/ios/playground.xcodeproj/xcshareddata/xcschemes/playground.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
43 |
49 |
50 |
51 |
52 |
53 |
58 |
59 |
61 |
67 |
68 |
69 |
70 |
71 |
77 |
78 |
79 |
80 |
81 |
82 |
92 |
94 |
100 |
101 |
102 |
103 |
104 |
105 |
111 |
113 |
119 |
120 |
121 |
122 |
124 |
125 |
128 |
129 |
130 |
--------------------------------------------------------------------------------
/playground/ios/playground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/playground/ios/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/playground/ios/playground/AppDelegate.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | #import
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (nonatomic, strong) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/playground/ios/playground/AppDelegate.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | #import "AppDelegate.h"
9 |
10 | #import
11 | #import
12 | #import
13 | #import
14 |
15 | @implementation AppDelegate
16 |
17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
18 | {
19 | RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
20 | RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
21 | moduleName:@"playground"
22 | initialProperties:nil];
23 |
24 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
25 |
26 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
27 | UIViewController *rootViewController = [UIViewController new];
28 | rootViewController.view = rootView;
29 | self.window.rootViewController = rootViewController;
30 | [self.window makeKeyAndVisible];
31 | return YES;
32 | }
33 |
34 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
35 | {
36 | #if DEBUG
37 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
38 | #else
39 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
40 | #endif
41 | }
42 |
43 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
44 | options:(NSDictionary *)options
45 | {
46 | return [RCTLinkingManager application:application openURL:url options:options];
47 | }
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/playground/ios/playground/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
21 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/playground/ios/playground/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ios-marketing",
45 | "size" : "1024x1024",
46 | "scale" : "1x"
47 | }
48 | ],
49 | "info" : {
50 | "version" : 1,
51 | "author" : "xcode"
52 | }
53 | }
--------------------------------------------------------------------------------
/playground/ios/playground/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/playground/ios/playground/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | playground
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleURLTypes
24 |
25 |
26 | CFBundleTypeRole
27 | Editor
28 | CFBundleURLName
29 | appid
30 | CFBundleURLSchemes
31 |
32 | wx13345678
33 |
34 |
35 |
36 | CFBundleVersion
37 | 1
38 | LSApplicationQueriesSchemes
39 |
40 | weixin
41 | wechat
42 |
43 | LSRequiresIPhoneOS
44 |
45 | NSAppTransportSecurity
46 |
47 | NSAllowsArbitraryLoads
48 |
49 | NSExceptionDomains
50 |
51 | localhost
52 |
53 | NSExceptionAllowsInsecureHTTPLoads
54 |
55 |
56 |
57 |
58 | NSLocationWhenInUseUsageDescription
59 |
60 | UILaunchStoryboardName
61 | LaunchScreen
62 | UIRequiredDeviceCapabilities
63 |
64 | armv7
65 |
66 | UISupportedInterfaceOrientations
67 |
68 | UIInterfaceOrientationPortrait
69 | UIInterfaceOrientationLandscapeLeft
70 | UIInterfaceOrientationLandscapeRight
71 |
72 | UIViewControllerBasedStatusBarAppearance
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/playground/ios/playground/main.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | #import
9 |
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/playground/ios/playgroundTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/playground/ios/playgroundTests/playgroundTests.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | #import
9 | #import
10 |
11 | #import
12 | #import
13 |
14 | #define TIMEOUT_SECONDS 600
15 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!"
16 |
17 | @interface playgroundTests : XCTestCase
18 |
19 | @end
20 |
21 | @implementation playgroundTests
22 |
23 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
24 | {
25 | if (test(view)) {
26 | return YES;
27 | }
28 | for (UIView *subview in [view subviews]) {
29 | if ([self findSubviewInView:subview matching:test]) {
30 | return YES;
31 | }
32 | }
33 | return NO;
34 | }
35 |
36 | - (void)testRendersWelcomeScreen
37 | {
38 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];
39 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
40 | BOOL foundElement = NO;
41 |
42 | __block NSString *redboxError = nil;
43 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
44 | if (level >= RCTLogLevelError) {
45 | redboxError = message;
46 | }
47 | });
48 |
49 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
50 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
51 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
52 |
53 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
54 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
55 | return YES;
56 | }
57 | return NO;
58 | }];
59 | }
60 |
61 | RCTSetLogFunction(RCTDefaultLogFunction);
62 |
63 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
64 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
65 | }
66 |
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/playground/metro.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Metro configuration for React Native
3 | * https://github.com/facebook/react-native
4 | *
5 | * @format
6 | */
7 |
8 | module.exports = {
9 | transformer: {
10 | getTransformOptions: async () => ({
11 | transform: {
12 | experimentalImportSupport: false,
13 | inlineRequires: false,
14 | },
15 | }),
16 | },
17 | };
18 |
--------------------------------------------------------------------------------
/playground/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "playground",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "start": "react-native start",
7 | "test": "jest",
8 | "lint": "eslint ."
9 | },
10 | "dependencies": {
11 | "react": "16.8.6",
12 | "react-native": "0.60.0",
13 | "react-native-wechat": "^1.9.12"
14 | },
15 | "devDependencies": {
16 | "@babel/core": "^7.6.2",
17 | "@babel/runtime": "^7.6.2",
18 | "@react-native-community/eslint-config": "^0.0.5",
19 | "babel-jest": "^24.9.0",
20 | "eslint": "^6.4.0",
21 | "jest": "^24.9.0",
22 | "metro-react-native-babel-preset": "^0.56.0",
23 | "react-test-renderer": "16.8.6"
24 | },
25 | "jest": {
26 | "preset": "react-native"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/qrcode_dingding.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/qrcode_dingding.jpg
--------------------------------------------------------------------------------
/qrcode_gitter.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/qrcode_gitter.jpg
--------------------------------------------------------------------------------
/qrcode_qq.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/qrcode_qq.jpg
--------------------------------------------------------------------------------
/weixin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yorkie/react-native-wechat/42c1d411a1151837a74fd49778f3ee09843855f9/weixin.png
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | events@1.0.2:
6 | version "1.0.2"
7 | resolved "https://registry.yarnpkg.com/events/-/events-1.0.2.tgz#75849dcfe93d10fb057c30055afdbd51d06a8e24"
8 |
--------------------------------------------------------------------------------