正在显示
59 个修改的文件
包含
4277 行增加
和
0 行删除
.gitignore
0 → 100644
.idea/react-native-wechat.iml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<module type="WEB_MODULE" version="4"> | ||
| 3 | + <component name="NewModuleRootManager"> | ||
| 4 | + <content url="file://$MODULE_DIR$"> | ||
| 5 | + <excludeFolder url="file://$MODULE_DIR$/.tmp" /> | ||
| 6 | + <excludeFolder url="file://$MODULE_DIR$/temp" /> | ||
| 7 | + <excludeFolder url="file://$MODULE_DIR$/tmp" /> | ||
| 8 | + </content> | ||
| 9 | + <orderEntry type="inheritedJdk" /> | ||
| 10 | + <orderEntry type="sourceFolder" forTests="false" /> | ||
| 11 | + </component> | ||
| 12 | +</module> |
.npmignore
0 → 100644
.travis.yml
0 → 100644
| 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 |
CODE_OF_CONDUCT.md
0 → 100644
| 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/ |
Example/.flowconfig
0 → 100644
| 1 | +[ignore] | ||
| 2 | + | ||
| 3 | +# We fork some components by platform. | ||
| 4 | +.*/*.web.js | ||
| 5 | +.*/*.android.js | ||
| 6 | + | ||
| 7 | +# Some modules have their own node_modules with overlap | ||
| 8 | +.*/node_modules/node-haste/.* | ||
| 9 | + | ||
| 10 | +# Ignore react-tools where there are overlaps, but don't ignore anything that | ||
| 11 | +# react-native relies on | ||
| 12 | +.*/node_modules/react-tools/src/React.js | ||
| 13 | +.*/node_modules/react-tools/src/renderers/shared/event/EventPropagators.js | ||
| 14 | +.*/node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderEventPlugin.js | ||
| 15 | +.*/node_modules/react-tools/src/shared/vendor/core/ExecutionEnvironment.js | ||
| 16 | + | ||
| 17 | +# Ignore commoner tests | ||
| 18 | +.*/node_modules/commoner/test/.* | ||
| 19 | + | ||
| 20 | +# See https://github.com/facebook/flow/issues/442 | ||
| 21 | +.*/react-tools/node_modules/commoner/lib/reader.js | ||
| 22 | + | ||
| 23 | +# Ignore jest | ||
| 24 | +.*/node_modules/jest-cli/.* | ||
| 25 | + | ||
| 26 | +# Ignore Website | ||
| 27 | +.*/website/.* | ||
| 28 | + | ||
| 29 | +[include] | ||
| 30 | + | ||
| 31 | +[libs] | ||
| 32 | +node_modules/react-native/Libraries/react-native/react-native-interface.js | ||
| 33 | + | ||
| 34 | +[options] | ||
| 35 | +module.system=haste | ||
| 36 | + | ||
| 37 | +munge_underscores=true | ||
| 38 | + | ||
| 39 | +module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub' | ||
| 40 | +module.name_mapper='^[./a-zA-Z0-9$_-]+\.png$' -> 'RelativeImageStub' | ||
| 41 | + | ||
| 42 | +suppress_type=$FlowIssue | ||
| 43 | +suppress_type=$FlowFixMe | ||
| 44 | +suppress_type=$FixMe | ||
| 45 | + | ||
| 46 | +suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(1[0-7]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) | ||
| 47 | +suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-7]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+ | ||
| 48 | +suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy | ||
| 49 | + | ||
| 50 | +[version] | ||
| 51 | +0.17.0 |
Example/.watchmanconfig
0 → 100644
| 1 | +{} |
Example/README.md
0 → 100644
Example/android/app/build.gradle
0 → 100644
| 1 | +apply plugin: "com.android.application" | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * The react.gradle file registers two tasks: bundleDebugJsAndAssets and bundleReleaseJsAndAssets. | ||
| 5 | + * These basically call `react-native bundle` with the correct arguments during the Android build | ||
| 6 | + * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the | ||
| 7 | + * bundle directly from the development server. Below you can see all the possible configurations | ||
| 8 | + * and their defaults. If you decide to add a configuration block, make sure to add it before the | ||
| 9 | + * `apply from: "react.gradle"` line. | ||
| 10 | + * | ||
| 11 | + * project.ext.react = [ | ||
| 12 | + * // the name of the generated asset file containing your JS bundle | ||
| 13 | + * bundleAssetName: "index.android.bundle", | ||
| 14 | + * | ||
| 15 | + * // the entry file for bundle generation | ||
| 16 | + * entryFile: "index.android.js", | ||
| 17 | + * | ||
| 18 | + * // whether to bundle JS and assets in debug mode | ||
| 19 | + * bundleInDebug: false, | ||
| 20 | + * | ||
| 21 | + * // whether to bundle JS and assets in release mode | ||
| 22 | + * bundleInRelease: true, | ||
| 23 | + * | ||
| 24 | + * // the root of your project, i.e. where "package.json" lives | ||
| 25 | + * root: "../../", | ||
| 26 | + * | ||
| 27 | + * // where to put the JS bundle asset in debug mode | ||
| 28 | + * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", | ||
| 29 | + * | ||
| 30 | + * // where to put the JS bundle asset in release mode | ||
| 31 | + * jsBundleDirRelease: "$buildDir/intermediates/assets/release", | ||
| 32 | + * | ||
| 33 | + * // where to put drawable resources / React Native assets, e.g. the ones you use via | ||
| 34 | + * // require('./image.png')), in debug mode | ||
| 35 | + * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", | ||
| 36 | + * | ||
| 37 | + * // where to put drawable resources / React Native assets, e.g. the ones you use via | ||
| 38 | + * // require('./image.png')), in release mode | ||
| 39 | + * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", | ||
| 40 | + * | ||
| 41 | + * // by default the gradle tasks are skipped if none of the JS files or assets change; this means | ||
| 42 | + * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to | ||
| 43 | + * // date; if you have any other folders that you want to ignore for performance reasons (gradle | ||
| 44 | + * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ | ||
| 45 | + * // for example, you might want to remove it from here. | ||
| 46 | + * inputExcludes: ["android/**", "ios/**"] | ||
| 47 | + * ] | ||
| 48 | + */ | ||
| 49 | + | ||
| 50 | +apply from: "react.gradle" | ||
| 51 | + | ||
| 52 | +android { | ||
| 53 | + compileSdkVersion 23 | ||
| 54 | + buildToolsVersion "23.0.1" | ||
| 55 | + | ||
| 56 | + defaultConfig { | ||
| 57 | + applicationId "com.example" | ||
| 58 | + minSdkVersion 16 | ||
| 59 | + targetSdkVersion 22 | ||
| 60 | + versionCode 1 | ||
| 61 | + versionName "1.0" | ||
| 62 | + ndk { | ||
| 63 | + abiFilters "armeabi-v7a", "x86" | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | + buildTypes { | ||
| 67 | + release { | ||
| 68 | + minifyEnabled false // Set this to true to enable Proguard | ||
| 69 | + proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | +} | ||
| 73 | + | ||
| 74 | +dependencies { | ||
| 75 | + compile fileTree(dir: "libs", include: ["*.jar"]) | ||
| 76 | + compile "com.android.support:appcompat-v7:23.0.1" | ||
| 77 | + compile "com.facebook.react:react-native:0.14.+" | ||
| 78 | +} |
Example/android/app/proguard-rules.pro
0 → 100644
| 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 | +# If your project uses WebView with JS, uncomment the following | ||
| 13 | +# and specify the fully qualified class name to the JavaScript interface | ||
| 14 | +# class: | ||
| 15 | +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||
| 16 | +# public *; | ||
| 17 | +#} | ||
| 18 | + | ||
| 19 | +# Disabling obfuscation is useful if you collect stack traces from production crashes | ||
| 20 | +# (unless you are using a system that supports de-obfuscate the stack traces). | ||
| 21 | +-dontobfuscate | ||
| 22 | + | ||
| 23 | +# React Native | ||
| 24 | + | ||
| 25 | +# Keep our interfaces so they can be used by other ProGuard rules. | ||
| 26 | +# See http://sourceforge.net/p/proguard/bugs/466/ | ||
| 27 | +-keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip | ||
| 28 | +-keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters | ||
| 29 | + | ||
| 30 | +# Do not strip any method/class that is annotated with @DoNotStrip | ||
| 31 | +-keep @com.facebook.proguard.annotations.DoNotStrip class * | ||
| 32 | +-keepclassmembers class * { | ||
| 33 | + @com.facebook.proguard.annotations.DoNotStrip *; | ||
| 34 | +} | ||
| 35 | + | ||
| 36 | +-keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * { | ||
| 37 | + void set*(***); | ||
| 38 | + *** get*(); | ||
| 39 | +} | ||
| 40 | + | ||
| 41 | +-keep class * extends com.facebook.react.bridge.JavaScriptModule { *; } | ||
| 42 | +-keep class * extends com.facebook.react.bridge.NativeModule { *; } | ||
| 43 | +-keepclassmembers class * { @com.facebook.react.uimanager.UIProp <fields>; } | ||
| 44 | +-keepclassmembers class * { @com.facebook.react.uimanager.ReactProp <methods>; } | ||
| 45 | +-keepclassmembers class * { @com.facebook.react.uimanager.ReactPropGroup <methods>; } | ||
| 46 | + | ||
| 47 | +# okhttp | ||
| 48 | + | ||
| 49 | +-keepattributes Signature | ||
| 50 | +-keepattributes *Annotation* | ||
| 51 | +-keep class com.squareup.okhttp.** { *; } | ||
| 52 | +-keep interface com.squareup.okhttp.** { *; } | ||
| 53 | +-dontwarn com.squareup.okhttp.** | ||
| 54 | + | ||
| 55 | +# okio | ||
| 56 | + | ||
| 57 | +-keep class sun.misc.Unsafe { *; } | ||
| 58 | +-dontwarn java.nio.file.* | ||
| 59 | +-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement | ||
| 60 | +-dontwarn okio.** |
Example/android/app/react.gradle
0 → 100644
| 1 | +def config = project.hasProperty("react") ? project.react : []; | ||
| 2 | + | ||
| 3 | +def bundleAssetName = config.bundleAssetName ?: "index.android.bundle" | ||
| 4 | +def entryFile = config.entryFile ?: "index.android.js" | ||
| 5 | + | ||
| 6 | +// because elvis operator | ||
| 7 | +def elvisFile(thing) { | ||
| 8 | + return thing ? file(thing) : null; | ||
| 9 | +} | ||
| 10 | + | ||
| 11 | +def reactRoot = elvisFile(config.root) ?: file("../../") | ||
| 12 | +def jsBundleDirDebug = elvisFile(config.jsBundleDirDebug) ?: | ||
| 13 | + file("$buildDir/intermediates/assets/debug") | ||
| 14 | +def jsBundleDirRelease = elvisFile(config.jsBundleDirRelease) ?: | ||
| 15 | + file("$buildDir/intermediates/assets/release") | ||
| 16 | +def resourcesDirDebug = elvisFile(config.resourcesDirDebug) ?: | ||
| 17 | + file("$buildDir/intermediates/res/merged/debug") | ||
| 18 | +def resourcesDirRelease = elvisFile(config.resourcesDirRelease) ?: | ||
| 19 | + file("$buildDir/intermediates/res/merged/release") | ||
| 20 | +def inputExcludes = config.inputExcludes ?: ["android/**", "ios/**"] | ||
| 21 | + | ||
| 22 | +def jsBundleFileDebug = file("$jsBundleDirDebug/$bundleAssetName") | ||
| 23 | +def jsBundleFileRelease = file("$jsBundleDirRelease/$bundleAssetName") | ||
| 24 | + | ||
| 25 | +task bundleDebugJsAndAssets(type: Exec) { | ||
| 26 | + // create dirs if they are not there (e.g. the "clean" task just ran) | ||
| 27 | + doFirst { | ||
| 28 | + jsBundleDirDebug.mkdirs() | ||
| 29 | + resourcesDirDebug.mkdirs() | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + // set up inputs and outputs so gradle can cache the result | ||
| 33 | + inputs.files fileTree(dir: reactRoot, excludes: inputExcludes) | ||
| 34 | + outputs.dir jsBundleDirDebug | ||
| 35 | + outputs.dir resourcesDirDebug | ||
| 36 | + | ||
| 37 | + // set up the call to the react-native cli | ||
| 38 | + workingDir reactRoot | ||
| 39 | + commandLine "react-native", "bundle", "--platform", "android", "--dev", "true", "--entry-file", | ||
| 40 | + entryFile, "--bundle-output", jsBundleFileDebug, "--assets-dest", resourcesDirDebug | ||
| 41 | + | ||
| 42 | + enabled config.bundleInDebug ?: false | ||
| 43 | +} | ||
| 44 | + | ||
| 45 | +task bundleReleaseJsAndAssets(type: Exec) { | ||
| 46 | + // create dirs if they are not there (e.g. the "clean" task just ran) | ||
| 47 | + doFirst { | ||
| 48 | + jsBundleDirRelease.mkdirs() | ||
| 49 | + resourcesDirRelease.mkdirs() | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + // set up inputs and outputs so gradle can cache the result | ||
| 53 | + inputs.files fileTree(dir: reactRoot, excludes: inputExcludes) | ||
| 54 | + outputs.dir jsBundleDirRelease | ||
| 55 | + outputs.dir resourcesDirRelease | ||
| 56 | + | ||
| 57 | + // set up the call to the react-native cli | ||
| 58 | + workingDir reactRoot | ||
| 59 | + commandLine "react-native", "bundle", "--platform", "android", "--dev", "false", "--entry-file", | ||
| 60 | + entryFile, "--bundle-output", jsBundleFileRelease, "--assets-dest", resourcesDirRelease | ||
| 61 | + | ||
| 62 | + enabled config.bundleInRelease ?: true | ||
| 63 | +} | ||
| 64 | + | ||
| 65 | +gradle.projectsEvaluated { | ||
| 66 | + // hook bundleDebugJsAndAssets into the android build process | ||
| 67 | + bundleDebugJsAndAssets.dependsOn mergeDebugResources | ||
| 68 | + bundleDebugJsAndAssets.dependsOn mergeDebugAssets | ||
| 69 | + processDebugResources.dependsOn bundleDebugJsAndAssets | ||
| 70 | + | ||
| 71 | + // hook bundleReleaseJsAndAssets into the android build process | ||
| 72 | + bundleReleaseJsAndAssets.dependsOn mergeReleaseResources | ||
| 73 | + bundleReleaseJsAndAssets.dependsOn mergeReleaseAssets | ||
| 74 | + processReleaseResources.dependsOn bundleReleaseJsAndAssets | ||
| 75 | +} |
| 1 | +<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 2 | + package="com.example"> | ||
| 3 | + | ||
| 4 | + <uses-permission android:name="android.permission.INTERNET" /> | ||
| 5 | + | ||
| 6 | + <application | ||
| 7 | + android:allowBackup="true" | ||
| 8 | + android:label="@string/app_name" | ||
| 9 | + android:icon="@mipmap/ic_launcher" | ||
| 10 | + android:theme="@style/AppTheme"> | ||
| 11 | + <activity | ||
| 12 | + android:name=".MainActivity" | ||
| 13 | + android:label="@string/app_name"> | ||
| 14 | + <intent-filter> | ||
| 15 | + <action android:name="android.intent.action.MAIN" /> | ||
| 16 | + <category android:name="android.intent.category.LAUNCHER" /> | ||
| 17 | + </intent-filter> | ||
| 18 | + </activity> | ||
| 19 | + <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" /> | ||
| 20 | + </application> | ||
| 21 | + | ||
| 22 | +</manifest> |
| 1 | +package com.example; | ||
| 2 | + | ||
| 3 | +import android.app.Activity; | ||
| 4 | +import android.os.Bundle; | ||
| 5 | +import android.view.KeyEvent; | ||
| 6 | + | ||
| 7 | +import com.facebook.react.LifecycleState; | ||
| 8 | +import com.facebook.react.ReactInstanceManager; | ||
| 9 | +import com.facebook.react.ReactRootView; | ||
| 10 | +import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; | ||
| 11 | +import com.facebook.react.shell.MainReactPackage; | ||
| 12 | +import com.facebook.soloader.SoLoader; | ||
| 13 | + | ||
| 14 | +public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler { | ||
| 15 | + | ||
| 16 | + private ReactInstanceManager mReactInstanceManager; | ||
| 17 | + private ReactRootView mReactRootView; | ||
| 18 | + | ||
| 19 | + @Override | ||
| 20 | + protected void onCreate(Bundle savedInstanceState) { | ||
| 21 | + super.onCreate(savedInstanceState); | ||
| 22 | + mReactRootView = new ReactRootView(this); | ||
| 23 | + | ||
| 24 | + mReactInstanceManager = ReactInstanceManager.builder() | ||
| 25 | + .setApplication(getApplication()) | ||
| 26 | + .setBundleAssetName("index.android.bundle") | ||
| 27 | + .setJSMainModuleName("index.android") | ||
| 28 | + .addPackage(new MainReactPackage()) | ||
| 29 | + .setUseDeveloperSupport(BuildConfig.DEBUG) | ||
| 30 | + .setInitialLifecycleState(LifecycleState.RESUMED) | ||
| 31 | + .build(); | ||
| 32 | + | ||
| 33 | + mReactRootView.startReactApplication(mReactInstanceManager, "Example", null); | ||
| 34 | + | ||
| 35 | + setContentView(mReactRootView); | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + @Override | ||
| 39 | + public boolean onKeyUp(int keyCode, KeyEvent event) { | ||
| 40 | + if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) { | ||
| 41 | + mReactInstanceManager.showDevOptionsDialog(); | ||
| 42 | + return true; | ||
| 43 | + } | ||
| 44 | + return super.onKeyUp(keyCode, event); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + @Override | ||
| 48 | + public void onBackPressed() { | ||
| 49 | + if (mReactInstanceManager != null) { | ||
| 50 | + mReactInstanceManager.onBackPressed(); | ||
| 51 | + } else { | ||
| 52 | + super.onBackPressed(); | ||
| 53 | + } | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + @Override | ||
| 57 | + public void invokeDefaultOnBackPressed() { | ||
| 58 | + super.onBackPressed(); | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + @Override | ||
| 62 | + protected void onPause() { | ||
| 63 | + super.onPause(); | ||
| 64 | + | ||
| 65 | + if (mReactInstanceManager != null) { | ||
| 66 | + mReactInstanceManager.onPause(); | ||
| 67 | + } | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + @Override | ||
| 71 | + protected void onResume() { | ||
| 72 | + super.onResume(); | ||
| 73 | + | ||
| 74 | + if (mReactInstanceManager != null) { | ||
| 75 | + mReactInstanceManager.onResume(this); | ||
| 76 | + } | ||
| 77 | + } | ||
| 78 | +} |
3.3 KB
2.2 KB
4.7 KB
7.5 KB
Example/android/build.gradle
0 → 100644
| 1 | +// Top-level build file where you can add configuration options common to all sub-projects/modules. | ||
| 2 | + | ||
| 3 | +buildscript { | ||
| 4 | + repositories { | ||
| 5 | + jcenter() | ||
| 6 | + } | ||
| 7 | + dependencies { | ||
| 8 | + classpath 'com.android.tools.build:gradle:1.3.1' | ||
| 9 | + | ||
| 10 | + // NOTE: Do not place your application dependencies here; they belong | ||
| 11 | + // in the individual module build.gradle files | ||
| 12 | + } | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | +allprojects { | ||
| 16 | + repositories { | ||
| 17 | + mavenLocal() | ||
| 18 | + jcenter() | ||
| 19 | + } | ||
| 20 | +} |
Example/android/gradle.properties
0 → 100644
| 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.useDeprecatedNdk=true |
不能预览此文件类型
Example/android/gradlew
0 → 100755
| 1 | +#!/usr/bin/env bash | ||
| 2 | + | ||
| 3 | +############################################################################## | ||
| 4 | +## | ||
| 5 | +## Gradle start up script for UN*X | ||
| 6 | +## | ||
| 7 | +############################################################################## | ||
| 8 | + | ||
| 9 | +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||
| 10 | +DEFAULT_JVM_OPTS="" | ||
| 11 | + | ||
| 12 | +APP_NAME="Gradle" | ||
| 13 | +APP_BASE_NAME=`basename "$0"` | ||
| 14 | + | ||
| 15 | +# Use the maximum available, or set MAX_FD != -1 to use that value. | ||
| 16 | +MAX_FD="maximum" | ||
| 17 | + | ||
| 18 | +warn ( ) { | ||
| 19 | + echo "$*" | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +die ( ) { | ||
| 23 | + echo | ||
| 24 | + echo "$*" | ||
| 25 | + echo | ||
| 26 | + exit 1 | ||
| 27 | +} | ||
| 28 | + | ||
| 29 | +# OS specific support (must be 'true' or 'false'). | ||
| 30 | +cygwin=false | ||
| 31 | +msys=false | ||
| 32 | +darwin=false | ||
| 33 | +case "`uname`" in | ||
| 34 | + CYGWIN* ) | ||
| 35 | + cygwin=true | ||
| 36 | + ;; | ||
| 37 | + Darwin* ) | ||
| 38 | + darwin=true | ||
| 39 | + ;; | ||
| 40 | + MINGW* ) | ||
| 41 | + msys=true | ||
| 42 | + ;; | ||
| 43 | +esac | ||
| 44 | + | ||
| 45 | +# For Cygwin, ensure paths are in UNIX format before anything is touched. | ||
| 46 | +if $cygwin ; then | ||
| 47 | + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` | ||
| 48 | +fi | ||
| 49 | + | ||
| 50 | +# Attempt to set APP_HOME | ||
| 51 | +# Resolve links: $0 may be a link | ||
| 52 | +PRG="$0" | ||
| 53 | +# Need this for relative symlinks. | ||
| 54 | +while [ -h "$PRG" ] ; do | ||
| 55 | + ls=`ls -ld "$PRG"` | ||
| 56 | + link=`expr "$ls" : '.*-> \(.*\)$'` | ||
| 57 | + if expr "$link" : '/.*' > /dev/null; then | ||
| 58 | + PRG="$link" | ||
| 59 | + else | ||
| 60 | + PRG=`dirname "$PRG"`"/$link" | ||
| 61 | + fi | ||
| 62 | +done | ||
| 63 | +SAVED="`pwd`" | ||
| 64 | +cd "`dirname \"$PRG\"`/" >&- | ||
| 65 | +APP_HOME="`pwd -P`" | ||
| 66 | +cd "$SAVED" >&- | ||
| 67 | + | ||
| 68 | +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | ||
| 69 | + | ||
| 70 | +# Determine the Java command to use to start the JVM. | ||
| 71 | +if [ -n "$JAVA_HOME" ] ; then | ||
| 72 | + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | ||
| 73 | + # IBM's JDK on AIX uses strange locations for the executables | ||
| 74 | + JAVACMD="$JAVA_HOME/jre/sh/java" | ||
| 75 | + else | ||
| 76 | + JAVACMD="$JAVA_HOME/bin/java" | ||
| 77 | + fi | ||
| 78 | + if [ ! -x "$JAVACMD" ] ; then | ||
| 79 | + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME | ||
| 80 | + | ||
| 81 | +Please set the JAVA_HOME variable in your environment to match the | ||
| 82 | +location of your Java installation." | ||
| 83 | + fi | ||
| 84 | +else | ||
| 85 | + JAVACMD="java" | ||
| 86 | + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||
| 87 | + | ||
| 88 | +Please set the JAVA_HOME variable in your environment to match the | ||
| 89 | +location of your Java installation." | ||
| 90 | +fi | ||
| 91 | + | ||
| 92 | +# Increase the maximum file descriptors if we can. | ||
| 93 | +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then | ||
| 94 | + MAX_FD_LIMIT=`ulimit -H -n` | ||
| 95 | + if [ $? -eq 0 ] ; then | ||
| 96 | + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then | ||
| 97 | + MAX_FD="$MAX_FD_LIMIT" | ||
| 98 | + fi | ||
| 99 | + ulimit -n $MAX_FD | ||
| 100 | + if [ $? -ne 0 ] ; then | ||
| 101 | + warn "Could not set maximum file descriptor limit: $MAX_FD" | ||
| 102 | + fi | ||
| 103 | + else | ||
| 104 | + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" | ||
| 105 | + fi | ||
| 106 | +fi | ||
| 107 | + | ||
| 108 | +# For Darwin, add options to specify how the application appears in the dock | ||
| 109 | +if $darwin; then | ||
| 110 | + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" | ||
| 111 | +fi | ||
| 112 | + | ||
| 113 | +# For Cygwin, switch paths to Windows format before running java | ||
| 114 | +if $cygwin ; then | ||
| 115 | + APP_HOME=`cygpath --path --mixed "$APP_HOME"` | ||
| 116 | + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` | ||
| 117 | + | ||
| 118 | + # We build the pattern for arguments to be converted via cygpath | ||
| 119 | + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` | ||
| 120 | + SEP="" | ||
| 121 | + for dir in $ROOTDIRSRAW ; do | ||
| 122 | + ROOTDIRS="$ROOTDIRS$SEP$dir" | ||
| 123 | + SEP="|" | ||
| 124 | + done | ||
| 125 | + OURCYGPATTERN="(^($ROOTDIRS))" | ||
| 126 | + # Add a user-defined pattern to the cygpath arguments | ||
| 127 | + if [ "$GRADLE_CYGPATTERN" != "" ] ; then | ||
| 128 | + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" | ||
| 129 | + fi | ||
| 130 | + # Now convert the arguments - kludge to limit ourselves to /bin/sh | ||
| 131 | + i=0 | ||
| 132 | + for arg in "$@" ; do | ||
| 133 | + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` | ||
| 134 | + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option | ||
| 135 | + | ||
| 136 | + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition | ||
| 137 | + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` | ||
| 138 | + else | ||
| 139 | + eval `echo args$i`="\"$arg\"" | ||
| 140 | + fi | ||
| 141 | + i=$((i+1)) | ||
| 142 | + done | ||
| 143 | + case $i in | ||
| 144 | + (0) set -- ;; | ||
| 145 | + (1) set -- "$args0" ;; | ||
| 146 | + (2) set -- "$args0" "$args1" ;; | ||
| 147 | + (3) set -- "$args0" "$args1" "$args2" ;; | ||
| 148 | + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; | ||
| 149 | + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; | ||
| 150 | + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; | ||
| 151 | + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; | ||
| 152 | + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; | ||
| 153 | + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; | ||
| 154 | + esac | ||
| 155 | +fi | ||
| 156 | + | ||
| 157 | +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules | ||
| 158 | +function splitJvmOpts() { | ||
| 159 | + JVM_OPTS=("$@") | ||
| 160 | +} | ||
| 161 | +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS | ||
| 162 | +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" | ||
| 163 | + | ||
| 164 | +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" |
Example/android/gradlew.bat
0 → 100644
| 1 | +@if "%DEBUG%" == "" @echo off | ||
| 2 | +@rem ########################################################################## | ||
| 3 | +@rem | ||
| 4 | +@rem Gradle startup script for Windows | ||
| 5 | +@rem | ||
| 6 | +@rem ########################################################################## | ||
| 7 | + | ||
| 8 | +@rem Set local scope for the variables with windows NT shell | ||
| 9 | +if "%OS%"=="Windows_NT" setlocal | ||
| 10 | + | ||
| 11 | +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||
| 12 | +set DEFAULT_JVM_OPTS= | ||
| 13 | + | ||
| 14 | +set DIRNAME=%~dp0 | ||
| 15 | +if "%DIRNAME%" == "" set DIRNAME=. | ||
| 16 | +set APP_BASE_NAME=%~n0 | ||
| 17 | +set APP_HOME=%DIRNAME% | ||
| 18 | + | ||
| 19 | +@rem Find java.exe | ||
| 20 | +if defined JAVA_HOME goto findJavaFromJavaHome | ||
| 21 | + | ||
| 22 | +set JAVA_EXE=java.exe | ||
| 23 | +%JAVA_EXE% -version >NUL 2>&1 | ||
| 24 | +if "%ERRORLEVEL%" == "0" goto init | ||
| 25 | + | ||
| 26 | +echo. | ||
| 27 | +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||
| 28 | +echo. | ||
| 29 | +echo Please set the JAVA_HOME variable in your environment to match the | ||
| 30 | +echo location of your Java installation. | ||
| 31 | + | ||
| 32 | +goto fail | ||
| 33 | + | ||
| 34 | +:findJavaFromJavaHome | ||
| 35 | +set JAVA_HOME=%JAVA_HOME:"=% | ||
| 36 | +set JAVA_EXE=%JAVA_HOME%/bin/java.exe | ||
| 37 | + | ||
| 38 | +if exist "%JAVA_EXE%" goto init | ||
| 39 | + | ||
| 40 | +echo. | ||
| 41 | +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | ||
| 42 | +echo. | ||
| 43 | +echo Please set the JAVA_HOME variable in your environment to match the | ||
| 44 | +echo location of your Java installation. | ||
| 45 | + | ||
| 46 | +goto fail | ||
| 47 | + | ||
| 48 | +:init | ||
| 49 | +@rem Get command-line arguments, handling Windowz variants | ||
| 50 | + | ||
| 51 | +if not "%OS%" == "Windows_NT" goto win9xME_args | ||
| 52 | +if "%@eval[2+2]" == "4" goto 4NT_args | ||
| 53 | + | ||
| 54 | +:win9xME_args | ||
| 55 | +@rem Slurp the command line arguments. | ||
| 56 | +set CMD_LINE_ARGS= | ||
| 57 | +set _SKIP=2 | ||
| 58 | + | ||
| 59 | +:win9xME_args_slurp | ||
| 60 | +if "x%~1" == "x" goto execute | ||
| 61 | + | ||
| 62 | +set CMD_LINE_ARGS=%* | ||
| 63 | +goto execute | ||
| 64 | + | ||
| 65 | +:4NT_args | ||
| 66 | +@rem Get arguments from the 4NT Shell from JP Software | ||
| 67 | +set CMD_LINE_ARGS=%$ | ||
| 68 | + | ||
| 69 | +:execute | ||
| 70 | +@rem Setup the command line | ||
| 71 | + | ||
| 72 | +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar | ||
| 73 | + | ||
| 74 | +@rem Execute Gradle | ||
| 75 | +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% | ||
| 76 | + | ||
| 77 | +:end | ||
| 78 | +@rem End local scope for the variables with windows NT shell | ||
| 79 | +if "%ERRORLEVEL%"=="0" goto mainEnd | ||
| 80 | + | ||
| 81 | +:fail | ||
| 82 | +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of | ||
| 83 | +rem the _cmd.exe /c_ return code! | ||
| 84 | +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 | ||
| 85 | +exit /b 1 | ||
| 86 | + | ||
| 87 | +:mainEnd | ||
| 88 | +if "%OS%"=="Windows_NT" endlocal | ||
| 89 | + | ||
| 90 | +:omega |
Example/android/settings.gradle
0 → 100644
Example/index.android.js
0 → 100644
| 1 | +/** | ||
| 2 | + * Sample React Native App | ||
| 3 | + * https://github.com/facebook/react-native | ||
| 4 | + */ | ||
| 5 | +'use strict'; | ||
| 6 | + | ||
| 7 | +var React = require('react-native'); | ||
| 8 | +var { | ||
| 9 | + AppRegistry, | ||
| 10 | + StyleSheet, | ||
| 11 | + Text, | ||
| 12 | + View, | ||
| 13 | +} = React; | ||
| 14 | + | ||
| 15 | +var Example = React.createClass({ | ||
| 16 | + render: function() { | ||
| 17 | + return ( | ||
| 18 | + <View style={styles.container}> | ||
| 19 | + <Text style={styles.welcome}> | ||
| 20 | + Welcome to React Native! | ||
| 21 | + </Text> | ||
| 22 | + <Text style={styles.instructions}> | ||
| 23 | + To get started, edit index.android.js | ||
| 24 | + </Text> | ||
| 25 | + <Text style={styles.instructions}> | ||
| 26 | + Shake or press menu button for dev menu | ||
| 27 | + </Text> | ||
| 28 | + </View> | ||
| 29 | + ); | ||
| 30 | + } | ||
| 31 | +}); | ||
| 32 | + | ||
| 33 | +var styles = StyleSheet.create({ | ||
| 34 | + container: { | ||
| 35 | + flex: 1, | ||
| 36 | + justifyContent: 'center', | ||
| 37 | + alignItems: 'center', | ||
| 38 | + backgroundColor: '#F5FCFF', | ||
| 39 | + }, | ||
| 40 | + welcome: { | ||
| 41 | + fontSize: 20, | ||
| 42 | + textAlign: 'center', | ||
| 43 | + margin: 10, | ||
| 44 | + }, | ||
| 45 | + instructions: { | ||
| 46 | + textAlign: 'center', | ||
| 47 | + color: '#333333', | ||
| 48 | + marginBottom: 5, | ||
| 49 | + }, | ||
| 50 | +}); | ||
| 51 | + | ||
| 52 | +AppRegistry.registerComponent('Example', () => Example); |
Example/index.ios.js
0 → 100644
| 1 | +/** | ||
| 2 | + * Sample React Native App | ||
| 3 | + * https://github.com/facebook/react-native | ||
| 4 | + */ | ||
| 5 | +"use strict"; | ||
| 6 | + | ||
| 7 | +var React = require('react-native'); | ||
| 8 | +var { | ||
| 9 | + AppRegistry, | ||
| 10 | + StyleSheet, | ||
| 11 | + Text, | ||
| 12 | + View, | ||
| 13 | + TouchableOpacity | ||
| 14 | +} = React; | ||
| 15 | +var WeChat = require('./react-native-wechat.js'); | ||
| 16 | + | ||
| 17 | +class Example extends React.Component { | ||
| 18 | + constructor(props) { | ||
| 19 | + super(props); | ||
| 20 | + this.state = { | ||
| 21 | + apiVersion: 'waiting...', | ||
| 22 | + wxAppInstallUrl: 'waiting...', | ||
| 23 | + isWXAppSupportApi: 'waiting...', | ||
| 24 | + isWXAppInstalled: 'waiting...', | ||
| 25 | + }; | ||
| 26 | + } | ||
| 27 | + async componentDidMount() { | ||
| 28 | + try { | ||
| 29 | + await WeChat.registerApp('1234567'); | ||
| 30 | + this.setState({ | ||
| 31 | + apiVersion: await WeChat.getApiVersion(), | ||
| 32 | + wxAppInstallUrl: await WeChat.getWXAppInstallUrl(), | ||
| 33 | + isWXAppSupportApi: await WeChat.isWXAppSupportApi(), | ||
| 34 | + isWXAppInstalled: await WeChat.isWXAppInstalled() | ||
| 35 | + }); | ||
| 36 | + console.log(this.state); | ||
| 37 | + } catch (e) { | ||
| 38 | + console.error(e); | ||
| 39 | + } | ||
| 40 | + console.log(WeChat); | ||
| 41 | + // console.log('getApiVersion', typeof WeChat.getApiVersion); | ||
| 42 | + // console.log('getWXAppInstallUrl', typeof WeChat.getWXAppInstallUrl); | ||
| 43 | + // console.log('sendRequest', typeof WeChat.sendRequest); | ||
| 44 | + // console.log('registerApp', typeof WeChat.registerApp); | ||
| 45 | + // console.log('sendErrorCommonResponse', typeof WeChat.sendErrorCommonResponse); | ||
| 46 | + // console.log('sendErrorUserCancelResponse', typeof WeChat.sendErrorUserCancelResponse); | ||
| 47 | + // console.log('sendAuthRequest', typeof WeChat.sendAuthRequest); | ||
| 48 | + // console.log('getWXAppInstallUrl', typeof WeChat.getWXAppInstallUrl); | ||
| 49 | + // console.log('openWXApp', typeof WeChat.openWXApp); | ||
| 50 | + // console.log('registerAppWithDescription', typeof WeChat.registerAppWithDescription); | ||
| 51 | + // console.log('isWXAppSupportApi', typeof WeChat.isWXAppSupportApi); | ||
| 52 | + // console.log('isWXAppInstalled', typeof WeChat.isWXAppInstalled); | ||
| 53 | + } | ||
| 54 | + render() { | ||
| 55 | + return ( | ||
| 56 | + <View style={styles.container}> | ||
| 57 | + <Text>api版本:{this.state.apiVersion}</Text> | ||
| 58 | + <Text>微信注册url:{this.state.wxAppInstallUrl}</Text> | ||
| 59 | + <Text>是否支持api:{String(this.state.isWXAppSupportApi)}</Text> | ||
| 60 | + <Text>是否安装微信:{String(this.state.isWXAppInstalled)}</Text> | ||
| 61 | + <TouchableOpacity onPress={this._openWXApp}> | ||
| 62 | + <Text>打开微信</Text> | ||
| 63 | + </TouchableOpacity> | ||
| 64 | + </View> | ||
| 65 | + ); | ||
| 66 | + } | ||
| 67 | + async _openWXApp() { | ||
| 68 | + await WeChat.openWXApp(); | ||
| 69 | + } | ||
| 70 | +} | ||
| 71 | + | ||
| 72 | +var styles = StyleSheet.create({ | ||
| 73 | + container: { | ||
| 74 | + flex: 1, | ||
| 75 | + justifyContent: 'center', | ||
| 76 | + alignItems: 'center', | ||
| 77 | + backgroundColor: '#F5FCFF', | ||
| 78 | + }, | ||
| 79 | + welcome: { | ||
| 80 | + fontSize: 20, | ||
| 81 | + textAlign: 'center', | ||
| 82 | + margin: 10, | ||
| 83 | + }, | ||
| 84 | + instructions: { | ||
| 85 | + textAlign: 'center', | ||
| 86 | + color: '#333333', | ||
| 87 | + marginBottom: 5, | ||
| 88 | + }, | ||
| 89 | +}); | ||
| 90 | + | ||
| 91 | +AppRegistry.registerComponent('Example', () => Example); |
| 1 | +// !$*UTF8*$! | ||
| 2 | +{ | ||
| 3 | + archiveVersion = 1; | ||
| 4 | + classes = { | ||
| 5 | + }; | ||
| 6 | + objectVersion = 46; | ||
| 7 | + objects = { | ||
| 8 | + | ||
| 9 | +/* Begin PBXBuildFile section */ | ||
| 10 | + 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; | ||
| 11 | + 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; | ||
| 12 | + 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; }; | ||
| 13 | + 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; }; | ||
| 14 | + 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; }; | ||
| 15 | + 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; }; | ||
| 16 | + 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; }; | ||
| 17 | + 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; }; | ||
| 18 | + 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; | ||
| 19 | + 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; | ||
| 20 | + 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; | ||
| 21 | + 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; | ||
| 22 | + 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; | ||
| 23 | + 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; | ||
| 24 | + 869DDDD71BFB274800372700 /* libRCTWeChat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 869DDDD51BFB273B00372700 /* libRCTWeChat.a */; }; | ||
| 25 | + 869DDDD91BFB294F00372700 /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 869DDDD81BFB294F00372700 /* CoreTelephony.framework */; }; | ||
| 26 | + 869DDDDB1BFB295E00372700 /* libsqlite3.0.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 869DDDDA1BFB295E00372700 /* libsqlite3.0.tbd */; }; | ||
| 27 | + 869DDDDD1BFB296700372700 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 869DDDDC1BFB296700372700 /* libc++.tbd */; }; | ||
| 28 | + 869DDDDF1BFB296F00372700 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 869DDDDE1BFB296F00372700 /* libz.tbd */; }; | ||
| 29 | +/* End PBXBuildFile section */ | ||
| 30 | + | ||
| 31 | +/* Begin PBXContainerItemProxy section */ | ||
| 32 | + 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */ = { | ||
| 33 | + isa = PBXContainerItemProxy; | ||
| 34 | + containerPortal = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; | ||
| 35 | + proxyType = 2; | ||
| 36 | + remoteGlobalIDString = 134814201AA4EA6300B7C361; | ||
| 37 | + remoteInfo = RCTActionSheet; | ||
| 38 | + }; | ||
| 39 | + 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = { | ||
| 40 | + isa = PBXContainerItemProxy; | ||
| 41 | + containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; | ||
| 42 | + proxyType = 2; | ||
| 43 | + remoteGlobalIDString = 134814201AA4EA6300B7C361; | ||
| 44 | + remoteInfo = RCTGeolocation; | ||
| 45 | + }; | ||
| 46 | + 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = { | ||
| 47 | + isa = PBXContainerItemProxy; | ||
| 48 | + containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; | ||
| 49 | + proxyType = 2; | ||
| 50 | + remoteGlobalIDString = 58B5115D1A9E6B3D00147676; | ||
| 51 | + remoteInfo = RCTImage; | ||
| 52 | + }; | ||
| 53 | + 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */ = { | ||
| 54 | + isa = PBXContainerItemProxy; | ||
| 55 | + containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; | ||
| 56 | + proxyType = 2; | ||
| 57 | + remoteGlobalIDString = 58B511DB1A9E6C8500147676; | ||
| 58 | + remoteInfo = RCTNetwork; | ||
| 59 | + }; | ||
| 60 | + 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */ = { | ||
| 61 | + isa = PBXContainerItemProxy; | ||
| 62 | + containerPortal = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; | ||
| 63 | + proxyType = 2; | ||
| 64 | + remoteGlobalIDString = 832C81801AAF6DEF007FA2F7; | ||
| 65 | + remoteInfo = RCTVibration; | ||
| 66 | + }; | ||
| 67 | + 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = { | ||
| 68 | + isa = PBXContainerItemProxy; | ||
| 69 | + containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; | ||
| 70 | + proxyType = 2; | ||
| 71 | + remoteGlobalIDString = 134814201AA4EA6300B7C361; | ||
| 72 | + remoteInfo = RCTSettings; | ||
| 73 | + }; | ||
| 74 | + 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */ = { | ||
| 75 | + isa = PBXContainerItemProxy; | ||
| 76 | + containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; | ||
| 77 | + proxyType = 2; | ||
| 78 | + remoteGlobalIDString = 3C86DF461ADF2C930047B81A; | ||
| 79 | + remoteInfo = RCTWebSocket; | ||
| 80 | + }; | ||
| 81 | + 146834031AC3E56700842450 /* PBXContainerItemProxy */ = { | ||
| 82 | + isa = PBXContainerItemProxy; | ||
| 83 | + containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; | ||
| 84 | + proxyType = 2; | ||
| 85 | + remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192; | ||
| 86 | + remoteInfo = React; | ||
| 87 | + }; | ||
| 88 | + 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = { | ||
| 89 | + isa = PBXContainerItemProxy; | ||
| 90 | + containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; | ||
| 91 | + proxyType = 2; | ||
| 92 | + remoteGlobalIDString = 134814201AA4EA6300B7C361; | ||
| 93 | + remoteInfo = RCTLinking; | ||
| 94 | + }; | ||
| 95 | + 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = { | ||
| 96 | + isa = PBXContainerItemProxy; | ||
| 97 | + containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; | ||
| 98 | + proxyType = 2; | ||
| 99 | + remoteGlobalIDString = 58B5119B1A9E6C1200147676; | ||
| 100 | + remoteInfo = RCTText; | ||
| 101 | + }; | ||
| 102 | + 869DDDD41BFB273B00372700 /* PBXContainerItemProxy */ = { | ||
| 103 | + isa = PBXContainerItemProxy; | ||
| 104 | + containerPortal = 869DDDC71BFB273A00372700 /* RCTWeChat.xcodeproj */; | ||
| 105 | + proxyType = 2; | ||
| 106 | + remoteGlobalIDString = 86D238421BD0BB9E00C75D01; | ||
| 107 | + remoteInfo = RCTWeChat; | ||
| 108 | + }; | ||
| 109 | +/* End PBXContainerItemProxy section */ | ||
| 110 | + | ||
| 111 | +/* Begin PBXFileReference section */ | ||
| 112 | + 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; }; | ||
| 113 | + 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = "<group>"; }; | ||
| 114 | + 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = "<group>"; }; | ||
| 115 | + 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = "<group>"; }; | ||
| 116 | + 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = "<group>"; }; | ||
| 117 | + 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = "<group>"; }; | ||
| 118 | + 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = "<group>"; }; | ||
| 119 | + 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = "<group>"; }; | ||
| 120 | + 13B07F961A680F5B00A75B9A /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; | ||
| 121 | + 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Example/AppDelegate.h; sourceTree = "<group>"; }; | ||
| 122 | + 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Example/AppDelegate.m; sourceTree = "<group>"; }; | ||
| 123 | + 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; }; | ||
| 124 | + 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Example/Images.xcassets; sourceTree = "<group>"; }; | ||
| 125 | + 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Example/Info.plist; sourceTree = "<group>"; }; | ||
| 126 | + 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Example/main.m; sourceTree = "<group>"; }; | ||
| 127 | + 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; }; | ||
| 128 | + 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; }; | ||
| 129 | + 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; }; | ||
| 130 | + 869DDDC71BFB273A00372700 /* RCTWeChat.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWeChat.xcodeproj; path = ../../ios/RCTWeChat.xcodeproj; sourceTree = "<group>"; }; | ||
| 131 | + 869DDDD81BFB294F00372700 /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; }; | ||
| 132 | + 869DDDDA1BFB295E00372700 /* libsqlite3.0.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.0.tbd; path = usr/lib/libsqlite3.0.tbd; sourceTree = SDKROOT; }; | ||
| 133 | + 869DDDDC1BFB296700372700 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; }; | ||
| 134 | + 869DDDDE1BFB296F00372700 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; | ||
| 135 | +/* End PBXFileReference section */ | ||
| 136 | + | ||
| 137 | +/* Begin PBXFrameworksBuildPhase section */ | ||
| 138 | + 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { | ||
| 139 | + isa = PBXFrameworksBuildPhase; | ||
| 140 | + buildActionMask = 2147483647; | ||
| 141 | + files = ( | ||
| 142 | + 869DDDDF1BFB296F00372700 /* libz.tbd in Frameworks */, | ||
| 143 | + 869DDDDD1BFB296700372700 /* libc++.tbd in Frameworks */, | ||
| 144 | + 869DDDDB1BFB295E00372700 /* libsqlite3.0.tbd in Frameworks */, | ||
| 145 | + 869DDDD91BFB294F00372700 /* CoreTelephony.framework in Frameworks */, | ||
| 146 | + 869DDDD71BFB274800372700 /* libRCTWeChat.a in Frameworks */, | ||
| 147 | + 146834051AC3E58100842450 /* libReact.a in Frameworks */, | ||
| 148 | + 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, | ||
| 149 | + 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, | ||
| 150 | + 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */, | ||
| 151 | + 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */, | ||
| 152 | + 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */, | ||
| 153 | + 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */, | ||
| 154 | + 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, | ||
| 155 | + 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, | ||
| 156 | + 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, | ||
| 157 | + ); | ||
| 158 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 159 | + }; | ||
| 160 | +/* End PBXFrameworksBuildPhase section */ | ||
| 161 | + | ||
| 162 | +/* Begin PBXGroup section */ | ||
| 163 | + 00C302A81ABCB8CE00DB3ED1 /* Products */ = { | ||
| 164 | + isa = PBXGroup; | ||
| 165 | + children = ( | ||
| 166 | + 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */, | ||
| 167 | + ); | ||
| 168 | + name = Products; | ||
| 169 | + sourceTree = "<group>"; | ||
| 170 | + }; | ||
| 171 | + 00C302B61ABCB90400DB3ED1 /* Products */ = { | ||
| 172 | + isa = PBXGroup; | ||
| 173 | + children = ( | ||
| 174 | + 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */, | ||
| 175 | + ); | ||
| 176 | + name = Products; | ||
| 177 | + sourceTree = "<group>"; | ||
| 178 | + }; | ||
| 179 | + 00C302BC1ABCB91800DB3ED1 /* Products */ = { | ||
| 180 | + isa = PBXGroup; | ||
| 181 | + children = ( | ||
| 182 | + 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */, | ||
| 183 | + ); | ||
| 184 | + name = Products; | ||
| 185 | + sourceTree = "<group>"; | ||
| 186 | + }; | ||
| 187 | + 00C302D41ABCB9D200DB3ED1 /* Products */ = { | ||
| 188 | + isa = PBXGroup; | ||
| 189 | + children = ( | ||
| 190 | + 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */, | ||
| 191 | + ); | ||
| 192 | + name = Products; | ||
| 193 | + sourceTree = "<group>"; | ||
| 194 | + }; | ||
| 195 | + 00C302E01ABCB9EE00DB3ED1 /* Products */ = { | ||
| 196 | + isa = PBXGroup; | ||
| 197 | + children = ( | ||
| 198 | + 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */, | ||
| 199 | + ); | ||
| 200 | + name = Products; | ||
| 201 | + sourceTree = "<group>"; | ||
| 202 | + }; | ||
| 203 | + 139105B71AF99BAD00B5F7CC /* Products */ = { | ||
| 204 | + isa = PBXGroup; | ||
| 205 | + children = ( | ||
| 206 | + 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */, | ||
| 207 | + ); | ||
| 208 | + name = Products; | ||
| 209 | + sourceTree = "<group>"; | ||
| 210 | + }; | ||
| 211 | + 139FDEE71B06529A00C62182 /* Products */ = { | ||
| 212 | + isa = PBXGroup; | ||
| 213 | + children = ( | ||
| 214 | + 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */, | ||
| 215 | + ); | ||
| 216 | + name = Products; | ||
| 217 | + sourceTree = "<group>"; | ||
| 218 | + }; | ||
| 219 | + 13B07FAE1A68108700A75B9A /* Example */ = { | ||
| 220 | + isa = PBXGroup; | ||
| 221 | + children = ( | ||
| 222 | + 008F07F21AC5B25A0029DE68 /* main.jsbundle */, | ||
| 223 | + 13B07FAF1A68108700A75B9A /* AppDelegate.h */, | ||
| 224 | + 13B07FB01A68108700A75B9A /* AppDelegate.m */, | ||
| 225 | + 13B07FB51A68108700A75B9A /* Images.xcassets */, | ||
| 226 | + 13B07FB61A68108700A75B9A /* Info.plist */, | ||
| 227 | + 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, | ||
| 228 | + 13B07FB71A68108700A75B9A /* main.m */, | ||
| 229 | + ); | ||
| 230 | + name = Example; | ||
| 231 | + sourceTree = "<group>"; | ||
| 232 | + }; | ||
| 233 | + 146834001AC3E56700842450 /* Products */ = { | ||
| 234 | + isa = PBXGroup; | ||
| 235 | + children = ( | ||
| 236 | + 146834041AC3E56700842450 /* libReact.a */, | ||
| 237 | + ); | ||
| 238 | + name = Products; | ||
| 239 | + sourceTree = "<group>"; | ||
| 240 | + }; | ||
| 241 | + 78C398B11ACF4ADC00677621 /* Products */ = { | ||
| 242 | + isa = PBXGroup; | ||
| 243 | + children = ( | ||
| 244 | + 78C398B91ACF4ADC00677621 /* libRCTLinking.a */, | ||
| 245 | + ); | ||
| 246 | + name = Products; | ||
| 247 | + sourceTree = "<group>"; | ||
| 248 | + }; | ||
| 249 | + 832341AE1AAA6A7D00B99B32 /* Libraries */ = { | ||
| 250 | + isa = PBXGroup; | ||
| 251 | + children = ( | ||
| 252 | + 869DDDC71BFB273A00372700 /* RCTWeChat.xcodeproj */, | ||
| 253 | + 146833FF1AC3E56700842450 /* React.xcodeproj */, | ||
| 254 | + 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, | ||
| 255 | + 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, | ||
| 256 | + 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */, | ||
| 257 | + 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */, | ||
| 258 | + 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */, | ||
| 259 | + 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */, | ||
| 260 | + 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */, | ||
| 261 | + 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */, | ||
| 262 | + 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */, | ||
| 263 | + ); | ||
| 264 | + name = Libraries; | ||
| 265 | + sourceTree = "<group>"; | ||
| 266 | + }; | ||
| 267 | + 832341B11AAA6A8300B99B32 /* Products */ = { | ||
| 268 | + isa = PBXGroup; | ||
| 269 | + children = ( | ||
| 270 | + 832341B51AAA6A8300B99B32 /* libRCTText.a */, | ||
| 271 | + ); | ||
| 272 | + name = Products; | ||
| 273 | + sourceTree = "<group>"; | ||
| 274 | + }; | ||
| 275 | + 83CBB9F61A601CBA00E9B192 = { | ||
| 276 | + isa = PBXGroup; | ||
| 277 | + children = ( | ||
| 278 | + 869DDDDE1BFB296F00372700 /* libz.tbd */, | ||
| 279 | + 869DDDDC1BFB296700372700 /* libc++.tbd */, | ||
| 280 | + 869DDDDA1BFB295E00372700 /* libsqlite3.0.tbd */, | ||
| 281 | + 869DDDD81BFB294F00372700 /* CoreTelephony.framework */, | ||
| 282 | + 13B07FAE1A68108700A75B9A /* Example */, | ||
| 283 | + 832341AE1AAA6A7D00B99B32 /* Libraries */, | ||
| 284 | + 83CBBA001A601CBA00E9B192 /* Products */, | ||
| 285 | + ); | ||
| 286 | + indentWidth = 2; | ||
| 287 | + sourceTree = "<group>"; | ||
| 288 | + tabWidth = 2; | ||
| 289 | + }; | ||
| 290 | + 83CBBA001A601CBA00E9B192 /* Products */ = { | ||
| 291 | + isa = PBXGroup; | ||
| 292 | + children = ( | ||
| 293 | + 13B07F961A680F5B00A75B9A /* Example.app */, | ||
| 294 | + ); | ||
| 295 | + name = Products; | ||
| 296 | + sourceTree = "<group>"; | ||
| 297 | + }; | ||
| 298 | + 869DDDC81BFB273A00372700 /* Products */ = { | ||
| 299 | + isa = PBXGroup; | ||
| 300 | + children = ( | ||
| 301 | + 869DDDD51BFB273B00372700 /* libRCTWeChat.a */, | ||
| 302 | + ); | ||
| 303 | + name = Products; | ||
| 304 | + sourceTree = "<group>"; | ||
| 305 | + }; | ||
| 306 | +/* End PBXGroup section */ | ||
| 307 | + | ||
| 308 | +/* Begin PBXNativeTarget section */ | ||
| 309 | + 13B07F861A680F5B00A75B9A /* Example */ = { | ||
| 310 | + isa = PBXNativeTarget; | ||
| 311 | + buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Example" */; | ||
| 312 | + buildPhases = ( | ||
| 313 | + 13B07F871A680F5B00A75B9A /* Sources */, | ||
| 314 | + 13B07F8C1A680F5B00A75B9A /* Frameworks */, | ||
| 315 | + 13B07F8E1A680F5B00A75B9A /* Resources */, | ||
| 316 | + 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, | ||
| 317 | + ); | ||
| 318 | + buildRules = ( | ||
| 319 | + ); | ||
| 320 | + dependencies = ( | ||
| 321 | + ); | ||
| 322 | + name = Example; | ||
| 323 | + productName = "Hello World"; | ||
| 324 | + productReference = 13B07F961A680F5B00A75B9A /* Example.app */; | ||
| 325 | + productType = "com.apple.product-type.application"; | ||
| 326 | + }; | ||
| 327 | +/* End PBXNativeTarget section */ | ||
| 328 | + | ||
| 329 | +/* Begin PBXProject section */ | ||
| 330 | + 83CBB9F71A601CBA00E9B192 /* Project object */ = { | ||
| 331 | + isa = PBXProject; | ||
| 332 | + attributes = { | ||
| 333 | + LastUpgradeCheck = 0710; | ||
| 334 | + ORGANIZATIONNAME = Facebook; | ||
| 335 | + TargetAttributes = { | ||
| 336 | + 13B07F861A680F5B00A75B9A = { | ||
| 337 | + DevelopmentTeam = JP4369ZCVM; | ||
| 338 | + }; | ||
| 339 | + }; | ||
| 340 | + }; | ||
| 341 | + buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Example" */; | ||
| 342 | + compatibilityVersion = "Xcode 3.2"; | ||
| 343 | + developmentRegion = English; | ||
| 344 | + hasScannedForEncodings = 0; | ||
| 345 | + knownRegions = ( | ||
| 346 | + en, | ||
| 347 | + Base, | ||
| 348 | + ); | ||
| 349 | + mainGroup = 83CBB9F61A601CBA00E9B192; | ||
| 350 | + productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; | ||
| 351 | + projectDirPath = ""; | ||
| 352 | + projectReferences = ( | ||
| 353 | + { | ||
| 354 | + ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */; | ||
| 355 | + ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; | ||
| 356 | + }, | ||
| 357 | + { | ||
| 358 | + ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */; | ||
| 359 | + ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; | ||
| 360 | + }, | ||
| 361 | + { | ||
| 362 | + ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */; | ||
| 363 | + ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; | ||
| 364 | + }, | ||
| 365 | + { | ||
| 366 | + ProductGroup = 78C398B11ACF4ADC00677621 /* Products */; | ||
| 367 | + ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; | ||
| 368 | + }, | ||
| 369 | + { | ||
| 370 | + ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */; | ||
| 371 | + ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; | ||
| 372 | + }, | ||
| 373 | + { | ||
| 374 | + ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */; | ||
| 375 | + ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; | ||
| 376 | + }, | ||
| 377 | + { | ||
| 378 | + ProductGroup = 832341B11AAA6A8300B99B32 /* Products */; | ||
| 379 | + ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; | ||
| 380 | + }, | ||
| 381 | + { | ||
| 382 | + ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */; | ||
| 383 | + ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; | ||
| 384 | + }, | ||
| 385 | + { | ||
| 386 | + ProductGroup = 139FDEE71B06529A00C62182 /* Products */; | ||
| 387 | + ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; | ||
| 388 | + }, | ||
| 389 | + { | ||
| 390 | + ProductGroup = 869DDDC81BFB273A00372700 /* Products */; | ||
| 391 | + ProjectRef = 869DDDC71BFB273A00372700 /* RCTWeChat.xcodeproj */; | ||
| 392 | + }, | ||
| 393 | + { | ||
| 394 | + ProductGroup = 146834001AC3E56700842450 /* Products */; | ||
| 395 | + ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */; | ||
| 396 | + }, | ||
| 397 | + ); | ||
| 398 | + projectRoot = ""; | ||
| 399 | + targets = ( | ||
| 400 | + 13B07F861A680F5B00A75B9A /* Example */, | ||
| 401 | + ); | ||
| 402 | + }; | ||
| 403 | +/* End PBXProject section */ | ||
| 404 | + | ||
| 405 | +/* Begin PBXReferenceProxy section */ | ||
| 406 | + 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = { | ||
| 407 | + isa = PBXReferenceProxy; | ||
| 408 | + fileType = archive.ar; | ||
| 409 | + path = libRCTActionSheet.a; | ||
| 410 | + remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */; | ||
| 411 | + sourceTree = BUILT_PRODUCTS_DIR; | ||
| 412 | + }; | ||
| 413 | + 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = { | ||
| 414 | + isa = PBXReferenceProxy; | ||
| 415 | + fileType = archive.ar; | ||
| 416 | + path = libRCTGeolocation.a; | ||
| 417 | + remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */; | ||
| 418 | + sourceTree = BUILT_PRODUCTS_DIR; | ||
| 419 | + }; | ||
| 420 | + 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = { | ||
| 421 | + isa = PBXReferenceProxy; | ||
| 422 | + fileType = archive.ar; | ||
| 423 | + path = libRCTImage.a; | ||
| 424 | + remoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */; | ||
| 425 | + sourceTree = BUILT_PRODUCTS_DIR; | ||
| 426 | + }; | ||
| 427 | + 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = { | ||
| 428 | + isa = PBXReferenceProxy; | ||
| 429 | + fileType = archive.ar; | ||
| 430 | + path = libRCTNetwork.a; | ||
| 431 | + remoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */; | ||
| 432 | + sourceTree = BUILT_PRODUCTS_DIR; | ||
| 433 | + }; | ||
| 434 | + 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = { | ||
| 435 | + isa = PBXReferenceProxy; | ||
| 436 | + fileType = archive.ar; | ||
| 437 | + path = libRCTVibration.a; | ||
| 438 | + remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */; | ||
| 439 | + sourceTree = BUILT_PRODUCTS_DIR; | ||
| 440 | + }; | ||
| 441 | + 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = { | ||
| 442 | + isa = PBXReferenceProxy; | ||
| 443 | + fileType = archive.ar; | ||
| 444 | + path = libRCTSettings.a; | ||
| 445 | + remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */; | ||
| 446 | + sourceTree = BUILT_PRODUCTS_DIR; | ||
| 447 | + }; | ||
| 448 | + 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */ = { | ||
| 449 | + isa = PBXReferenceProxy; | ||
| 450 | + fileType = archive.ar; | ||
| 451 | + path = libRCTWebSocket.a; | ||
| 452 | + remoteRef = 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */; | ||
| 453 | + sourceTree = BUILT_PRODUCTS_DIR; | ||
| 454 | + }; | ||
| 455 | + 146834041AC3E56700842450 /* libReact.a */ = { | ||
| 456 | + isa = PBXReferenceProxy; | ||
| 457 | + fileType = archive.ar; | ||
| 458 | + path = libReact.a; | ||
| 459 | + remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */; | ||
| 460 | + sourceTree = BUILT_PRODUCTS_DIR; | ||
| 461 | + }; | ||
| 462 | + 78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = { | ||
| 463 | + isa = PBXReferenceProxy; | ||
| 464 | + fileType = archive.ar; | ||
| 465 | + path = libRCTLinking.a; | ||
| 466 | + remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */; | ||
| 467 | + sourceTree = BUILT_PRODUCTS_DIR; | ||
| 468 | + }; | ||
| 469 | + 832341B51AAA6A8300B99B32 /* libRCTText.a */ = { | ||
| 470 | + isa = PBXReferenceProxy; | ||
| 471 | + fileType = archive.ar; | ||
| 472 | + path = libRCTText.a; | ||
| 473 | + remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */; | ||
| 474 | + sourceTree = BUILT_PRODUCTS_DIR; | ||
| 475 | + }; | ||
| 476 | + 869DDDD51BFB273B00372700 /* libRCTWeChat.a */ = { | ||
| 477 | + isa = PBXReferenceProxy; | ||
| 478 | + fileType = archive.ar; | ||
| 479 | + path = libRCTWeChat.a; | ||
| 480 | + remoteRef = 869DDDD41BFB273B00372700 /* PBXContainerItemProxy */; | ||
| 481 | + sourceTree = BUILT_PRODUCTS_DIR; | ||
| 482 | + }; | ||
| 483 | +/* End PBXReferenceProxy section */ | ||
| 484 | + | ||
| 485 | +/* Begin PBXResourcesBuildPhase section */ | ||
| 486 | + 13B07F8E1A680F5B00A75B9A /* Resources */ = { | ||
| 487 | + isa = PBXResourcesBuildPhase; | ||
| 488 | + buildActionMask = 2147483647; | ||
| 489 | + files = ( | ||
| 490 | + 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, | ||
| 491 | + 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, | ||
| 492 | + ); | ||
| 493 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 494 | + }; | ||
| 495 | +/* End PBXResourcesBuildPhase section */ | ||
| 496 | + | ||
| 497 | +/* Begin PBXShellScriptBuildPhase section */ | ||
| 498 | + 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { | ||
| 499 | + isa = PBXShellScriptBuildPhase; | ||
| 500 | + buildActionMask = 2147483647; | ||
| 501 | + files = ( | ||
| 502 | + ); | ||
| 503 | + inputPaths = ( | ||
| 504 | + ); | ||
| 505 | + name = "Bundle React Native code and images"; | ||
| 506 | + outputPaths = ( | ||
| 507 | + ); | ||
| 508 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 509 | + shellPath = /bin/sh; | ||
| 510 | + shellScript = "../node_modules/react-native/packager/react-native-xcode.sh"; | ||
| 511 | + }; | ||
| 512 | +/* End PBXShellScriptBuildPhase section */ | ||
| 513 | + | ||
| 514 | +/* Begin PBXSourcesBuildPhase section */ | ||
| 515 | + 13B07F871A680F5B00A75B9A /* Sources */ = { | ||
| 516 | + isa = PBXSourcesBuildPhase; | ||
| 517 | + buildActionMask = 2147483647; | ||
| 518 | + files = ( | ||
| 519 | + 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, | ||
| 520 | + 13B07FC11A68108700A75B9A /* main.m in Sources */, | ||
| 521 | + ); | ||
| 522 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 523 | + }; | ||
| 524 | +/* End PBXSourcesBuildPhase section */ | ||
| 525 | + | ||
| 526 | +/* Begin PBXVariantGroup section */ | ||
| 527 | + 13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = { | ||
| 528 | + isa = PBXVariantGroup; | ||
| 529 | + children = ( | ||
| 530 | + 13B07FB21A68108700A75B9A /* Base */, | ||
| 531 | + ); | ||
| 532 | + name = LaunchScreen.xib; | ||
| 533 | + path = Example; | ||
| 534 | + sourceTree = "<group>"; | ||
| 535 | + }; | ||
| 536 | +/* End PBXVariantGroup section */ | ||
| 537 | + | ||
| 538 | +/* Begin XCBuildConfiguration section */ | ||
| 539 | + 13B07F941A680F5B00A75B9A /* Debug */ = { | ||
| 540 | + isa = XCBuildConfiguration; | ||
| 541 | + buildSettings = { | ||
| 542 | + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | ||
| 543 | + CODE_SIGN_IDENTITY = "iPhone Developer"; | ||
| 544 | + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | ||
| 545 | + DEAD_CODE_STRIPPING = NO; | ||
| 546 | + HEADER_SEARCH_PATHS = ( | ||
| 547 | + "$(inherited)", | ||
| 548 | + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, | ||
| 549 | + "$(SRCROOT)/../node_modules/react-native/React/**", | ||
| 550 | + ); | ||
| 551 | + INFOPLIST_FILE = Example/Info.plist; | ||
| 552 | + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; | ||
| 553 | + OTHER_LDFLAGS = "-ObjC"; | ||
| 554 | + PRODUCT_BUNDLE_IDENTIFIER = "com.weflex.wechat-example"; | ||
| 555 | + PRODUCT_NAME = Example; | ||
| 556 | + PROVISIONING_PROFILE = ""; | ||
| 557 | + }; | ||
| 558 | + name = Debug; | ||
| 559 | + }; | ||
| 560 | + 13B07F951A680F5B00A75B9A /* Release */ = { | ||
| 561 | + isa = XCBuildConfiguration; | ||
| 562 | + buildSettings = { | ||
| 563 | + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | ||
| 564 | + CODE_SIGN_IDENTITY = "iPhone Developer"; | ||
| 565 | + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | ||
| 566 | + HEADER_SEARCH_PATHS = ( | ||
| 567 | + "$(inherited)", | ||
| 568 | + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, | ||
| 569 | + "$(SRCROOT)/../node_modules/react-native/React/**", | ||
| 570 | + ); | ||
| 571 | + INFOPLIST_FILE = Example/Info.plist; | ||
| 572 | + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; | ||
| 573 | + OTHER_LDFLAGS = "-ObjC"; | ||
| 574 | + PRODUCT_BUNDLE_IDENTIFIER = "com.weflex.wechat-example"; | ||
| 575 | + PRODUCT_NAME = Example; | ||
| 576 | + PROVISIONING_PROFILE = ""; | ||
| 577 | + }; | ||
| 578 | + name = Release; | ||
| 579 | + }; | ||
| 580 | + 83CBBA201A601CBA00E9B192 /* Debug */ = { | ||
| 581 | + isa = XCBuildConfiguration; | ||
| 582 | + buildSettings = { | ||
| 583 | + ALWAYS_SEARCH_USER_PATHS = NO; | ||
| 584 | + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; | ||
| 585 | + CLANG_CXX_LIBRARY = "libc++"; | ||
| 586 | + CLANG_ENABLE_MODULES = YES; | ||
| 587 | + CLANG_ENABLE_OBJC_ARC = YES; | ||
| 588 | + CLANG_WARN_BOOL_CONVERSION = YES; | ||
| 589 | + CLANG_WARN_CONSTANT_CONVERSION = YES; | ||
| 590 | + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | ||
| 591 | + CLANG_WARN_EMPTY_BODY = YES; | ||
| 592 | + CLANG_WARN_ENUM_CONVERSION = YES; | ||
| 593 | + CLANG_WARN_INT_CONVERSION = YES; | ||
| 594 | + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | ||
| 595 | + CLANG_WARN_UNREACHABLE_CODE = YES; | ||
| 596 | + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | ||
| 597 | + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | ||
| 598 | + COPY_PHASE_STRIP = NO; | ||
| 599 | + ENABLE_STRICT_OBJC_MSGSEND = YES; | ||
| 600 | + ENABLE_TESTABILITY = YES; | ||
| 601 | + GCC_C_LANGUAGE_STANDARD = gnu99; | ||
| 602 | + GCC_DYNAMIC_NO_PIC = NO; | ||
| 603 | + GCC_OPTIMIZATION_LEVEL = 0; | ||
| 604 | + GCC_PREPROCESSOR_DEFINITIONS = ( | ||
| 605 | + "DEBUG=1", | ||
| 606 | + "$(inherited)", | ||
| 607 | + ); | ||
| 608 | + GCC_SYMBOLS_PRIVATE_EXTERN = NO; | ||
| 609 | + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | ||
| 610 | + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | ||
| 611 | + GCC_WARN_UNDECLARED_SELECTOR = YES; | ||
| 612 | + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | ||
| 613 | + GCC_WARN_UNUSED_FUNCTION = YES; | ||
| 614 | + GCC_WARN_UNUSED_VARIABLE = YES; | ||
| 615 | + HEADER_SEARCH_PATHS = ( | ||
| 616 | + "$(inherited)", | ||
| 617 | + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, | ||
| 618 | + "$(SRCROOT)/../node_modules/react-native/React/**", | ||
| 619 | + ); | ||
| 620 | + IPHONEOS_DEPLOYMENT_TARGET = 9.1; | ||
| 621 | + MTL_ENABLE_DEBUG_INFO = YES; | ||
| 622 | + ONLY_ACTIVE_ARCH = YES; | ||
| 623 | + SDKROOT = iphoneos; | ||
| 624 | + }; | ||
| 625 | + name = Debug; | ||
| 626 | + }; | ||
| 627 | + 83CBBA211A601CBA00E9B192 /* Release */ = { | ||
| 628 | + isa = XCBuildConfiguration; | ||
| 629 | + buildSettings = { | ||
| 630 | + ALWAYS_SEARCH_USER_PATHS = NO; | ||
| 631 | + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; | ||
| 632 | + CLANG_CXX_LIBRARY = "libc++"; | ||
| 633 | + CLANG_ENABLE_MODULES = YES; | ||
| 634 | + CLANG_ENABLE_OBJC_ARC = YES; | ||
| 635 | + CLANG_WARN_BOOL_CONVERSION = YES; | ||
| 636 | + CLANG_WARN_CONSTANT_CONVERSION = YES; | ||
| 637 | + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | ||
| 638 | + CLANG_WARN_EMPTY_BODY = YES; | ||
| 639 | + CLANG_WARN_ENUM_CONVERSION = YES; | ||
| 640 | + CLANG_WARN_INT_CONVERSION = YES; | ||
| 641 | + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | ||
| 642 | + CLANG_WARN_UNREACHABLE_CODE = YES; | ||
| 643 | + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | ||
| 644 | + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | ||
| 645 | + COPY_PHASE_STRIP = YES; | ||
| 646 | + ENABLE_NS_ASSERTIONS = NO; | ||
| 647 | + ENABLE_STRICT_OBJC_MSGSEND = YES; | ||
| 648 | + GCC_C_LANGUAGE_STANDARD = gnu99; | ||
| 649 | + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | ||
| 650 | + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | ||
| 651 | + GCC_WARN_UNDECLARED_SELECTOR = YES; | ||
| 652 | + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | ||
| 653 | + GCC_WARN_UNUSED_FUNCTION = YES; | ||
| 654 | + GCC_WARN_UNUSED_VARIABLE = YES; | ||
| 655 | + HEADER_SEARCH_PATHS = ( | ||
| 656 | + "$(inherited)", | ||
| 657 | + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, | ||
| 658 | + "$(SRCROOT)/../node_modules/react-native/React/**", | ||
| 659 | + ); | ||
| 660 | + IPHONEOS_DEPLOYMENT_TARGET = 9.1; | ||
| 661 | + MTL_ENABLE_DEBUG_INFO = NO; | ||
| 662 | + SDKROOT = iphoneos; | ||
| 663 | + VALIDATE_PRODUCT = YES; | ||
| 664 | + }; | ||
| 665 | + name = Release; | ||
| 666 | + }; | ||
| 667 | +/* End XCBuildConfiguration section */ | ||
| 668 | + | ||
| 669 | +/* Begin XCConfigurationList section */ | ||
| 670 | + 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Example" */ = { | ||
| 671 | + isa = XCConfigurationList; | ||
| 672 | + buildConfigurations = ( | ||
| 673 | + 13B07F941A680F5B00A75B9A /* Debug */, | ||
| 674 | + 13B07F951A680F5B00A75B9A /* Release */, | ||
| 675 | + ); | ||
| 676 | + defaultConfigurationIsVisible = 0; | ||
| 677 | + defaultConfigurationName = Release; | ||
| 678 | + }; | ||
| 679 | + 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Example" */ = { | ||
| 680 | + isa = XCConfigurationList; | ||
| 681 | + buildConfigurations = ( | ||
| 682 | + 83CBBA201A601CBA00E9B192 /* Debug */, | ||
| 683 | + 83CBBA211A601CBA00E9B192 /* Release */, | ||
| 684 | + ); | ||
| 685 | + defaultConfigurationIsVisible = 0; | ||
| 686 | + defaultConfigurationName = Release; | ||
| 687 | + }; | ||
| 688 | +/* End XCConfigurationList section */ | ||
| 689 | + }; | ||
| 690 | + rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; | ||
| 691 | +} |
不能预览此文件类型
不能预览此文件类型
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<Scheme | ||
| 3 | + LastUpgradeVersion = "0710" | ||
| 4 | + version = "1.3"> | ||
| 5 | + <BuildAction | ||
| 6 | + parallelizeBuildables = "YES" | ||
| 7 | + buildImplicitDependencies = "YES"> | ||
| 8 | + <BuildActionEntries> | ||
| 9 | + <BuildActionEntry | ||
| 10 | + buildForTesting = "YES" | ||
| 11 | + buildForRunning = "YES" | ||
| 12 | + buildForProfiling = "YES" | ||
| 13 | + buildForArchiving = "YES" | ||
| 14 | + buildForAnalyzing = "YES"> | ||
| 15 | + <BuildableReference | ||
| 16 | + BuildableIdentifier = "primary" | ||
| 17 | + BlueprintIdentifier = "13B07F861A680F5B00A75B9A" | ||
| 18 | + BuildableName = "Example.app" | ||
| 19 | + BlueprintName = "Example" | ||
| 20 | + ReferencedContainer = "container:Example.xcodeproj"> | ||
| 21 | + </BuildableReference> | ||
| 22 | + </BuildActionEntry> | ||
| 23 | + <BuildActionEntry | ||
| 24 | + buildForTesting = "YES" | ||
| 25 | + buildForRunning = "YES" | ||
| 26 | + buildForProfiling = "NO" | ||
| 27 | + buildForArchiving = "NO" | ||
| 28 | + buildForAnalyzing = "YES"> | ||
| 29 | + <BuildableReference | ||
| 30 | + BuildableIdentifier = "primary" | ||
| 31 | + BlueprintIdentifier = "00E356ED1AD99517003FC87E" | ||
| 32 | + BuildableName = "ExampleTests.xctest" | ||
| 33 | + BlueprintName = "ExampleTests" | ||
| 34 | + ReferencedContainer = "container:Example.xcodeproj"> | ||
| 35 | + </BuildableReference> | ||
| 36 | + </BuildActionEntry> | ||
| 37 | + </BuildActionEntries> | ||
| 38 | + </BuildAction> | ||
| 39 | + <TestAction | ||
| 40 | + buildConfiguration = "Debug" | ||
| 41 | + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
| 42 | + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
| 43 | + shouldUseLaunchSchemeArgsEnv = "YES"> | ||
| 44 | + <Testables> | ||
| 45 | + <TestableReference | ||
| 46 | + skipped = "NO"> | ||
| 47 | + <BuildableReference | ||
| 48 | + BuildableIdentifier = "primary" | ||
| 49 | + BlueprintIdentifier = "00E356ED1AD99517003FC87E" | ||
| 50 | + BuildableName = "ExampleTests.xctest" | ||
| 51 | + BlueprintName = "ExampleTests" | ||
| 52 | + ReferencedContainer = "container:Example.xcodeproj"> | ||
| 53 | + </BuildableReference> | ||
| 54 | + </TestableReference> | ||
| 55 | + </Testables> | ||
| 56 | + <MacroExpansion> | ||
| 57 | + <BuildableReference | ||
| 58 | + BuildableIdentifier = "primary" | ||
| 59 | + BlueprintIdentifier = "13B07F861A680F5B00A75B9A" | ||
| 60 | + BuildableName = "Example.app" | ||
| 61 | + BlueprintName = "Example" | ||
| 62 | + ReferencedContainer = "container:Example.xcodeproj"> | ||
| 63 | + </BuildableReference> | ||
| 64 | + </MacroExpansion> | ||
| 65 | + <AdditionalOptions> | ||
| 66 | + </AdditionalOptions> | ||
| 67 | + </TestAction> | ||
| 68 | + <LaunchAction | ||
| 69 | + buildConfiguration = "Debug" | ||
| 70 | + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
| 71 | + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
| 72 | + launchStyle = "0" | ||
| 73 | + useCustomWorkingDirectory = "NO" | ||
| 74 | + ignoresPersistentStateOnLaunch = "NO" | ||
| 75 | + debugDocumentVersioning = "YES" | ||
| 76 | + debugServiceExtension = "internal" | ||
| 77 | + allowLocationSimulation = "YES"> | ||
| 78 | + <BuildableProductRunnable | ||
| 79 | + runnableDebuggingMode = "0"> | ||
| 80 | + <BuildableReference | ||
| 81 | + BuildableIdentifier = "primary" | ||
| 82 | + BlueprintIdentifier = "13B07F861A680F5B00A75B9A" | ||
| 83 | + BuildableName = "Example.app" | ||
| 84 | + BlueprintName = "Example" | ||
| 85 | + ReferencedContainer = "container:Example.xcodeproj"> | ||
| 86 | + </BuildableReference> | ||
| 87 | + </BuildableProductRunnable> | ||
| 88 | + <AdditionalOptions> | ||
| 89 | + </AdditionalOptions> | ||
| 90 | + </LaunchAction> | ||
| 91 | + <ProfileAction | ||
| 92 | + buildConfiguration = "Release" | ||
| 93 | + shouldUseLaunchSchemeArgsEnv = "YES" | ||
| 94 | + savedToolIdentifier = "" | ||
| 95 | + useCustomWorkingDirectory = "NO" | ||
| 96 | + debugDocumentVersioning = "YES"> | ||
| 97 | + <BuildableProductRunnable | ||
| 98 | + runnableDebuggingMode = "0"> | ||
| 99 | + <BuildableReference | ||
| 100 | + BuildableIdentifier = "primary" | ||
| 101 | + BlueprintIdentifier = "13B07F861A680F5B00A75B9A" | ||
| 102 | + BuildableName = "Example.app" | ||
| 103 | + BlueprintName = "Example" | ||
| 104 | + ReferencedContainer = "container:Example.xcodeproj"> | ||
| 105 | + </BuildableReference> | ||
| 106 | + </BuildableProductRunnable> | ||
| 107 | + </ProfileAction> | ||
| 108 | + <AnalyzeAction | ||
| 109 | + buildConfiguration = "Debug"> | ||
| 110 | + </AnalyzeAction> | ||
| 111 | + <ArchiveAction | ||
| 112 | + buildConfiguration = "Release" | ||
| 113 | + revealArchiveInOrganizer = "YES"> | ||
| 114 | + </ArchiveAction> | ||
| 115 | +</Scheme> |
Example/ios/Example.xcodeproj/xcuserdata/yorkie.xcuserdatad/xcschemes/xcschememanagement.plist
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
| 3 | +<plist version="1.0"> | ||
| 4 | +<dict> | ||
| 5 | + <key>SuppressBuildableAutocreation</key> | ||
| 6 | + <dict> | ||
| 7 | + <key>13B07F861A680F5B00A75B9A</key> | ||
| 8 | + <dict> | ||
| 9 | + <key>primary</key> | ||
| 10 | + <true/> | ||
| 11 | + </dict> | ||
| 12 | + </dict> | ||
| 13 | +</dict> | ||
| 14 | +</plist> |
Example/ios/Example.xcodeproj/xcuserdata/yorkieliu.xcuserdatad/xcschemes/xcschememanagement.plist
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
| 3 | +<plist version="1.0"> | ||
| 4 | +<dict> | ||
| 5 | + <key>SchemeUserState</key> | ||
| 6 | + <dict> | ||
| 7 | + <key>Example.xcscheme_^#shared#^_</key> | ||
| 8 | + <dict> | ||
| 9 | + <key>orderHint</key> | ||
| 10 | + <integer>0</integer> | ||
| 11 | + </dict> | ||
| 12 | + </dict> | ||
| 13 | + <key>SuppressBuildableAutocreation</key> | ||
| 14 | + <dict> | ||
| 15 | + <key>00E356ED1AD99517003FC87E</key> | ||
| 16 | + <dict> | ||
| 17 | + <key>primary</key> | ||
| 18 | + <true/> | ||
| 19 | + </dict> | ||
| 20 | + <key>13B07F861A680F5B00A75B9A</key> | ||
| 21 | + <dict> | ||
| 22 | + <key>primary</key> | ||
| 23 | + <true/> | ||
| 24 | + </dict> | ||
| 25 | + </dict> | ||
| 26 | +</dict> | ||
| 27 | +</plist> |
Example/ios/Example/AppDelegate.h
0 → 100644
| 1 | +/** | ||
| 2 | + * Copyright (c) 2015-present, Facebook, Inc. | ||
| 3 | + * All rights reserved. | ||
| 4 | + * | ||
| 5 | + * This source code is licensed under the BSD-style license found in the | ||
| 6 | + * LICENSE file in the root directory of this source tree. An additional grant | ||
| 7 | + * of patent rights can be found in the PATENTS file in the same directory. | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +#import <UIKit/UIKit.h> | ||
| 11 | + | ||
| 12 | +@interface AppDelegate : UIResponder <UIApplicationDelegate> | ||
| 13 | + | ||
| 14 | +@property (nonatomic, strong) UIWindow *window; | ||
| 15 | + | ||
| 16 | +@end |
Example/ios/Example/AppDelegate.m
0 → 100644
| 1 | +/** | ||
| 2 | + * Copyright (c) 2015-present, Facebook, Inc. | ||
| 3 | + * All rights reserved. | ||
| 4 | + * | ||
| 5 | + * This source code is licensed under the BSD-style license found in the | ||
| 6 | + * LICENSE file in the root directory of this source tree. An additional grant | ||
| 7 | + * of patent rights can be found in the PATENTS file in the same directory. | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +#import "AppDelegate.h" | ||
| 11 | + | ||
| 12 | +#import "RCTRootView.h" | ||
| 13 | + | ||
| 14 | +@implementation AppDelegate | ||
| 15 | + | ||
| 16 | +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions | ||
| 17 | +{ | ||
| 18 | + NSURL *jsCodeLocation; | ||
| 19 | + | ||
| 20 | + /** | ||
| 21 | + * Loading JavaScript code - uncomment the one you want. | ||
| 22 | + * | ||
| 23 | + * OPTION 1 | ||
| 24 | + * Load from development server. Start the server from the repository root: | ||
| 25 | + * | ||
| 26 | + * $ npm start | ||
| 27 | + * | ||
| 28 | + * To run on device, change `localhost` to the IP address of your computer | ||
| 29 | + * (you can get this by typing `ifconfig` into the terminal and selecting the | ||
| 30 | + * `inet` value under `en0:`) and make sure your computer and iOS device are | ||
| 31 | + * on the same Wi-Fi network. | ||
| 32 | + */ | ||
| 33 | + | ||
| 34 | + jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"]; | ||
| 35 | + | ||
| 36 | + /** | ||
| 37 | + * OPTION 2 | ||
| 38 | + * Load from pre-bundled file on disk. The static bundle is automatically | ||
| 39 | + * generated by "Bundle React Native code and images" build step. | ||
| 40 | + */ | ||
| 41 | + | ||
| 42 | +// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; | ||
| 43 | + | ||
| 44 | + RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation | ||
| 45 | + moduleName:@"Example" | ||
| 46 | + initialProperties:nil | ||
| 47 | + launchOptions:launchOptions]; | ||
| 48 | + | ||
| 49 | + self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; | ||
| 50 | + UIViewController *rootViewController = [[UIViewController alloc] init]; | ||
| 51 | + rootViewController.view = rootView; | ||
| 52 | + self.window.rootViewController = rootViewController; | ||
| 53 | + [self.window makeKeyAndVisible]; | ||
| 54 | + return YES; | ||
| 55 | +} | ||
| 56 | + | ||
| 57 | +@end |
| 1 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||
| 2 | +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9059" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES"> | ||
| 3 | + <dependencies> | ||
| 4 | + <deployment identifier="iOS"/> | ||
| 5 | + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9049"/> | ||
| 6 | + <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/> | ||
| 7 | + </dependencies> | ||
| 8 | + <objects> | ||
| 9 | + <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/> | ||
| 10 | + <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> | ||
| 11 | + <view contentMode="scaleToFill" id="iN0-l3-epB"> | ||
| 12 | + <rect key="frame" x="0.0" y="0.0" width="480" height="480"/> | ||
| 13 | + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||
| 14 | + <subviews> | ||
| 15 | + <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Powered by React Native" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye"> | ||
| 16 | + <rect key="frame" x="20" y="439" width="441" height="21"/> | ||
| 17 | + <animations/> | ||
| 18 | + <fontDescription key="fontDescription" type="system" pointSize="17"/> | ||
| 19 | + <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> | ||
| 20 | + <nil key="highlightedColor"/> | ||
| 21 | + </label> | ||
| 22 | + <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Example" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX"> | ||
| 23 | + <rect key="frame" x="20" y="140" width="441" height="43"/> | ||
| 24 | + <animations/> | ||
| 25 | + <fontDescription key="fontDescription" type="boldSystem" pointSize="36"/> | ||
| 26 | + <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> | ||
| 27 | + <nil key="highlightedColor"/> | ||
| 28 | + </label> | ||
| 29 | + </subviews> | ||
| 30 | + <animations/> | ||
| 31 | + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> | ||
| 32 | + <constraints> | ||
| 33 | + <constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/> | ||
| 34 | + <constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/> | ||
| 35 | + <constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/> | ||
| 36 | + <constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/> | ||
| 37 | + <constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/> | ||
| 38 | + <constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/> | ||
| 39 | + </constraints> | ||
| 40 | + <nil key="simulatedStatusBarMetrics"/> | ||
| 41 | + <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> | ||
| 42 | + <point key="canvasLocation" x="548" y="455"/> | ||
| 43 | + </view> | ||
| 44 | + </objects> | ||
| 45 | +</document> |
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "iphone", | ||
| 5 | + "size" : "29x29", | ||
| 6 | + "scale" : "2x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "iphone", | ||
| 10 | + "size" : "29x29", | ||
| 11 | + "scale" : "3x" | ||
| 12 | + }, | ||
| 13 | + { | ||
| 14 | + "idiom" : "iphone", | ||
| 15 | + "size" : "40x40", | ||
| 16 | + "scale" : "2x" | ||
| 17 | + }, | ||
| 18 | + { | ||
| 19 | + "idiom" : "iphone", | ||
| 20 | + "size" : "40x40", | ||
| 21 | + "scale" : "3x" | ||
| 22 | + }, | ||
| 23 | + { | ||
| 24 | + "idiom" : "iphone", | ||
| 25 | + "size" : "60x60", | ||
| 26 | + "scale" : "2x" | ||
| 27 | + }, | ||
| 28 | + { | ||
| 29 | + "idiom" : "iphone", | ||
| 30 | + "size" : "60x60", | ||
| 31 | + "scale" : "3x" | ||
| 32 | + } | ||
| 33 | + ], | ||
| 34 | + "info" : { | ||
| 35 | + "version" : 1, | ||
| 36 | + "author" : "xcode" | ||
| 37 | + } | ||
| 38 | +} |
Example/ios/Example/Info.plist
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
| 3 | +<plist version="1.0"> | ||
| 4 | +<dict> | ||
| 5 | + <key>CFBundleDevelopmentRegion</key> | ||
| 6 | + <string>en</string> | ||
| 7 | + <key>CFBundleExecutable</key> | ||
| 8 | + <string>$(EXECUTABLE_NAME)</string> | ||
| 9 | + <key>CFBundleIdentifier</key> | ||
| 10 | + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | ||
| 11 | + <key>CFBundleInfoDictionaryVersion</key> | ||
| 12 | + <string>6.0</string> | ||
| 13 | + <key>CFBundleName</key> | ||
| 14 | + <string>$(PRODUCT_NAME)</string> | ||
| 15 | + <key>CFBundlePackageType</key> | ||
| 16 | + <string>APPL</string> | ||
| 17 | + <key>CFBundleShortVersionString</key> | ||
| 18 | + <string>1.0</string> | ||
| 19 | + <key>CFBundleSignature</key> | ||
| 20 | + <string>????</string> | ||
| 21 | + <key>CFBundleVersion</key> | ||
| 22 | + <string>1</string> | ||
| 23 | + <key>LSRequiresIPhoneOS</key> | ||
| 24 | + <true/> | ||
| 25 | + <key>NSAppTransportSecurity</key> | ||
| 26 | + <dict> | ||
| 27 | + <key>NSAllowsArbitraryLoads</key> | ||
| 28 | + <true/> | ||
| 29 | + </dict> | ||
| 30 | + <key>NSLocationWhenInUseUsageDescription</key> | ||
| 31 | + <string></string> | ||
| 32 | + <key>UILaunchStoryboardName</key> | ||
| 33 | + <string>LaunchScreen</string> | ||
| 34 | + <key>UIRequiredDeviceCapabilities</key> | ||
| 35 | + <array> | ||
| 36 | + <string>armv7</string> | ||
| 37 | + </array> | ||
| 38 | + <key>UISupportedInterfaceOrientations</key> | ||
| 39 | + <array> | ||
| 40 | + <string>UIInterfaceOrientationPortrait</string> | ||
| 41 | + <string>UIInterfaceOrientationLandscapeLeft</string> | ||
| 42 | + <string>UIInterfaceOrientationLandscapeRight</string> | ||
| 43 | + </array> | ||
| 44 | + <key>UIViewControllerBasedStatusBarAppearance</key> | ||
| 45 | + <false/> | ||
| 46 | +</dict> | ||
| 47 | +</plist> |
Example/ios/Example/main.m
0 → 100644
| 1 | +/** | ||
| 2 | + * Copyright (c) 2015-present, Facebook, Inc. | ||
| 3 | + * All rights reserved. | ||
| 4 | + * | ||
| 5 | + * This source code is licensed under the BSD-style license found in the | ||
| 6 | + * LICENSE file in the root directory of this source tree. An additional grant | ||
| 7 | + * of patent rights can be found in the PATENTS file in the same directory. | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +#import <UIKit/UIKit.h> | ||
| 11 | + | ||
| 12 | +#import "AppDelegate.h" | ||
| 13 | + | ||
| 14 | +int main(int argc, char * argv[]) { | ||
| 15 | + @autoreleasepool { | ||
| 16 | + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); | ||
| 17 | + } | ||
| 18 | +} |
Example/package.json
0 → 100644
| 1 | +{ | ||
| 2 | + "name": "Example", | ||
| 3 | + "version": "0.0.1", | ||
| 4 | + "private": true, | ||
| 5 | + "scripts": { | ||
| 6 | + "start": "node_modules/react-native/packager/packager.sh", | ||
| 7 | + "postinstall": "ln -sf ../index.js ./react-native-wechat.js" | ||
| 8 | + }, | ||
| 9 | + "dependencies": { | ||
| 10 | + "es6-promisify": "^3.0.0", | ||
| 11 | + "react-native": "^0.14.2", | ||
| 12 | + "events": "1.0.2" | ||
| 13 | + } | ||
| 14 | +} |
Example/react-native-wechat.js
0 → 120000
| 1 | +../index.js |
LICENSE
0 → 100644
| 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. |
README.md
0 → 100644
| 1 | +<img height="200" src="./weixin.png?raw=true"> | ||
| 2 | + | ||
| 3 | +# React-Native-Wechat | ||
| 4 | + | ||
| 5 | +[React Native] bridging library that integrates WeChat SDKs: | ||
| 6 | + | ||
| 7 | +- [x] iOS SDK 1.8.2 | ||
| 8 | +- [x] Android SDK ++ | ||
| 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() (iOS平台) | ||
| 63 | + | ||
| 64 | +- returns {Boolean} Contains the result. | ||
| 65 | + | ||
| 66 | +Check if wechat support open url. | ||
| 67 | +#### isWXAppSupportApi(supportSdk) (Android平台) | ||
| 68 | +```java | ||
| 69 | + //传入对应的字符串判断是否支持,没有找到微信文档,字面意思自己理解 | ||
| 70 | + public static final int SDK_INT = 620824064; | ||
| 71 | + public static final int MIN_SDK_INT = 553713665; | ||
| 72 | + public static final int CHECK_TOKEN_SDK_INT = 620824064; | ||
| 73 | + public static final int TIMELINE_SUPPORTED_SDK_INT = 553779201; | ||
| 74 | + public static final int EMOJI_SUPPORTED_SDK_INT = 553844737; | ||
| 75 | + public static final int MUSIC_DATA_URL_SUPPORTED_SDK_INT = 553910273; | ||
| 76 | + public static final int PAY_SUPPORTED_SDK_INT = 570425345; | ||
| 77 | + public static final int OPENID_SUPPORTED_SDK_INT = 570425345; | ||
| 78 | + public static final int FAVORITE_SUPPPORTED_SDK_INT = 570425345; | ||
| 79 | + public static final int MESSAGE_ACTION_SUPPPORTED_SDK_INT = 570490883; | ||
| 80 | + public static final int SCAN_QRCODE_AUTH_SUPPORTED_SDK_INT = 587268097; | ||
| 81 | + public static final int MINIPROGRAM_SUPPORTED_SDK_INT = 620756993; | ||
| 82 | + public static final int VIDEO_FILE_SUPPORTED_SDK_INT = 620756996; | ||
| 83 | + public static final int SUBSCRIBE_MESSAGE_SUPPORTED_SDK_INT = 620756998; | ||
| 84 | + public static final int LAUNCH_MINIPROGRAM_SUPPORTED_SDK_INT = 620757000; | ||
| 85 | + public static final int CHOOSE_INVOICE_TILE_SUPPORT_SDK_INT = 620822528; | ||
| 86 | + public static final int INVOICE_AUTH_INSERT_SDK_INT = 620823552; | ||
| 87 | + public static final int NON_TAX_PAY_SDK_INT = 620823552; | ||
| 88 | + public static final int PAY_INSURANCE_SDK_INT = 620823552; | ||
| 89 | + public static final int SUBSCRIBE_MINI_PROGRAM_MSG_SUPPORTED_SDK_INT = 620823808; | ||
| 90 | + public static final int OFFLINE_PAY_SDK_INT = 620823808; | ||
| 91 | + public static final int SEND_TO_SPECIFIED_CONTACT_SDK_INT = 620824064; | ||
| 92 | + public static final int OPEN_BUSINESS_WEBVIEW_SDK_INT = 620824064; | ||
| 93 | +``` | ||
| 94 | +- returns {Boolean} Contain the result. | ||
| 95 | + | ||
| 96 | +Check if wechat support open url. | ||
| 97 | + | ||
| 98 | +#### getApiVersion() | ||
| 99 | + | ||
| 100 | +- returns {String} Contains the result. | ||
| 101 | + | ||
| 102 | +Get the WeChat SDK api version. | ||
| 103 | + | ||
| 104 | +#### openWXApp() | ||
| 105 | + | ||
| 106 | +- returns {Boolean} | ||
| 107 | + | ||
| 108 | +Open the WeChat app from your application. | ||
| 109 | + | ||
| 110 | +#### sendAuthRequest([scope[, state]]) | ||
| 111 | + | ||
| 112 | +- `scope` {Array|String} Scopes of auth request. | ||
| 113 | +- `state` {String} the state of OAuth2 | ||
| 114 | +- returns {Object} | ||
| 115 | + | ||
| 116 | +Send authentication request, and it returns an object with the | ||
| 117 | +following fields: | ||
| 118 | + | ||
| 119 | +| field | type | description | | ||
| 120 | +| ------- | ------ | ----------------------------------- | | ||
| 121 | +| errCode | Number | Error Code | | ||
| 122 | +| errStr | String | Error message if any error occurred | | ||
| 123 | +| openId | String | | | ||
| 124 | +| code | String | Authorization code | | ||
| 125 | +| url | String | The URL string | | ||
| 126 | +| lang | String | The user language | | ||
| 127 | +| country | String | The user country | | ||
| 128 | + | ||
| 129 | +#### class `ShareMetadata` | ||
| 130 | + | ||
| 131 | +- `type` {Number} type of this message. Can be {news|text|imageUrl|imageFile|imageResource|video|audio|file} | ||
| 132 | +- `thumbImage` {String} Thumb image of the message, which can be a uri or a resource id. | ||
| 133 | +- `description` {String} The description about the sharing. | ||
| 134 | +- `webpageUrl` {String} Required if type equals `news`. The webpage link to share. | ||
| 135 | +- `imageUrl` {String} Provide a remote image if type equals `image`. | ||
| 136 | +- `videoUrl` {String} Provide a remote video if type equals `video`. | ||
| 137 | +- `musicUrl` {String} Provide a remote music if type equals `audio`. | ||
| 138 | +- `filePath` {String} Provide a local file if type equals `file`. | ||
| 139 | +- `fileExtension` {String} Provide the file type if type equals `file`. | ||
| 140 | + | ||
| 141 | +#### shareToTimeline(message) | ||
| 142 | + | ||
| 143 | +- `message` {ShareMetadata} This object saves the metadata for sharing | ||
| 144 | +- returns {Object} | ||
| 145 | + | ||
| 146 | +Share a `ShareMetadata` message to timeline(朋友圈) and returns: | ||
| 147 | + | ||
| 148 | +| name | type | description | | ||
| 149 | +| ------- | ------ | ----------------------------------- | | ||
| 150 | +| errCode | Number | 0 if authorization successed | | ||
| 151 | +| errStr | String | Error message if any error occurred | | ||
| 152 | + | ||
| 153 | +The following examples require the 'react-native-chat' and 'react-native-fs' packages. | ||
| 154 | + | ||
| 155 | +```js | ||
| 156 | +import * as WeChat from 'react-native-wechat'; | ||
| 157 | +import fs from 'react-native-fs'; | ||
| 158 | +let resolveAssetSource = require('resolveAssetSource'); | ||
| 159 | + | ||
| 160 | +// Code example to share text message: | ||
| 161 | +try { | ||
| 162 | + let result = await WeChat.shareToTimeline({ | ||
| 163 | + type: 'text', | ||
| 164 | + description: 'hello, wechat' | ||
| 165 | + }); | ||
| 166 | + console.log('share text message to time line successful:', result); | ||
| 167 | +} catch (e) { | ||
| 168 | + if (e instanceof WeChat.WechatError) { | ||
| 169 | + console.error(e.stack); | ||
| 170 | + } else { | ||
| 171 | + throw e; | ||
| 172 | + } | ||
| 173 | +} | ||
| 174 | + | ||
| 175 | +// Code example to share image url: | ||
| 176 | +// Share raw http(s) image from web will always fail with unknown reason, please use image file or image resource instead | ||
| 177 | +try { | ||
| 178 | + let result = await WeChat.shareToTimeline({ | ||
| 179 | + type: 'imageUrl', | ||
| 180 | + title: 'web image', | ||
| 181 | + description: 'share web image to time line', | ||
| 182 | + mediaTagName: 'email signature', | ||
| 183 | + messageAction: undefined, | ||
| 184 | + messageExt: undefined, | ||
| 185 | + imageUrl: 'http://www.ncloud.hk/email-signature-262x100.png' | ||
| 186 | + }); | ||
| 187 | + console.log('share image url to time line successful:', result); | ||
| 188 | +} catch (e) { | ||
| 189 | + if (e instanceof WeChat.WechatError) { | ||
| 190 | + console.error(e.stack); | ||
| 191 | + } else { | ||
| 192 | + throw e; | ||
| 193 | + } | ||
| 194 | +} | ||
| 195 | + | ||
| 196 | +// Code example to share image file: | ||
| 197 | +try { | ||
| 198 | + let rootPath = fs.DocumentDirectoryPath; | ||
| 199 | + let savePath = rootPath + '/email-signature-262x100.png'; | ||
| 200 | + console.log(savePath); | ||
| 201 | + | ||
| 202 | + /* | ||
| 203 | + * savePath on iOS may be: | ||
| 204 | + * /var/mobile/Containers/Data/Application/B1308E13-35F1-41AB-A20D-3117BE8EE8FE/Documents/email-signature-262x100.png | ||
| 205 | + * | ||
| 206 | + * savePath on Android may be: | ||
| 207 | + * /data/data/com.wechatsample/files/email-signature-262x100.png | ||
| 208 | + **/ | ||
| 209 | + await fs.downloadFile('http://www.ncloud.hk/email-signature-262x100.png', savePath); | ||
| 210 | + let result = await WeChat.shareToTimeline({ | ||
| 211 | + type: 'imageFile', | ||
| 212 | + title: 'image file download from network', | ||
| 213 | + description: 'share image file to time line', | ||
| 214 | + mediaTagName: 'email signature', | ||
| 215 | + messageAction: undefined, | ||
| 216 | + messageExt: undefined, | ||
| 217 | + imageUrl: "file://" + savePath // require the prefix on both iOS and Android platform | ||
| 218 | + }); | ||
| 219 | + console.log('share image file to time line successful:', result); | ||
| 220 | +} catch (e) { | ||
| 221 | + if (e instanceof WeChat.WechatError) { | ||
| 222 | + console.error(e.stack); | ||
| 223 | + } else { | ||
| 224 | + throw e; | ||
| 225 | + } | ||
| 226 | +} | ||
| 227 | + | ||
| 228 | +// Code example to share image resource: | ||
| 229 | +try { | ||
| 230 | + let imageResource = require('./email-signature-262x100.png'); | ||
| 231 | + let result = await WeChat.shareToTimeline({ | ||
| 232 | + type: 'imageResource', | ||
| 233 | + title: 'resource image', | ||
| 234 | + description: 'share resource image to time line', | ||
| 235 | + mediaTagName: 'email signature', | ||
| 236 | + messageAction: undefined, | ||
| 237 | + messageExt: undefined, | ||
| 238 | + imageUrl: resolveAssetSource(imageResource).uri | ||
| 239 | + }); | ||
| 240 | + console.log('share resource image to time line successful', result); | ||
| 241 | +} | ||
| 242 | +catch (e) { | ||
| 243 | + if (e instanceof WeChat.WechatError) { | ||
| 244 | + console.error(e.stack); | ||
| 245 | + } else { | ||
| 246 | + throw e; | ||
| 247 | + } | ||
| 248 | +} | ||
| 249 | + | ||
| 250 | +// Code example to download an word file from web, then share it to WeChat session | ||
| 251 | +// only support to share to session but time line | ||
| 252 | +// iOS code use DocumentDirectoryPath | ||
| 253 | +try { | ||
| 254 | + let rootPath = fs.DocumentDirectoryPath; | ||
| 255 | + let fileName = 'signature_method.doc'; | ||
| 256 | + /* | ||
| 257 | + * savePath on iOS may be: | ||
| 258 | + * /var/mobile/Containers/Data/Application/B1308E13-35F1-41AB-A20D-3117BE8EE8FE/Documents/signature_method.doc | ||
| 259 | + **/ | ||
| 260 | + let savePath = rootPath + '/' + fileName; | ||
| 261 | + | ||
| 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 | +} catch (e) { | ||
| 275 | + if (e instanceof WeChat.WechatError) { | ||
| 276 | + console.error(e.stack); | ||
| 277 | + } else { | ||
| 278 | + throw e; | ||
| 279 | + } | ||
| 280 | +} | ||
| 281 | + | ||
| 282 | +//android code use ExternalDirectoryPath | ||
| 283 | +try { | ||
| 284 | + let rootPath = fs.ExternalDirectoryPath; | ||
| 285 | + let fileName = 'signature_method.doc'; | ||
| 286 | + /* | ||
| 287 | + * savePath on Android may be: | ||
| 288 | + * /storage/emulated/0/Android/data/com.wechatsample/files/signature_method.doc | ||
| 289 | + **/ | ||
| 290 | + let savePath = rootPath + '/' + fileName; | ||
| 291 | + await fs.downloadFile('https://open.weixin.qq.com/zh_CN/htmledition/res/assets/signature_method.doc', savePath); | ||
| 292 | + let result = await WeChat.shareToSession({ | ||
| 293 | + type: 'file', | ||
| 294 | + title: fileName, // WeChat app treat title as file name | ||
| 295 | + description: 'share word file to chat session', | ||
| 296 | + mediaTagName: 'word file', | ||
| 297 | + messageAction: undefined, | ||
| 298 | + messageExt: undefined, | ||
| 299 | + filePath: savePath, | ||
| 300 | + fileExtension: '.doc' | ||
| 301 | + }); | ||
| 302 | + console.log('share word file to chat session successful', result); | ||
| 303 | +} | ||
| 304 | +catch (e) { | ||
| 305 | + if (e instanceof WeChat.WechatError) { | ||
| 306 | + console.error(e.stack); | ||
| 307 | + } else { | ||
| 308 | + throw e; | ||
| 309 | + } | ||
| 310 | +} | ||
| 311 | +``` | ||
| 312 | + | ||
| 313 | +#### shareToSession(message) | ||
| 314 | + | ||
| 315 | +- `message` {ShareMetadata} This object saves the metadata for sharing | ||
| 316 | +- returns {Object} | ||
| 317 | + | ||
| 318 | +Similar to `shareToTimeline` but sends the message to a friend or chat group. | ||
| 319 | + | ||
| 320 | +#### launchMini(params) | ||
| 321 | + | ||
| 322 | +- `params` {Object} 打开小程序的参数 | ||
| 323 | + | ||
| 324 | + - `userName` {String} 拉起的小程序的username | ||
| 325 | + | ||
| 326 | + - `miniProgramType` {Integer} 拉起小程序的类型. 0-正式版 1-开发版 2-体验版 | ||
| 327 | + | ||
| 328 | + - `path` {String} 拉起小程序页面的可带参路径,不填默认拉起小程序首页 | ||
| 329 | + | ||
| 330 | + | ||
| 331 | + | ||
| 332 | +#### pay(payload) | ||
| 333 | + | ||
| 334 | +- `payload` {Object} the payment data | ||
| 335 | + - `partnerId` {String} 商家向财付通申请的商家ID | ||
| 336 | + - `prepayId` {String} 预支付订单ID | ||
| 337 | + - `nonceStr` {String} 随机串 | ||
| 338 | + - `timeStamp` {String} 时间戳 | ||
| 339 | + - `package` {String} 商家根据财付通文档填写的数据和签名 | ||
| 340 | + - `sign` {String} 商家根据微信开放平台文档对数据做的签名 | ||
| 341 | +- returns {Object} | ||
| 342 | + | ||
| 343 | +Sends request for proceeding payment, then returns an object: | ||
| 344 | + | ||
| 345 | +| name | type | description | | ||
| 346 | +| ------- | ------ | ----------------------------------- | | ||
| 347 | +| errCode | Number | 0 if authorization successed | | ||
| 348 | +| errStr | String | Error message if any error occurred | | ||
| 349 | + | ||
| 350 | +## Installation | ||
| 351 | + | ||
| 352 | +```sh | ||
| 353 | +$ npm install react-native-wechat --save | ||
| 354 | +``` | ||
| 355 | + | ||
| 356 | +## Community | ||
| 357 | + | ||
| 358 | +#### IRC | ||
| 359 | + | ||
| 360 | +<a href="http://qm.qq.com/cgi-bin/qm/qr?k=cg3irEFCGxjkm2YJCt5V9OeJA1pNo5Ui"><img width="200" src="./qrcode_qq.jpg"></a> | ||
| 361 | + | ||
| 362 | +#### Tutorials | ||
| 363 | + | ||
| 364 | +- [react-native-wechat微信组件的使用](http://www.jianshu.com/p/3f424cccb888) | ||
| 365 | +- [超详细React Native实现微信好友/朋友圈分享功能-Android/iOS双平台通用](http://www.jianshu.com/p/ce5439dd1f52) | ||
| 366 | +- [柳轩涤俗 - 微信登录](http://www.cnblogs.com/zhangdw/p/6194345.html) | ||
| 367 | + | ||
| 368 | +#### Who's using it | ||
| 369 | + | ||
| 370 | +<a href="https://github.com/attentiveness/reading"><img height="80" width="80" src="https://raw.githubusercontent.com/attentiveness/reading/master/Reading_Logo.png"></a> | ||
| 371 | +<a href="https://github.com/lipeiwei-szu/ReactNativeOne"><img height="80" width="80" src="http://android-artworks.25pp.com/fs08/2017/05/22/3/110_ed42e5c8f701ae26be6b0c423cb51858_con_130x130.png"></a> | ||
| 372 | + | ||
| 373 | +## Authors | ||
| 374 | + | ||
| 375 | +| GitHub | Role | Email | | ||
| 376 | +|---------------|------------|-----------------------| | ||
| 377 | +| [@yorkie] | Author | yorkiefixer@gmail.com | | ||
| 378 | +| [@xing-zheng] | Emeriti | | | ||
| 379 | +| [@tdzl2003] | Emeriti | tdzl2003@gmail.com | | ||
| 380 | + | ||
| 381 | +[@yorkie]: https://github.com/yorkie | ||
| 382 | +[@xing-zheng]: https://github.com/xing-zheng | ||
| 383 | +[@tdzl2003]: https://github.com/tdzl2003 | ||
| 384 | + | ||
| 385 | +## License | ||
| 386 | + | ||
| 387 | +MIT | ||
| 388 | + | ||
| 389 | +[react-native-wechat]: https://github.com/yorkie/react-native-wechat | ||
| 390 | +[npm-image]: https://img.shields.io/npm/v/react-native-wechat.svg?style=flat-square | ||
| 391 | +[npm-url]: https://npmjs.org/package/react-native-wechat | ||
| 392 | +[travis-image]: https://img.shields.io/travis/yorkie/react-native-wechat.svg?style=flat-square | ||
| 393 | +[travis-url]: https://travis-ci.org/yorkie/react-native-wechat | ||
| 394 | +[david-image]: http://img.shields.io/david/yorkie/react-native-wechat.svg?style=flat-square | ||
| 395 | +[david-url]: https://david-dm.org/yorkie/react-native-wechat | ||
| 396 | +[downloads-image]: http://img.shields.io/npm/dm/react-native-wechat.svg?style=flat-square | ||
| 397 | +[downloads-url]: https://npmjs.org/package/react-native-wechat | ||
| 398 | +[React Native]: https://github.com/facebook/react-native | ||
| 399 | +[react-native-cn]: https://github.com/reactnativecn | ||
| 400 | +[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 | ||
| 401 | +[Linking Libraries iOS Guidance]: https://developer.apple.com/library/ios/recipes/xcode_help-project_editor/Articles/AddingaLibrarytoaTarget.html | ||
| 402 | + |
_config.yml
0 → 100644
| 1 | +theme: jekyll-theme-merlot |
android/build.gradle
0 → 100644
| 1 | +apply plugin: 'com.android.library' | ||
| 2 | + | ||
| 3 | +android { | ||
| 4 | + compileSdkVersion 28 | ||
| 5 | + buildToolsVersion "28.0.3" | ||
| 6 | + defaultConfig { | ||
| 7 | + minSdkVersion 16 | ||
| 8 | + targetSdkVersion 28 | ||
| 9 | + versionCode 1 | ||
| 10 | + versionName "1.0" | ||
| 11 | + ndk { | ||
| 12 | + abiFilters "armeabi-v7a", "x86" | ||
| 13 | + } | ||
| 14 | + } | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +allprojects { | ||
| 18 | + repositories { | ||
| 19 | + jcenter() | ||
| 20 | + maven { url "$projectDir/../../react-native/android" } | ||
| 21 | + } | ||
| 22 | +} | ||
| 23 | + | ||
| 24 | +dependencies { | ||
| 25 | + compile 'com.facebook.react:react-native:+' | ||
| 26 | + compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+' | ||
| 27 | +} |
android/react-native-wechat.iml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<module external.linked.project.id=":react-native-wechat" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/../../../android" external.system.id="GRADLE" type="JAVA_MODULE" version="4"> | ||
| 3 | + <component name="FacetManager"> | ||
| 4 | + <facet type="android-gradle" name="Android-Gradle"> | ||
| 5 | + <configuration> | ||
| 6 | + <option name="GRADLE_PROJECT_PATH" value=":react-native-wechat" /> | ||
| 7 | + </configuration> | ||
| 8 | + </facet> | ||
| 9 | + <facet type="android" name="Android"> | ||
| 10 | + <configuration> | ||
| 11 | + <option name="SELECTED_BUILD_VARIANT" value="debug" /> | ||
| 12 | + <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" /> | ||
| 13 | + <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" /> | ||
| 14 | + <afterSyncTasks> | ||
| 15 | + <task>generateDebugSources</task> | ||
| 16 | + </afterSyncTasks> | ||
| 17 | + <option name="ALLOW_USER_CONFIGURATION" value="false" /> | ||
| 18 | + <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" /> | ||
| 19 | + <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" /> | ||
| 20 | + <option name="RES_FOLDERS_RELATIVE_PATH" value="" /> | ||
| 21 | + <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" /> | ||
| 22 | + <option name="PROJECT_TYPE" value="1" /> | ||
| 23 | + </configuration> | ||
| 24 | + </facet> | ||
| 25 | + </component> | ||
| 26 | + <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7"> | ||
| 27 | + <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" /> | ||
| 28 | + <output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" /> | ||
| 29 | + <exclude-output /> | ||
| 30 | + <content url="file://$MODULE_DIR$"> | ||
| 31 | + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/debug" isTestSource="false" generated="true" /> | ||
| 32 | + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" /> | ||
| 33 | + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" /> | ||
| 34 | + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" /> | ||
| 35 | + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" /> | ||
| 36 | + <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" /> | ||
| 37 | + <sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" /> | ||
| 38 | + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/androidTest/debug" isTestSource="true" generated="true" /> | ||
| 39 | + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" /> | ||
| 40 | + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" /> | ||
| 41 | + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" /> | ||
| 42 | + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" /> | ||
| 43 | + <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" /> | ||
| 44 | + <sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" /> | ||
| 45 | + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/test/debug" isTestSource="true" generated="true" /> | ||
| 46 | + <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" /> | ||
| 47 | + <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" /> | ||
| 48 | + <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" /> | ||
| 49 | + <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" /> | ||
| 50 | + <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" /> | ||
| 51 | + <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" /> | ||
| 52 | + <sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" /> | ||
| 53 | + <sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" /> | ||
| 54 | + <sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" /> | ||
| 55 | + <sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" /> | ||
| 56 | + <sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" /> | ||
| 57 | + <sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" /> | ||
| 58 | + <sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" /> | ||
| 59 | + <sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" /> | ||
| 60 | + <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/res" type="java-test-resource" /> | ||
| 61 | + <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/resources" type="java-test-resource" /> | ||
| 62 | + <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/assets" type="java-test-resource" /> | ||
| 63 | + <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/aidl" isTestSource="true" /> | ||
| 64 | + <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/java" isTestSource="true" /> | ||
| 65 | + <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/rs" isTestSource="true" /> | ||
| 66 | + <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/shaders" isTestSource="true" /> | ||
| 67 | + <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" /> | ||
| 68 | + <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> | ||
| 69 | + <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" /> | ||
| 70 | + <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" /> | ||
| 71 | + <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> | ||
| 72 | + <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" /> | ||
| 73 | + <sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" /> | ||
| 74 | + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" /> | ||
| 75 | + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" /> | ||
| 76 | + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" /> | ||
| 77 | + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" /> | ||
| 78 | + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" /> | ||
| 79 | + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" /> | ||
| 80 | + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" /> | ||
| 81 | + <sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" /> | ||
| 82 | + <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" /> | ||
| 83 | + <sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" /> | ||
| 84 | + <sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" /> | ||
| 85 | + <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> | ||
| 86 | + <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" /> | ||
| 87 | + <sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" /> | ||
| 88 | + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/attr" /> | ||
| 89 | + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" /> | ||
| 90 | + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/check-manifest" /> | ||
| 91 | + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" /> | ||
| 92 | + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" /> | ||
| 93 | + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/packaged-aidl" /> | ||
| 94 | + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/packaged_res" /> | ||
| 95 | + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/public_res" /> | ||
| 96 | + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" /> | ||
| 97 | + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" /> | ||
| 98 | + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/splits-support" /> | ||
| 99 | + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" /> | ||
| 100 | + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/tmp" /> | ||
| 101 | + <excludeFolder url="file://$MODULE_DIR$/build/outputs" /> | ||
| 102 | + </content> | ||
| 103 | + <orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" /> | ||
| 104 | + <orderEntry type="sourceFolder" forTests="false" /> | ||
| 105 | + <orderEntry type="library" name="com.facebook.fresco:imagepipeline-okhttp3-1.3.0" level="project" /> | ||
| 106 | + <orderEntry type="library" name="com.android.support:support-v4-23.0.1" level="project" /> | ||
| 107 | + <orderEntry type="library" name="com.facebook.fresco:imagepipeline-1.3.0" level="project" /> | ||
| 108 | + <orderEntry type="library" name="com.squareup.okhttp3:okhttp:3.6.0@jar" level="project" /> | ||
| 109 | + <orderEntry type="library" name="com.facebook.fresco:fbcore-1.3.0" level="project" /> | ||
| 110 | + <orderEntry type="library" name="com.facebook.fresco:drawee-1.3.0" level="project" /> | ||
| 111 | + <orderEntry type="library" name="com.tencent.mm.opensdk:wechat-sdk-android-without-mta:5.1.4@jar" level="project" /> | ||
| 112 | + <orderEntry type="library" name="com.android.support:appcompat-v7-23.0.1" level="project" /> | ||
| 113 | + <orderEntry type="library" name="javax.inject:javax.inject:1@jar" level="project" /> | ||
| 114 | + <orderEntry type="library" name="com.facebook.fbui.textlayoutbuilder:staticlayout-proxy:1.0@jar" level="project" /> | ||
| 115 | + <orderEntry type="library" name="com.facebook.fresco:imagepipeline-base-1.3.0" level="project" /> | ||
| 116 | + <orderEntry type="library" name="com.parse.bolts:bolts-tasks:1.4.0@jar" level="project" /> | ||
| 117 | + <orderEntry type="library" name="com.facebook.react:react-native-0.55.4" level="project" /> | ||
| 118 | + <orderEntry type="library" name="com.google.code.findbugs:jsr305:3.0.0@jar" level="project" /> | ||
| 119 | + <orderEntry type="library" name="com.squareup.okhttp3:okhttp-urlconnection:3.6.0@jar" level="project" /> | ||
| 120 | + <orderEntry type="library" name="com.android.support:support-annotations:23.0.1@jar" level="project" /> | ||
| 121 | + <orderEntry type="library" name="com.facebook.soloader:soloader-0.1.0" level="project" /> | ||
| 122 | + <orderEntry type="library" name="com.squareup.okio:okio:1.13.0@jar" level="project" /> | ||
| 123 | + <orderEntry type="library" name="com.facebook.fbui.textlayoutbuilder:textlayoutbuilder-1.0.0" level="project" /> | ||
| 124 | + <orderEntry type="library" name="com.facebook.fresco:fresco-1.3.0" level="project" /> | ||
| 125 | + <orderEntry type="library" name="org.webkit:android-jsc-r174650" level="project" /> | ||
| 126 | + </component> | ||
| 127 | +</module> |
android/src/main/AndroidManifest.xml
0 → 100644
| 1 | +<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 2 | + package="com.theweflex.react"> | ||
| 3 | + <uses-permission android:name="android.permission.INTERNET"/> | ||
| 4 | + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> | ||
| 5 | + <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> | ||
| 6 | + <uses-permission android:name="android.permission.READ_PHONE_STATE"/> | ||
| 7 | + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> | ||
| 8 | +</manifest> |
| 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.references.CloseableReference; | ||
| 11 | +import com.facebook.common.util.UriUtil; | ||
| 12 | +import com.facebook.datasource.DataSource; | ||
| 13 | +import com.facebook.drawee.backends.pipeline.Fresco; | ||
| 14 | +import com.facebook.imagepipeline.common.ResizeOptions; | ||
| 15 | +import com.facebook.imagepipeline.core.ImagePipeline; | ||
| 16 | +import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber; | ||
| 17 | +import com.facebook.imagepipeline.image.CloseableImage; | ||
| 18 | +import com.facebook.imagepipeline.request.ImageRequest; | ||
| 19 | +import com.facebook.imagepipeline.request.ImageRequestBuilder; | ||
| 20 | +import com.facebook.react.bridge.Arguments; | ||
| 21 | +import com.facebook.react.bridge.Callback; | ||
| 22 | +import com.facebook.react.bridge.ReactApplicationContext; | ||
| 23 | +import com.facebook.react.bridge.ReactContextBaseJavaModule; | ||
| 24 | +import com.facebook.react.bridge.ReactMethod; | ||
| 25 | +import com.facebook.react.bridge.ReadableMap; | ||
| 26 | +import com.facebook.react.bridge.WritableMap; | ||
| 27 | +import com.facebook.react.modules.core.DeviceEventManagerModule; | ||
| 28 | +import com.tencent.mm.opensdk.constants.Build; | ||
| 29 | +import com.tencent.mm.opensdk.constants.ConstantsAPI; | ||
| 30 | +import com.tencent.mm.opensdk.modelbase.BaseReq; | ||
| 31 | +import com.tencent.mm.opensdk.modelbase.BaseResp; | ||
| 32 | +import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram; | ||
| 33 | +import com.tencent.mm.opensdk.modelmsg.SendAuth; | ||
| 34 | +import com.tencent.mm.opensdk.modelmsg.SendMessageToWX; | ||
| 35 | +import com.tencent.mm.opensdk.modelmsg.WXFileObject; | ||
| 36 | +import com.tencent.mm.opensdk.modelmsg.WXImageObject; | ||
| 37 | +import com.tencent.mm.opensdk.modelmsg.WXMediaMessage; | ||
| 38 | +import com.tencent.mm.opensdk.modelmsg.WXMiniProgramObject; | ||
| 39 | +import com.tencent.mm.opensdk.modelmsg.WXMusicObject; | ||
| 40 | +import com.tencent.mm.opensdk.modelmsg.WXTextObject; | ||
| 41 | +import com.tencent.mm.opensdk.modelmsg.WXVideoObject; | ||
| 42 | +import com.tencent.mm.opensdk.modelmsg.WXWebpageObject; | ||
| 43 | +import com.tencent.mm.opensdk.modelpay.PayReq; | ||
| 44 | +import com.tencent.mm.opensdk.modelpay.PayResp; | ||
| 45 | +import com.tencent.mm.opensdk.openapi.IWXAPI; | ||
| 46 | +import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler; | ||
| 47 | +import com.tencent.mm.opensdk.openapi.WXAPIFactory; | ||
| 48 | + | ||
| 49 | +import java.util.ArrayList; | ||
| 50 | +import java.util.UUID; | ||
| 51 | + | ||
| 52 | +/** | ||
| 53 | + * Created by tdzl2_000 on 2015-10-10. | ||
| 54 | + */ | ||
| 55 | +public class WeChatModule extends ReactContextBaseJavaModule implements IWXAPIEventHandler { | ||
| 56 | + private String appId; | ||
| 57 | + | ||
| 58 | + private IWXAPI api = null; | ||
| 59 | + private final static String NOT_REGISTERED = "registerApp required."; | ||
| 60 | + private final static String INVOKE_FAILED = "WeChat API invoke returns false."; | ||
| 61 | + private final static String INVALID_ARGUMENT = "invalid argument."; | ||
| 62 | + | ||
| 63 | + public WeChatModule(ReactApplicationContext context) { | ||
| 64 | + super(context); | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + @Override | ||
| 68 | + public String getName() { | ||
| 69 | + return "RCTWeChat"; | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + /** | ||
| 73 | + * fix Native module WeChatModule tried to override WeChatModule for module name RCTWeChat. | ||
| 74 | + * If this was your intention, return true from WeChatModule#canOverrideExistingModule() bug | ||
| 75 | + * | ||
| 76 | + * @return | ||
| 77 | + */ | ||
| 78 | + public boolean canOverrideExistingModule(){ | ||
| 79 | + return true; | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + private static ArrayList<WeChatModule> modules = new ArrayList<>(); | ||
| 83 | + | ||
| 84 | + @Override | ||
| 85 | + public void initialize() { | ||
| 86 | + super.initialize(); | ||
| 87 | + modules.add(this); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + @Override | ||
| 91 | + public void onCatalystInstanceDestroy() { | ||
| 92 | + super.onCatalystInstanceDestroy(); | ||
| 93 | + if (api != null) { | ||
| 94 | + api = null; | ||
| 95 | + } | ||
| 96 | + modules.remove(this); | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + public static void handleIntent(Intent intent) { | ||
| 100 | + for (WeChatModule mod : modules) { | ||
| 101 | + mod.api.handleIntent(intent, mod); | ||
| 102 | + } | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + @ReactMethod | ||
| 106 | + public void registerApp(String appid, Callback callback) { | ||
| 107 | + this.appId = appid; | ||
| 108 | + api = WXAPIFactory.createWXAPI(this.getReactApplicationContext().getBaseContext(), appid, true); | ||
| 109 | + callback.invoke(null, api.registerApp(appid)); | ||
| 110 | + } | ||
| 111 | + | ||
| 112 | + @ReactMethod | ||
| 113 | + public void isWXAppInstalled(Callback callback) { | ||
| 114 | + if (api == null) { | ||
| 115 | + callback.invoke(NOT_REGISTERED); | ||
| 116 | + return; | ||
| 117 | + } | ||
| 118 | + callback.invoke(null, api.isWXAppInstalled()); | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + @ReactMethod | ||
| 122 | + public void isWXAppSupportApi(String supportApi, Callback callback) { | ||
| 123 | + if (api == null) { | ||
| 124 | + callback.invoke(NOT_REGISTERED); | ||
| 125 | + return; | ||
| 126 | + } | ||
| 127 | + int supportSDKINT = Build.PAY_SUPPORTED_SDK_INT; | ||
| 128 | + switch (supportApi) { | ||
| 129 | + case "SDK_INT": | ||
| 130 | + supportSDKINT = Build.SDK_INT; | ||
| 131 | + break; | ||
| 132 | + case "MIN_SDK_INT": | ||
| 133 | + supportSDKINT = Build.MIN_SDK_INT; | ||
| 134 | + break; | ||
| 135 | + case "CHECK_TOKEN_SDK_INT": | ||
| 136 | + supportSDKINT = Build.CHECK_TOKEN_SDK_INT; | ||
| 137 | + break; | ||
| 138 | + case "TIMELINE_SUPPORTED_SDK_INT": | ||
| 139 | + supportSDKINT = Build.TIMELINE_SUPPORTED_SDK_INT; | ||
| 140 | + break; | ||
| 141 | + case "EMOJI_SUPPORTED_SDK_INT": | ||
| 142 | + supportSDKINT = Build.EMOJI_SUPPORTED_SDK_INT; | ||
| 143 | + break; | ||
| 144 | + case "MUSIC_DATA_URL_SUPPORTED_SDK_INT": | ||
| 145 | + supportSDKINT = Build.MUSIC_DATA_URL_SUPPORTED_SDK_INT; | ||
| 146 | + break; | ||
| 147 | + case "PAY_SUPPORTED_SDK_INT": | ||
| 148 | + supportSDKINT = Build.PAY_SUPPORTED_SDK_INT; | ||
| 149 | + break; | ||
| 150 | + case "OPENID_SUPPORTED_SDK_INT": | ||
| 151 | + supportSDKINT = Build.OPENID_SUPPORTED_SDK_INT; | ||
| 152 | + break; | ||
| 153 | + case "FAVORITE_SUPPPORTED_SDK_INT": | ||
| 154 | + supportSDKINT = Build.FAVORITE_SUPPPORTED_SDK_INT; | ||
| 155 | + break; | ||
| 156 | + case "MESSAGE_ACTION_SUPPPORTED_SDK_INT": | ||
| 157 | + supportSDKINT = Build.MESSAGE_ACTION_SUPPPORTED_SDK_INT; | ||
| 158 | + break; | ||
| 159 | + case "SCAN_QRCODE_AUTH_SUPPORTED_SDK_INT": | ||
| 160 | + supportSDKINT = Build.SCAN_QRCODE_AUTH_SUPPORTED_SDK_INT; | ||
| 161 | + break; | ||
| 162 | + case "MINIPROGRAM_SUPPORTED_SDK_INT": | ||
| 163 | + supportSDKINT = Build.MINIPROGRAM_SUPPORTED_SDK_INT; | ||
| 164 | + break; | ||
| 165 | + case "VIDEO_FILE_SUPPORTED_SDK_INT": | ||
| 166 | + supportSDKINT = Build.VIDEO_FILE_SUPPORTED_SDK_INT; | ||
| 167 | + break; | ||
| 168 | + case "SUBSCRIBE_MESSAGE_SUPPORTED_SDK_INT": | ||
| 169 | + supportSDKINT = Build.SUBSCRIBE_MESSAGE_SUPPORTED_SDK_INT; | ||
| 170 | + break; | ||
| 171 | + case "LAUNCH_MINIPROGRAM_SUPPORTED_SDK_INT": | ||
| 172 | + supportSDKINT = Build.LAUNCH_MINIPROGRAM_SUPPORTED_SDK_INT; | ||
| 173 | + break; | ||
| 174 | + case "CHOOSE_INVOICE_TILE_SUPPORT_SDK_INT": | ||
| 175 | + supportSDKINT = Build.CHOOSE_INVOICE_TILE_SUPPORT_SDK_INT; | ||
| 176 | + break; | ||
| 177 | + case "INVOICE_AUTH_INSERT_SDK_INT": | ||
| 178 | + supportSDKINT = Build.INVOICE_AUTH_INSERT_SDK_INT; | ||
| 179 | + break; | ||
| 180 | + case "NON_TAX_PAY_SDK_INT": | ||
| 181 | + supportSDKINT = Build.NON_TAX_PAY_SDK_INT; | ||
| 182 | + break; | ||
| 183 | + case "PAY_INSURANCE_SDK_INT": | ||
| 184 | + supportSDKINT = Build.PAY_INSURANCE_SDK_INT; | ||
| 185 | + break; | ||
| 186 | + case "SUBSCRIBE_MINI_PROGRAM_MSG_SUPPORTED_SDK_INT": | ||
| 187 | + supportSDKINT = Build.SUBSCRIBE_MINI_PROGRAM_MSG_SUPPORTED_SDK_INT; | ||
| 188 | + break; | ||
| 189 | + case "OFFLINE_PAY_SDK_INT": | ||
| 190 | + supportSDKINT = Build.OFFLINE_PAY_SDK_INT; | ||
| 191 | + break; | ||
| 192 | + case "SEND_TO_SPECIFIED_CONTACT_SDK_INT": | ||
| 193 | + supportSDKINT = Build.SEND_TO_SPECIFIED_CONTACT_SDK_INT; | ||
| 194 | + break; | ||
| 195 | + case "OPEN_BUSINESS_WEBVIEW_SDK_INT": | ||
| 196 | + supportSDKINT = Build.OPEN_BUSINESS_WEBVIEW_SDK_INT; | ||
| 197 | + break; | ||
| 198 | + } | ||
| 199 | + boolean isWXAppSupportAPI = api.getWXAppSupportAPI() >= supportSDKINT; | ||
| 200 | + callback.invoke(null, isWXAppSupportAPI); | ||
| 201 | + } | ||
| 202 | + | ||
| 203 | + @ReactMethod | ||
| 204 | + public void getApiVersion(Callback callback) { | ||
| 205 | + if (api == null) { | ||
| 206 | + callback.invoke(NOT_REGISTERED); | ||
| 207 | + return; | ||
| 208 | + } | ||
| 209 | + callback.invoke(null, api.getWXAppSupportAPI()); | ||
| 210 | + } | ||
| 211 | + | ||
| 212 | + @ReactMethod | ||
| 213 | + public void openWXApp(Callback callback) { | ||
| 214 | + if (api == null) { | ||
| 215 | + callback.invoke(NOT_REGISTERED); | ||
| 216 | + return; | ||
| 217 | + } | ||
| 218 | + callback.invoke(null, api.openWXApp()); | ||
| 219 | + } | ||
| 220 | + | ||
| 221 | + @ReactMethod | ||
| 222 | + public void sendAuthRequest(String scope, String state, Callback callback) { | ||
| 223 | + if (api == null) { | ||
| 224 | + callback.invoke(NOT_REGISTERED); | ||
| 225 | + return; | ||
| 226 | + } | ||
| 227 | + SendAuth.Req req = new SendAuth.Req(); | ||
| 228 | + req.scope = scope; | ||
| 229 | + req.state = state; | ||
| 230 | + callback.invoke(null, api.sendReq(req)); | ||
| 231 | + } | ||
| 232 | + | ||
| 233 | + @ReactMethod | ||
| 234 | + public void shareToTimeline(ReadableMap data, Callback callback) { | ||
| 235 | + if (api == null) { | ||
| 236 | + callback.invoke(NOT_REGISTERED); | ||
| 237 | + return; | ||
| 238 | + } | ||
| 239 | + _share(SendMessageToWX.Req.WXSceneTimeline, data, callback); | ||
| 240 | + } | ||
| 241 | + | ||
| 242 | + @ReactMethod | ||
| 243 | + public void launchMini(ReadableMap data, Callback callback) { | ||
| 244 | + if (api == null) { | ||
| 245 | + callback.invoke(NOT_REGISTERED); | ||
| 246 | + return; | ||
| 247 | + } | ||
| 248 | + WXLaunchMiniProgram.Req req = new WXLaunchMiniProgram.Req(); | ||
| 249 | + req.userName = data.getString("userName"); // 填小程序原始id | ||
| 250 | + req.path = data.getString("path"); //拉起小程序页面的可带参路径,不填默认拉起小程序首页 | ||
| 251 | + req.miniprogramType = data.getInt("miniProgramType");// 可选打开 开发版,体验版和正式版 | ||
| 252 | +// req.miniprogramType = WXLaunchMiniProgram.Req.MINIPTOGRAM_TYPE_RELEASE;// 可选打开 开发版,体验版和正式版 | ||
| 253 | + boolean success = api.sendReq(req); | ||
| 254 | + if (!success) callback.invoke(INVALID_ARGUMENT); | ||
| 255 | + } | ||
| 256 | + | ||
| 257 | + @ReactMethod | ||
| 258 | + public void shareToSession(ReadableMap data, Callback callback) { | ||
| 259 | + if (api == null) { | ||
| 260 | + callback.invoke(NOT_REGISTERED); | ||
| 261 | + return; | ||
| 262 | + } | ||
| 263 | + _share(SendMessageToWX.Req.WXSceneSession, data, callback); | ||
| 264 | + } | ||
| 265 | + | ||
| 266 | + @ReactMethod | ||
| 267 | + public void pay(ReadableMap data, Callback callback) { | ||
| 268 | + PayReq payReq = new PayReq(); | ||
| 269 | + if (data.hasKey("partnerId")) { | ||
| 270 | + payReq.partnerId = data.getString("partnerId"); | ||
| 271 | + } | ||
| 272 | + if (data.hasKey("prepayId")) { | ||
| 273 | + payReq.prepayId = data.getString("prepayId"); | ||
| 274 | + } | ||
| 275 | + if (data.hasKey("nonceStr")) { | ||
| 276 | + payReq.nonceStr = data.getString("nonceStr"); | ||
| 277 | + } | ||
| 278 | + if (data.hasKey("timeStamp")) { | ||
| 279 | + payReq.timeStamp = data.getString("timeStamp"); | ||
| 280 | + } | ||
| 281 | + if (data.hasKey("sign")) { | ||
| 282 | + payReq.sign = data.getString("sign"); | ||
| 283 | + } | ||
| 284 | + if (data.hasKey("package")) { | ||
| 285 | + payReq.packageValue = data.getString("package"); | ||
| 286 | + } | ||
| 287 | + if (data.hasKey("extData")) { | ||
| 288 | + payReq.extData = data.getString("extData"); | ||
| 289 | + } | ||
| 290 | + payReq.appId = appId; | ||
| 291 | + callback.invoke(api.sendReq(payReq) ? null : INVOKE_FAILED); | ||
| 292 | + } | ||
| 293 | + | ||
| 294 | + private void _share(final int scene, final ReadableMap data, final Callback callback) { | ||
| 295 | + Uri uri = null; | ||
| 296 | + if (data.hasKey("thumbImage") || data.hasKey("hdImageData")) { | ||
| 297 | + String imageUrl = data.hasKey("hdImageData") ? data.getString("hdImageData") : data.getString("thumbImage"); | ||
| 298 | + | ||
| 299 | + try { | ||
| 300 | + uri = Uri.parse(imageUrl); | ||
| 301 | + // Verify scheme is set, so that relative uri (used by static resources) are not handled. | ||
| 302 | + if (uri.getScheme() == null) { | ||
| 303 | + uri = getResourceDrawableUri(getReactApplicationContext(), imageUrl); | ||
| 304 | + } | ||
| 305 | + } catch (Exception e) { | ||
| 306 | + // ignore malformed uri, then attempt to extract resource ID. | ||
| 307 | + } | ||
| 308 | + } | ||
| 309 | + | ||
| 310 | + if (uri != null) { | ||
| 311 | + this._getImage(uri, new ResizeOptions(100, 100), new ImageCallback() { | ||
| 312 | + @Override | ||
| 313 | + public void invoke(@Nullable Bitmap bitmap) { | ||
| 314 | + WeChatModule.this._share(scene, data, bitmap, callback); | ||
| 315 | + } | ||
| 316 | + }); | ||
| 317 | + } else { | ||
| 318 | + this._share(scene, data, null, callback); | ||
| 319 | + } | ||
| 320 | + } | ||
| 321 | + | ||
| 322 | + private void _getImage(Uri uri, ResizeOptions resizeOptions, final ImageCallback imageCallback) { | ||
| 323 | + BaseBitmapDataSubscriber dataSubscriber = new BaseBitmapDataSubscriber() { | ||
| 324 | + @Override | ||
| 325 | + protected void onNewResultImpl(Bitmap bitmap) { | ||
| 326 | + bitmap = bitmap.copy(bitmap.getConfig(), true); | ||
| 327 | + imageCallback.invoke(bitmap); | ||
| 328 | + } | ||
| 329 | + | ||
| 330 | + @Override | ||
| 331 | + protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) { | ||
| 332 | + imageCallback.invoke(null); | ||
| 333 | + } | ||
| 334 | + }; | ||
| 335 | + | ||
| 336 | + ImageRequestBuilder builder = ImageRequestBuilder.newBuilderWithSource(uri); | ||
| 337 | + if (resizeOptions != null) { | ||
| 338 | +// builder = builder.setResizeOptions(resizeOptions); | ||
| 339 | + } | ||
| 340 | + ImageRequest imageRequest = builder.build(); | ||
| 341 | + | ||
| 342 | + ImagePipeline imagePipeline = Fresco.getImagePipeline(); | ||
| 343 | + DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(imageRequest, null); | ||
| 344 | + dataSource.subscribe(dataSubscriber, UiThreadImmediateExecutorService.getInstance()); | ||
| 345 | + } | ||
| 346 | + | ||
| 347 | + private static Uri getResourceDrawableUri(Context context, String name) { | ||
| 348 | + if (name == null || name.isEmpty()) { | ||
| 349 | + return null; | ||
| 350 | + } | ||
| 351 | + name = name.toLowerCase().replace("-", "_"); | ||
| 352 | + int resId = context.getResources().getIdentifier( | ||
| 353 | + name, | ||
| 354 | + "drawable", | ||
| 355 | + context.getPackageName()); | ||
| 356 | + | ||
| 357 | + if (resId == 0) { | ||
| 358 | + return null; | ||
| 359 | + } else { | ||
| 360 | + return new Uri.Builder() | ||
| 361 | + .scheme(UriUtil.LOCAL_RESOURCE_SCHEME) | ||
| 362 | + .path(String.valueOf(resId)) | ||
| 363 | + .build(); | ||
| 364 | + } | ||
| 365 | + } | ||
| 366 | + | ||
| 367 | + private void _share(final int scene, final ReadableMap data, final Bitmap thumbImage, final Callback callback) { | ||
| 368 | + if (!data.hasKey("type")) { | ||
| 369 | + callback.invoke(INVALID_ARGUMENT); | ||
| 370 | + return; | ||
| 371 | + } | ||
| 372 | + String type = data.getString("type"); | ||
| 373 | + | ||
| 374 | + WXMediaMessage.IMediaObject mediaObject = null; | ||
| 375 | + if (type.equals("news")) { | ||
| 376 | + mediaObject = _jsonToWebpageMedia(data); | ||
| 377 | + } else if (type.equals("text")) { | ||
| 378 | + mediaObject = _jsonToTextMedia(data); | ||
| 379 | + } else if (type.equals("imageUrl") || type.equals("imageResource")) { | ||
| 380 | + __jsonToImageUrlMedia(data, new MediaObjectCallback() { | ||
| 381 | + @Override | ||
| 382 | + public void invoke(@Nullable WXMediaMessage.IMediaObject mediaObject) { | ||
| 383 | + if (mediaObject == null) { | ||
| 384 | + callback.invoke(INVALID_ARGUMENT); | ||
| 385 | + } else { | ||
| 386 | + WeChatModule.this._share(scene, data, thumbImage, mediaObject, callback); | ||
| 387 | + } | ||
| 388 | + } | ||
| 389 | + }); | ||
| 390 | + return; | ||
| 391 | + } else if (type.equals("imageFile")) { | ||
| 392 | + __jsonToImageFileMedia(data, new MediaObjectCallback() { | ||
| 393 | + @Override | ||
| 394 | + public void invoke(@Nullable WXMediaMessage.IMediaObject mediaObject) { | ||
| 395 | + if (mediaObject == null) { | ||
| 396 | + callback.invoke(INVALID_ARGUMENT); | ||
| 397 | + } else { | ||
| 398 | + WeChatModule.this._share(scene, data, thumbImage, mediaObject, callback); | ||
| 399 | + } | ||
| 400 | + } | ||
| 401 | + }); | ||
| 402 | + return; | ||
| 403 | + } else if (type.equals("video")) { | ||
| 404 | + mediaObject = __jsonToVideoMedia(data); | ||
| 405 | + } else if (type.equals("audio")) { | ||
| 406 | + mediaObject = __jsonToMusicMedia(data); | ||
| 407 | + } else if (type.equals("file")) { | ||
| 408 | + mediaObject = __jsonToFileMedia(data); | ||
| 409 | + } else if (type.equals("mini")) { | ||
| 410 | + mediaObject = __jsonToMiniMedia(data); | ||
| 411 | + } | ||
| 412 | + | ||
| 413 | + if (mediaObject == null) { | ||
| 414 | + callback.invoke(INVALID_ARGUMENT); | ||
| 415 | + } else { | ||
| 416 | + _share(scene, data, thumbImage, mediaObject, callback); | ||
| 417 | + } | ||
| 418 | + } | ||
| 419 | + | ||
| 420 | + private void _share(int scene, ReadableMap data, Bitmap thumbImage, WXMediaMessage.IMediaObject mediaObject, Callback callback) { | ||
| 421 | + | ||
| 422 | + WXMediaMessage message = new WXMediaMessage(); | ||
| 423 | + message.mediaObject = mediaObject; | ||
| 424 | + | ||
| 425 | + if (thumbImage != null) { | ||
| 426 | + message.setThumbImage(thumbImage); | ||
| 427 | + } | ||
| 428 | + if (data.hasKey("title")) { | ||
| 429 | + message.title = data.getString("title"); | ||
| 430 | + } | ||
| 431 | + if (data.hasKey("description")) { | ||
| 432 | + message.description = data.getString("description"); | ||
| 433 | + } | ||
| 434 | + if (data.hasKey("mediaTagName")) { | ||
| 435 | + message.mediaTagName = data.getString("mediaTagName"); | ||
| 436 | + } | ||
| 437 | + if (data.hasKey("messageAction")) { | ||
| 438 | + message.messageAction = data.getString("messageAction"); | ||
| 439 | + } | ||
| 440 | + if (data.hasKey("messageExt")) { | ||
| 441 | + message.messageExt = data.getString("messageExt"); | ||
| 442 | + } | ||
| 443 | + | ||
| 444 | + SendMessageToWX.Req req = new SendMessageToWX.Req(); | ||
| 445 | + req.message = message; | ||
| 446 | + req.scene = scene; | ||
| 447 | + req.transaction = UUID.randomUUID().toString(); | ||
| 448 | + callback.invoke(null, api.sendReq(req)); | ||
| 449 | + } | ||
| 450 | + | ||
| 451 | + private WXTextObject _jsonToTextMedia(ReadableMap data) { | ||
| 452 | + if (!data.hasKey("description")) { | ||
| 453 | + return null; | ||
| 454 | + } | ||
| 455 | + | ||
| 456 | + WXTextObject ret = new WXTextObject(); | ||
| 457 | + ret.text = data.getString("description"); | ||
| 458 | + return ret; | ||
| 459 | + } | ||
| 460 | + | ||
| 461 | + private WXWebpageObject _jsonToWebpageMedia(ReadableMap data) { | ||
| 462 | + if (!data.hasKey("webpageUrl")) { | ||
| 463 | + return null; | ||
| 464 | + } | ||
| 465 | + | ||
| 466 | + WXWebpageObject ret = new WXWebpageObject(); | ||
| 467 | + ret.webpageUrl = data.getString("webpageUrl"); | ||
| 468 | + if (data.hasKey("extInfo")) { | ||
| 469 | + ret.extInfo = data.getString("extInfo"); | ||
| 470 | + } | ||
| 471 | + return ret; | ||
| 472 | + } | ||
| 473 | + | ||
| 474 | + private void __jsonToImageMedia(String imageUrl, final MediaObjectCallback callback) { | ||
| 475 | + Uri imageUri; | ||
| 476 | + try { | ||
| 477 | + imageUri = Uri.parse(imageUrl); | ||
| 478 | + // Verify scheme is set, so that relative uri (used by static resources) are not handled. | ||
| 479 | + if (imageUri.getScheme() == null) { | ||
| 480 | + imageUri = getResourceDrawableUri(getReactApplicationContext(), imageUrl); | ||
| 481 | + } | ||
| 482 | + } catch (Exception e) { | ||
| 483 | + imageUri = null; | ||
| 484 | + } | ||
| 485 | + | ||
| 486 | + if (imageUri == null) { | ||
| 487 | + callback.invoke(null); | ||
| 488 | + return; | ||
| 489 | + } | ||
| 490 | + | ||
| 491 | + this._getImage(imageUri, null, new ImageCallback() { | ||
| 492 | + @Override | ||
| 493 | + public void invoke(@Nullable Bitmap bitmap) { | ||
| 494 | + callback.invoke(bitmap == null ? null : new WXImageObject(bitmap)); | ||
| 495 | + } | ||
| 496 | + }); | ||
| 497 | + } | ||
| 498 | + | ||
| 499 | + private void __jsonToImageUrlMedia(ReadableMap data, MediaObjectCallback callback) { | ||
| 500 | + if (!data.hasKey("imageUrl")) { | ||
| 501 | + callback.invoke(null); | ||
| 502 | + return; | ||
| 503 | + } | ||
| 504 | + String imageUrl = data.getString("imageUrl"); | ||
| 505 | + __jsonToImageMedia(imageUrl, callback); | ||
| 506 | + } | ||
| 507 | + | ||
| 508 | + private void __jsonToImageFileMedia(ReadableMap data, MediaObjectCallback callback) { | ||
| 509 | + if (!data.hasKey("imageUrl")) { | ||
| 510 | + callback.invoke(null); | ||
| 511 | + return; | ||
| 512 | + } | ||
| 513 | + | ||
| 514 | + String imageUrl = data.getString("imageUrl"); | ||
| 515 | + if (!imageUrl.toLowerCase().startsWith("file://")) { | ||
| 516 | + imageUrl = "file://" + imageUrl; | ||
| 517 | + } | ||
| 518 | + __jsonToImageMedia(imageUrl, callback); | ||
| 519 | + } | ||
| 520 | + | ||
| 521 | + private WXMusicObject __jsonToMusicMedia(ReadableMap data) { | ||
| 522 | + if (!data.hasKey("musicUrl")) { | ||
| 523 | + return null; | ||
| 524 | + } | ||
| 525 | + | ||
| 526 | + WXMusicObject ret = new WXMusicObject(); | ||
| 527 | + ret.musicUrl = data.getString("musicUrl"); | ||
| 528 | + return ret; | ||
| 529 | + } | ||
| 530 | + | ||
| 531 | + private WXVideoObject __jsonToVideoMedia(ReadableMap data) { | ||
| 532 | + if (!data.hasKey("videoUrl")) { | ||
| 533 | + return null; | ||
| 534 | + } | ||
| 535 | + | ||
| 536 | + WXVideoObject ret = new WXVideoObject(); | ||
| 537 | + ret.videoUrl = data.getString("videoUrl"); | ||
| 538 | + return ret; | ||
| 539 | + } | ||
| 540 | + | ||
| 541 | + private WXFileObject __jsonToFileMedia(ReadableMap data) { | ||
| 542 | + if (!data.hasKey("filePath")) { | ||
| 543 | + return null; | ||
| 544 | + } | ||
| 545 | + return new WXFileObject(data.getString("filePath")); | ||
| 546 | + } | ||
| 547 | + | ||
| 548 | + private WXMiniProgramObject __jsonToMiniMedia(ReadableMap data) { | ||
| 549 | + if (!data.hasKey("userName")) { | ||
| 550 | + return null; | ||
| 551 | + } | ||
| 552 | + WXMiniProgramObject miniProgramObject = new WXMiniProgramObject(); | ||
| 553 | + miniProgramObject.userName = data.getString("userName"); | ||
| 554 | + if (data.hasKey("miniProgramType")) | ||
| 555 | + miniProgramObject.miniprogramType = data.getInt("miniProgramType"); | ||
| 556 | + if (data.hasKey("webpageUrl")) miniProgramObject.webpageUrl = data.getString("webpageUrl"); | ||
| 557 | + if (data.hasKey("path")) miniProgramObject.path = data.getString("path"); | ||
| 558 | + if (data.hasKey("withShareTicket")) | ||
| 559 | + miniProgramObject.withShareTicket = data.getBoolean("withShareTicket"); | ||
| 560 | + return miniProgramObject; | ||
| 561 | + } | ||
| 562 | + | ||
| 563 | + // TODO: 实现sendRequest、sendSuccessResponse、sendErrorCommonResponse、sendErrorUserCancelResponse | ||
| 564 | + | ||
| 565 | + @Override | ||
| 566 | + public void onReq(BaseReq baseReq) { | ||
| 567 | + | ||
| 568 | + } | ||
| 569 | + | ||
| 570 | + @Override | ||
| 571 | + public void onResp(BaseResp baseResp) { | ||
| 572 | + WritableMap map = Arguments.createMap(); | ||
| 573 | + map.putInt("errCode", baseResp.errCode); | ||
| 574 | + map.putString("errStr", baseResp.errStr); | ||
| 575 | + map.putString("openId", baseResp.openId); | ||
| 576 | + map.putString("transaction", baseResp.transaction); | ||
| 577 | + | ||
| 578 | + if (baseResp instanceof SendAuth.Resp) { | ||
| 579 | + SendAuth.Resp resp = (SendAuth.Resp) (baseResp); | ||
| 580 | + | ||
| 581 | + map.putString("type", "SendAuth.Resp"); | ||
| 582 | + map.putString("code", resp.code); | ||
| 583 | + map.putString("state", resp.state); | ||
| 584 | + map.putString("url", resp.url); | ||
| 585 | + map.putString("lang", resp.lang); | ||
| 586 | + map.putString("country", resp.country); | ||
| 587 | + } else if (baseResp instanceof SendMessageToWX.Resp) { | ||
| 588 | + SendMessageToWX.Resp resp = (SendMessageToWX.Resp) (baseResp); | ||
| 589 | + map.putString("type", "SendMessageToWX.Resp"); | ||
| 590 | + } else if (baseResp instanceof PayResp) { | ||
| 591 | + PayResp resp = (PayResp) (baseResp); | ||
| 592 | + map.putString("type", "PayReq.Resp"); | ||
| 593 | + map.putString("returnKey", resp.returnKey); | ||
| 594 | + } else if (baseResp.getType() == ConstantsAPI.COMMAND_LAUNCH_WX_MINIPROGRAM) { | ||
| 595 | + WXLaunchMiniProgram.Resp resp = (WXLaunchMiniProgram.Resp) baseResp; | ||
| 596 | + String extraData = resp.extMsg; // 对应JsApi navigateBackApplication中的extraData字段数据 | ||
| 597 | + map.putString("extraData", extraData); | ||
| 598 | + } | ||
| 599 | + | ||
| 600 | + this.getReactApplicationContext() | ||
| 601 | + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) | ||
| 602 | + .emit("WeChat_Resp", map); | ||
| 603 | + } | ||
| 604 | + | ||
| 605 | + private interface ImageCallback { | ||
| 606 | + void invoke(@Nullable Bitmap bitmap); | ||
| 607 | + } | ||
| 608 | + | ||
| 609 | + private interface MediaObjectCallback { | ||
| 610 | + void invoke(@Nullable WXMediaMessage.IMediaObject mediaObject); | ||
| 611 | + } | ||
| 612 | + | ||
| 613 | +} |
| 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<NativeModule> createNativeModules(ReactApplicationContext reactContext) { | ||
| 19 | + return Arrays.asList(new NativeModule[]{ | ||
| 20 | + // Modules from third-party | ||
| 21 | + new WeChatModule(reactContext), | ||
| 22 | + }); | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + public List<Class<? extends JavaScriptModule>> createJSModules() { | ||
| 26 | + return Collections.emptyList(); | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + @Override | ||
| 30 | + public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { | ||
| 31 | + return Collections.emptyList(); | ||
| 32 | + } | ||
| 33 | +} |
| 1 | +package com.theweflex.react; | ||
| 2 | + | ||
| 3 | +import android.content.BroadcastReceiver; | ||
| 4 | +import android.content.Context; | ||
| 5 | +import android.content.Intent; | ||
| 6 | +import android.util.Log; | ||
| 7 | + | ||
| 8 | +import com.tencent.mm.opensdk.openapi.IWXAPI; | ||
| 9 | +import com.tencent.mm.opensdk.openapi.WXAPIFactory; | ||
| 10 | + | ||
| 11 | +public class WeChatRegister extends BroadcastReceiver { | ||
| 12 | + | ||
| 13 | + private static final String TAG = "WeChatRegister"; | ||
| 14 | + @Override | ||
| 15 | + public void onReceive(Context context, Intent intent) { | ||
| 16 | + Log.e(TAG, "onReceive: "); | ||
| 17 | + // final IWXAPI api = WXAPIFactory.createWXAPI(context, WeChatModule.appId); | ||
| 18 | + // api.registerApp(WeChatModule.appId); | ||
| 19 | + } | ||
| 20 | +} |
docs/build-setup-android.md
0 → 100644
| 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 | + compile project(':RCTWeChat') | ||
| 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; | ||
| 30 | + | ||
| 31 | +@Override | ||
| 32 | +protected List<ReactPackage> getPackages() { | ||
| 33 | + return Arrays.<ReactPackage>asList( | ||
| 34 | + new MainReactPackage(), | ||
| 35 | + new WeChatPackage() // Add this line | ||
| 36 | + ); | ||
| 37 | +} | ||
| 38 | +``` | ||
| 39 | + | ||
| 40 | +**Integrating with login and share** | ||
| 41 | + | ||
| 42 | +If you are going to integrate login or share functions, you need to | ||
| 43 | +create a package named 'wxapi' in your application package and a class | ||
| 44 | +named `WXEntryActivity` in it. | ||
| 45 | + | ||
| 46 | +```java | ||
| 47 | +package your.package.wxapi; | ||
| 48 | + | ||
| 49 | +import android.app.Activity; | ||
| 50 | +import android.os.Bundle; | ||
| 51 | +import com.theweflex.react.WeChatModule; | ||
| 52 | + | ||
| 53 | +public class WXEntryActivity extends Activity { | ||
| 54 | + @Override | ||
| 55 | + protected void onCreate(Bundle savedInstanceState) { | ||
| 56 | + super.onCreate(savedInstanceState); | ||
| 57 | + WeChatModule.handleIntent(getIntent()); | ||
| 58 | + finish(); | ||
| 59 | + } | ||
| 60 | +} | ||
| 61 | +``` | ||
| 62 | + | ||
| 63 | +Then add the following node to `AndroidManifest.xml`: | ||
| 64 | + | ||
| 65 | +```xml | ||
| 66 | +<manifest> | ||
| 67 | + <application> | ||
| 68 | + <activity | ||
| 69 | + android:name=".wxapi.WXEntryActivity" | ||
| 70 | + android:label="@string/app_name" | ||
| 71 | + android:exported="true" | ||
| 72 | + /> | ||
| 73 | + </application> | ||
| 74 | +</manifest> | ||
| 75 | +``` | ||
| 76 | + | ||
| 77 | +**Integrating the WeChat Payment** | ||
| 78 | + | ||
| 79 | +If you are going to integrate payment functionality by using this library, then | ||
| 80 | +create a package named also `wxapi` in your application package and a class named | ||
| 81 | +`WXPayEntryActivity`, this is used to bypass the response to JS level: | ||
| 82 | + | ||
| 83 | +```java | ||
| 84 | +package your.package.wxapi; | ||
| 85 | + | ||
| 86 | +import android.app.Activity; | ||
| 87 | +import android.os.Bundle; | ||
| 88 | +import com.theweflex.react.WeChatModule; | ||
| 89 | + | ||
| 90 | +public class WXPayEntryActivity extends Activity { | ||
| 91 | + @Override | ||
| 92 | + protected void onCreate(Bundle savedInstanceState) { | ||
| 93 | + super.onCreate(savedInstanceState); | ||
| 94 | + WeChatModule.handleIntent(getIntent()); | ||
| 95 | + finish(); | ||
| 96 | + } | ||
| 97 | +} | ||
| 98 | +``` | ||
| 99 | + | ||
| 100 | +Then add the following node to `AndroidManifest.xml`: | ||
| 101 | + | ||
| 102 | +```xml | ||
| 103 | +<manifest> | ||
| 104 | + <application> | ||
| 105 | + <activity | ||
| 106 | + android:name=".wxapi.WXPayEntryActivity" | ||
| 107 | + android:label="@string/app_name" | ||
| 108 | + android:exported="true" | ||
| 109 | + /> | ||
| 110 | + </application> | ||
| 111 | +</manifest> | ||
| 112 | +``` |
docs/build-setup-ios.md
0 → 100644
| 1 | +# Build Setup for iOS | ||
| 2 | + | ||
| 3 | +Add the following libraries to your "Link Binary with Libraries": | ||
| 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 | +<key>LSApplicationQueriesSchemes</key> | ||
| 22 | +<array> | ||
| 23 | + <string>weixin</string> | ||
| 24 | + <string>wechat</string> | ||
| 25 | +</array> | ||
| 26 | +``` | ||
| 27 | + | ||
| 28 | +Then copy the following in `AppDelegate.m`: | ||
| 29 | + | ||
| 30 | +```objc | ||
| 31 | +#import <React/RCTLinkingManager.h> | ||
| 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<NSString*, id> *)options | ||
| 44 | +{ | ||
| 45 | + return [RCTLinkingManager application:application openURL:url options:options]; | ||
| 46 | +} | ||
| 47 | + | ||
| 48 | + | ||
| 49 | +``` |
index.js
0 → 100644
| 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 nativeLaunchMini = wrapApi(WeChat.launchMini); | ||
| 146 | +const nativeShareToSession = wrapApi(WeChat.shareToSession); | ||
| 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 | + }); | ||
| 158 | + emitter.once('SendAuth.Resp', resp => { | ||
| 159 | + if (resp.errCode === 0) { | ||
| 160 | + resolve(resp); | ||
| 161 | + } else { | ||
| 162 | + reject(new WechatError(resp)); | ||
| 163 | + } | ||
| 164 | + }); | ||
| 165 | + }); | ||
| 166 | +} | ||
| 167 | + | ||
| 168 | +/** | ||
| 169 | + * Share something to timeline/moments/朋友圈 | ||
| 170 | + * @method shareToTimeline | ||
| 171 | + * @param {Object} data | ||
| 172 | + * @param {String} data.thumbImage - Thumb image of the message, which can be a uri or a resource id. | ||
| 173 | + * @param {String} data.type - Type of this message. Could be {news|text|imageUrl|imageFile|imageResource|video|audio|file|mini} | ||
| 174 | + * @param {String} data.webpageUrl - Required if type equals news or mini. The webpage link to share. | ||
| 175 | + * @param {String} data.userName - 小程序的原生id. | ||
| 176 | + * @param {String} data.path - 小程序页面的路径. | ||
| 177 | + * @param {String} data.hdImageData - 小程序节点高清大图,小于128k. | ||
| 178 | + * @param {Boolean} data.withShareTicket - 是否使用带 shareTicket 的转发 | ||
| 179 | + * @param {Integer} data.miniProgramType - 分享小程序的版本(0-正式,1-开发,2-体验) | ||
| 180 | + * @param {String} data.webpageUrl - Required if type equals news. The webpage link to share. | ||
| 181 | + * @param {String} data.webpageUrl - Required if type equals news. The webpage link to share. | ||
| 182 | + * @param {String} data.imageUrl - Provide a remote image if type equals image. | ||
| 183 | + * @param {String} data.videoUrl - Provide a remote video if type equals video. | ||
| 184 | + * @param {String} data.musicUrl - Provide a remote music if type equals audio. | ||
| 185 | + * @param {String} data.filePath - Provide a local file if type equals file. | ||
| 186 | + * @param {String} data.fileExtension - Provide the file type if type equals file. | ||
| 187 | + */ | ||
| 188 | +export function shareToTimeline(data) { | ||
| 189 | + return new Promise((resolve, reject) => { | ||
| 190 | + nativeShareToTimeline(data); | ||
| 191 | + emitter.once('SendMessageToWX.Resp', resp => { | ||
| 192 | + if (resp.errCode === 0) { | ||
| 193 | + resolve(resp); | ||
| 194 | + } else { | ||
| 195 | + reject(new WechatError(resp)); | ||
| 196 | + } | ||
| 197 | + }); | ||
| 198 | + }); | ||
| 199 | +} | ||
| 200 | + | ||
| 201 | +/** | ||
| 202 | + * 打开小程序 | ||
| 203 | + * @method launchMini | ||
| 204 | + * @param | ||
| 205 | + * @param {String} userName - 拉起的小程序的username | ||
| 206 | + * @param {Integer} miniProgramType - 拉起小程序的类型. 0-正式版 1-开发版 2-体验版 | ||
| 207 | + * @param {String} path - 拉起小程序页面的可带参路径,不填默认拉起小程序首页 | ||
| 208 | + */ | ||
| 209 | +export function launchMini({userName, miniProgramType = 0, path = ''}) { | ||
| 210 | + return new Promise((resolve, reject) => { | ||
| 211 | + if (miniProgramType !== 0 && miniProgramType !== 1 && miniProgramType !== 2) { | ||
| 212 | + reject(new WechatError({errStr: '拉起小程序的类型不对,0-正式版 1-开发版 2-体验版', errCode: -1})) | ||
| 213 | + return | ||
| 214 | + } | ||
| 215 | + nativeLaunchMini({userName, miniProgramType, path}); | ||
| 216 | + emitter.once('WXLaunchMiniProgramReq.Resp', resp => { | ||
| 217 | + if (resp.errCode === 0) { | ||
| 218 | + resolve(resp); | ||
| 219 | + } else { | ||
| 220 | + reject(new WechatError(resp)); | ||
| 221 | + } | ||
| 222 | + }); | ||
| 223 | + }); | ||
| 224 | +} | ||
| 225 | + | ||
| 226 | +/** | ||
| 227 | + * Share something to a friend or group | ||
| 228 | + * @method shareToSession | ||
| 229 | + * @param {Object} data | ||
| 230 | + * @param {String} data.thumbImage - Thumb image of the message, which can be a uri or a resource id. | ||
| 231 | + * @param {String} data.type - Type of this message. Could be {news|text|imageUrl|imageFile|imageResource|video|audio|file} | ||
| 232 | + * @param {String} data.webpageUrl - Required if type equals news. The webpage link to share. | ||
| 233 | + * @param {String} data.userName - 小程序的原生id. | ||
| 234 | + * @param {String} data.path - 小程序页面的路径. | ||
| 235 | + * @param {String} data.hdImageData - 小程序节点高清大图,小于128k. | ||
| 236 | + * @param {Boolean} data.withShareTicket - 是否使用带 shareTicket 的转发 | ||
| 237 | + * @param {Integer} data.miniProgramType - 分享小程序的版本(0-正式,1-开发,2-体验) | ||
| 238 | + * @param {String} data.imageUrl - Provide a remote image if type equals image. | ||
| 239 | + * @param {String} data.videoUrl - Provide a remote video if type equals video. | ||
| 240 | + * @param {String} data.musicUrl - Provide a remote music if type equals audio. | ||
| 241 | + * @param {String} data.filePath - Provide a local file if type equals file. | ||
| 242 | + * @param {String} data.fileExtension - Provide the file type if type equals file. | ||
| 243 | + */ | ||
| 244 | +export function shareToSession(data) { | ||
| 245 | + return new Promise((resolve, reject) => { | ||
| 246 | + nativeShareToSession(data); | ||
| 247 | + emitter.once('SendMessageToWX.Resp', resp => { | ||
| 248 | + if (resp.errCode === 0) { | ||
| 249 | + resolve(resp); | ||
| 250 | + } else { | ||
| 251 | + reject(new WechatError(resp)); | ||
| 252 | + } | ||
| 253 | + }); | ||
| 254 | + }); | ||
| 255 | +} | ||
| 256 | + | ||
| 257 | +/** | ||
| 258 | + * wechat pay | ||
| 259 | + * @param {Object} data | ||
| 260 | + * @param {String} data.partnerId | ||
| 261 | + * @param {String} data.prepayId | ||
| 262 | + * @param {String} data.nonceStr | ||
| 263 | + * @param {String} data.timeStamp | ||
| 264 | + * @param {String} data.package | ||
| 265 | + * @param {String} data.sign | ||
| 266 | + * @returns {Promise} | ||
| 267 | + */ | ||
| 268 | +export function pay(data) { | ||
| 269 | + // FIXME(Yorkie): see https://github.com/yorkie/react-native-wechat/issues/203 | ||
| 270 | + // Here the server-side returns params in lowercase, but here SDK requires timeStamp | ||
| 271 | + // for compatibility, we make this correction for users. | ||
| 272 | + function correct(actual, fixed) { | ||
| 273 | + if (!data[fixed] && data[actual]) { | ||
| 274 | + data[fixed] = data[actual]; | ||
| 275 | + delete data[actual]; | ||
| 276 | + } | ||
| 277 | + } | ||
| 278 | + | ||
| 279 | + correct('prepayid', 'prepayId'); | ||
| 280 | + correct('noncestr', 'nonceStr'); | ||
| 281 | + correct('partnerid', 'partnerId'); | ||
| 282 | + correct('timestamp', 'timeStamp'); | ||
| 283 | + | ||
| 284 | + return new Promise((resolve, reject) => { | ||
| 285 | + WeChat.pay(data, result => { | ||
| 286 | + if (result) reject(result); | ||
| 287 | + }); | ||
| 288 | + emitter.once('PayReq.Resp', resp => { | ||
| 289 | + if (resp.errCode === 0) { | ||
| 290 | + resolve(resp); | ||
| 291 | + } else { | ||
| 292 | + reject(new WechatError(resp)); | ||
| 293 | + } | ||
| 294 | + }); | ||
| 295 | + }); | ||
| 296 | +} | ||
| 297 | + | ||
| 298 | +/** | ||
| 299 | + * promises will reject with this error when API call finish with an errCode other than zero. | ||
| 300 | + */ | ||
| 301 | +export class WechatError extends Error { | ||
| 302 | + constructor(resp) { | ||
| 303 | + const message = resp.errStr || resp.errCode.toString(); | ||
| 304 | + super(message); | ||
| 305 | + this.name = 'WechatError'; | ||
| 306 | + this.code = resp.errCode; | ||
| 307 | + | ||
| 308 | + // avoid babel's limition about extending Error class | ||
| 309 | + // https://github.com/babel/babel/issues/3083 | ||
| 310 | + if (typeof Object.setPrototypeOf === 'function') { | ||
| 311 | + Object.setPrototypeOf(this, WechatError.prototype); | ||
| 312 | + } else { | ||
| 313 | + this.__proto__ = WechatError.prototype; | ||
| 314 | + } | ||
| 315 | + } | ||
| 316 | +} | ||
| 317 | + |
ios/RCTWeChat.h
0 → 100644
| 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 <Foundation/Foundation.h> | ||
| 10 | +#import <UIKit/UIKit.h> | ||
| 11 | + | ||
| 12 | +#import <React/RCTBridgeModule.h> | ||
| 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 | +#define RCTWXShareTypeMini @"mini" | ||
| 26 | + | ||
| 27 | +#define RCTWXShareType @"type" | ||
| 28 | +#define RCTWXShareTitle @"title" | ||
| 29 | +#define RCTWXShareDescription @"description" | ||
| 30 | +#define RCTWXShareWebpageUrl @"webpageUrl" | ||
| 31 | +#define RCTWXShareImageUrl @"imageUrl" | ||
| 32 | + | ||
| 33 | +#define RCTWXEventName @"WeChat_Resp" | ||
| 34 | + | ||
| 35 | +@interface RCTWeChat : NSObject <RCTBridgeModule, WXApiDelegate> | ||
| 36 | + | ||
| 37 | +@property NSString* appId; | ||
| 38 | + | ||
| 39 | +@end |
ios/RCTWeChat.m
0 → 100644
| 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 <React/RCTEventDispatcher.h> | ||
| 12 | +#import <React/RCTBridge.h> | ||
| 13 | +#import <React/RCTLog.h> | ||
| 14 | +#import <React/RCTImageLoader.h> | ||
| 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(isWXAppInstalled:(RCTResponseSenderBlock)callback) | ||
| 70 | +{ | ||
| 71 | + callback(@[[NSNull null], @([WXApi isWXAppInstalled])]); | ||
| 72 | +} | ||
| 73 | + | ||
| 74 | +RCT_EXPORT_METHOD(isWXAppSupportApi:(RCTResponseSenderBlock)callback) | ||
| 75 | +{ | ||
| 76 | + callback(@[[NSNull null], @([WXApi isWXAppSupportApi])]); | ||
| 77 | +} | ||
| 78 | + | ||
| 79 | +RCT_EXPORT_METHOD(getWXAppInstallUrl:(RCTResponseSenderBlock)callback) | ||
| 80 | +{ | ||
| 81 | + callback(@[[NSNull null], [WXApi getWXAppInstallUrl]]); | ||
| 82 | +} | ||
| 83 | + | ||
| 84 | +RCT_EXPORT_METHOD(getApiVersion:(RCTResponseSenderBlock)callback) | ||
| 85 | +{ | ||
| 86 | + callback(@[[NSNull null], [WXApi getApiVersion]]); | ||
| 87 | +} | ||
| 88 | + | ||
| 89 | +RCT_EXPORT_METHOD(openWXApp:(RCTResponseSenderBlock)callback) | ||
| 90 | +{ | ||
| 91 | + callback(@[([WXApi openWXApp] ? [NSNull null] : INVOKE_FAILED)]); | ||
| 92 | +} | ||
| 93 | + | ||
| 94 | +RCT_EXPORT_METHOD(sendRequest:(NSString *)openid | ||
| 95 | + :(RCTResponseSenderBlock)callback) | ||
| 96 | +{ | ||
| 97 | + BaseReq* req = [[BaseReq alloc] init]; | ||
| 98 | + req.openID = openid; | ||
| 99 | + callback(@[[WXApi sendReq:req] ? [NSNull null] : INVOKE_FAILED]); | ||
| 100 | +} | ||
| 101 | + | ||
| 102 | +RCT_EXPORT_METHOD(sendAuthRequest:(NSString *)scope | ||
| 103 | + :(NSString *)state | ||
| 104 | + :(RCTResponseSenderBlock)callback) | ||
| 105 | +{ | ||
| 106 | + SendAuthReq* req = [[SendAuthReq alloc] init]; | ||
| 107 | + req.scope = scope; | ||
| 108 | + req.state = state; | ||
| 109 | + BOOL success = [WXApi sendReq:req]; | ||
| 110 | + callback(@[success ? [NSNull null] : INVOKE_FAILED]); | ||
| 111 | +} | ||
| 112 | + | ||
| 113 | +RCT_EXPORT_METHOD(sendSuccessResponse:(RCTResponseSenderBlock)callback) | ||
| 114 | +{ | ||
| 115 | + BaseResp* resp = [[BaseResp alloc] init]; | ||
| 116 | + resp.errCode = WXSuccess; | ||
| 117 | + callback(@[[WXApi sendResp:resp] ? [NSNull null] : INVOKE_FAILED]); | ||
| 118 | +} | ||
| 119 | + | ||
| 120 | +RCT_EXPORT_METHOD(sendErrorCommonResponse:(NSString *)message | ||
| 121 | + :(RCTResponseSenderBlock)callback) | ||
| 122 | +{ | ||
| 123 | + BaseResp* resp = [[BaseResp alloc] init]; | ||
| 124 | + resp.errCode = WXErrCodeCommon; | ||
| 125 | + resp.errStr = message; | ||
| 126 | + callback(@[[WXApi sendResp:resp] ? [NSNull null] : INVOKE_FAILED]); | ||
| 127 | +} | ||
| 128 | + | ||
| 129 | +RCT_EXPORT_METHOD(sendErrorUserCancelResponse:(NSString *)message | ||
| 130 | + :(RCTResponseSenderBlock)callback) | ||
| 131 | +{ | ||
| 132 | + BaseResp* resp = [[BaseResp alloc] init]; | ||
| 133 | + resp.errCode = WXErrCodeUserCancel; | ||
| 134 | + resp.errStr = message; | ||
| 135 | + callback(@[[WXApi sendResp:resp] ? [NSNull null] : INVOKE_FAILED]); | ||
| 136 | +} | ||
| 137 | + | ||
| 138 | +RCT_EXPORT_METHOD(shareToTimeline:(NSDictionary *)data | ||
| 139 | + :(RCTResponseSenderBlock)callback) | ||
| 140 | +{ | ||
| 141 | + [self shareToWeixinWithData:data scene:WXSceneTimeline callback:callback]; | ||
| 142 | +} | ||
| 143 | + | ||
| 144 | +RCT_EXPORT_METHOD(shareToSession:(NSDictionary *)data | ||
| 145 | + :(RCTResponseSenderBlock)callback) | ||
| 146 | +{ | ||
| 147 | + [self shareToWeixinWithData:data scene:WXSceneSession callback:callback]; | ||
| 148 | +} | ||
| 149 | +RCT_EXPORT_METHOD(launchMini:(NSDictionary *)data | ||
| 150 | + :(RCTResponseSenderBlock)callback) | ||
| 151 | +{ | ||
| 152 | + WXLaunchMiniProgramReq *launchMiniProgramReq = [WXLaunchMiniProgramReq object]; | ||
| 153 | + launchMiniProgramReq.userName = data[@"userName"]; //拉起的小程序的username | ||
| 154 | + launchMiniProgramReq.path = data[@"path"]; //拉起小程序页面的可带参路径,不填默认拉起小程序首页 | ||
| 155 | + //拉起小程序的类型 | ||
| 156 | + launchMiniProgramReq.miniProgramType = [data[@"miniProgramType"] integerValue]; | ||
| 157 | + BOOL success = [WXApi sendReq:launchMiniProgramReq]; | ||
| 158 | + callback(@[success ? [NSNull null] : INVOKE_FAILED]); | ||
| 159 | +} | ||
| 160 | + | ||
| 161 | +RCT_EXPORT_METHOD(pay:(NSDictionary *)data | ||
| 162 | + :(RCTResponseSenderBlock)callback) | ||
| 163 | +{ | ||
| 164 | + PayReq* req = [PayReq new]; | ||
| 165 | + req.partnerId = data[@"partnerId"]; | ||
| 166 | + req.prepayId = data[@"prepayId"]; | ||
| 167 | + req.nonceStr = data[@"nonceStr"]; | ||
| 168 | + req.timeStamp = [data[@"timeStamp"] unsignedIntValue]; | ||
| 169 | + req.package = data[@"package"]; | ||
| 170 | + req.sign = data[@"sign"]; | ||
| 171 | + BOOL success = [WXApi sendReq:req]; | ||
| 172 | + callback(@[success ? [NSNull null] : INVOKE_FAILED]); | ||
| 173 | +} | ||
| 174 | + | ||
| 175 | +- (void)shareToWeixinWithData:(NSDictionary *)aData | ||
| 176 | + thumbImage:(UIImage *)aThumbImage | ||
| 177 | + scene:(int)aScene | ||
| 178 | + callBack:(RCTResponseSenderBlock)callback | ||
| 179 | +{ | ||
| 180 | + NSString *type = aData[RCTWXShareType]; | ||
| 181 | + | ||
| 182 | + if ([type isEqualToString:RCTWXShareTypeText]) { | ||
| 183 | + NSString *text = aData[RCTWXShareDescription]; | ||
| 184 | + [self shareToWeixinWithTextMessage:aScene Text:text callBack:callback]; | ||
| 185 | + } else { | ||
| 186 | + NSString * title = aData[RCTWXShareTitle]; | ||
| 187 | + NSString * description = aData[RCTWXShareDescription]; | ||
| 188 | + NSString * mediaTagName = aData[@"mediaTagName"]; | ||
| 189 | + NSString * messageAction = aData[@"messageAction"]; | ||
| 190 | + NSString * messageExt = aData[@"messageExt"]; | ||
| 191 | + | ||
| 192 | + if (type.length <= 0 || [type isEqualToString:RCTWXShareTypeNews]) { | ||
| 193 | + NSString * webpageUrl = aData[RCTWXShareWebpageUrl]; | ||
| 194 | + if (webpageUrl.length <= 0) { | ||
| 195 | + callback(@[@"webpageUrl required"]); | ||
| 196 | + return; | ||
| 197 | + } | ||
| 198 | + | ||
| 199 | + WXWebpageObject* webpageObject = [WXWebpageObject object]; | ||
| 200 | + webpageObject.webpageUrl = webpageUrl; | ||
| 201 | + | ||
| 202 | + [self shareToWeixinWithMediaMessage:aScene | ||
| 203 | + Title:title | ||
| 204 | + Description:description | ||
| 205 | + Object:webpageObject | ||
| 206 | + MessageExt:messageExt | ||
| 207 | + MessageAction:messageAction | ||
| 208 | + ThumbImage:aThumbImage | ||
| 209 | + MediaTag:mediaTagName | ||
| 210 | + callBack:callback]; | ||
| 211 | + | ||
| 212 | + } else if ([type isEqualToString:RCTWXShareTypeAudio]) { | ||
| 213 | + WXMusicObject *musicObject = [WXMusicObject new]; | ||
| 214 | + musicObject.musicUrl = aData[@"musicUrl"]; | ||
| 215 | + musicObject.musicLowBandUrl = aData[@"musicLowBandUrl"]; | ||
| 216 | + musicObject.musicDataUrl = aData[@"musicDataUrl"]; | ||
| 217 | + musicObject.musicLowBandDataUrl = aData[@"musicLowBandDataUrl"]; | ||
| 218 | + | ||
| 219 | + [self shareToWeixinWithMediaMessage:aScene | ||
| 220 | + Title:title | ||
| 221 | + Description:description | ||
| 222 | + Object:musicObject | ||
| 223 | + MessageExt:messageExt | ||
| 224 | + MessageAction:messageAction | ||
| 225 | + ThumbImage:aThumbImage | ||
| 226 | + MediaTag:mediaTagName | ||
| 227 | + callBack:callback]; | ||
| 228 | + | ||
| 229 | + } else if ([type isEqualToString:RCTWXShareTypeVideo]) { | ||
| 230 | + WXVideoObject *videoObject = [WXVideoObject new]; | ||
| 231 | + videoObject.videoUrl = aData[@"videoUrl"]; | ||
| 232 | + videoObject.videoLowBandUrl = aData[@"videoLowBandUrl"]; | ||
| 233 | + | ||
| 234 | + [self shareToWeixinWithMediaMessage:aScene | ||
| 235 | + Title:title | ||
| 236 | + Description:description | ||
| 237 | + Object:videoObject | ||
| 238 | + MessageExt:messageExt | ||
| 239 | + MessageAction:messageAction | ||
| 240 | + ThumbImage:aThumbImage | ||
| 241 | + MediaTag:mediaTagName | ||
| 242 | + callBack:callback]; | ||
| 243 | + | ||
| 244 | + } else if ([type isEqualToString:RCTWXShareTypeImageUrl] || | ||
| 245 | + [type isEqualToString:RCTWXShareTypeImageFile] || | ||
| 246 | + [type isEqualToString:RCTWXShareTypeImageResource]) { | ||
| 247 | + NSURL *url = [NSURL URLWithString:aData[RCTWXShareImageUrl]]; | ||
| 248 | + NSURLRequest *imageRequest = [NSURLRequest requestWithURL:url]; | ||
| 249 | + [self.bridge.imageLoader loadImageWithURLRequest:imageRequest callback:^(NSError *error, UIImage *image) { | ||
| 250 | + if (image == nil){ | ||
| 251 | + callback(@[@"fail to load image resource"]); | ||
| 252 | + } else { | ||
| 253 | + WXImageObject *imageObject = [WXImageObject object]; | ||
| 254 | + imageObject.imageData = UIImagePNGRepresentation(image); | ||
| 255 | + | ||
| 256 | + [self shareToWeixinWithMediaMessage:aScene | ||
| 257 | + Title:title | ||
| 258 | + Description:description | ||
| 259 | + Object:imageObject | ||
| 260 | + MessageExt:messageExt | ||
| 261 | + MessageAction:messageAction | ||
| 262 | + ThumbImage:aThumbImage | ||
| 263 | + MediaTag:mediaTagName | ||
| 264 | + callBack:callback]; | ||
| 265 | + | ||
| 266 | + } | ||
| 267 | + }]; | ||
| 268 | + } else if ([type isEqualToString:RCTWXShareTypeFile]) { | ||
| 269 | + NSString * filePath = aData[@"filePath"]; | ||
| 270 | + NSString * fileExtension = aData[@"fileExtension"]; | ||
| 271 | + | ||
| 272 | + WXFileObject *fileObject = [WXFileObject object]; | ||
| 273 | + fileObject.fileData = [NSData dataWithContentsOfFile:filePath]; | ||
| 274 | + fileObject.fileExtension = fileExtension; | ||
| 275 | + | ||
| 276 | + [self shareToWeixinWithMediaMessage:aScene | ||
| 277 | + Title:title | ||
| 278 | + Description:description | ||
| 279 | + Object:fileObject | ||
| 280 | + MessageExt:messageExt | ||
| 281 | + MessageAction:messageAction | ||
| 282 | + ThumbImage:aThumbImage | ||
| 283 | + MediaTag:mediaTagName | ||
| 284 | + callBack:callback]; | ||
| 285 | + | ||
| 286 | + } else if ([type isEqualToString:RCTWXShareTypeMini]) { | ||
| 287 | + | ||
| 288 | + WXMiniProgramObject *miniObject = [WXMiniProgramObject object]; | ||
| 289 | + miniObject.webpageUrl = aData[@"webpageUrl"]; | ||
| 290 | + miniObject.userName = aData[@"userName"]; | ||
| 291 | + miniObject.path = aData[@"path"]; | ||
| 292 | + miniObject.withShareTicket = [aData[@"withShareTicket"] boolValue]; | ||
| 293 | + miniObject.miniProgramType = [aData[@"miniProgramType"] integerValue]; | ||
| 294 | + miniObject.hdImageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:aData[@"hdImageData"]]] ; | ||
| 295 | + | ||
| 296 | + [self shareToWeixinWithMediaMessage:aScene | ||
| 297 | + Title:title | ||
| 298 | + Description:description | ||
| 299 | + Object:miniObject | ||
| 300 | + MessageExt:messageExt | ||
| 301 | + MessageAction:messageAction | ||
| 302 | + ThumbImage:aThumbImage | ||
| 303 | + MediaTag:mediaTagName | ||
| 304 | + callBack:callback]; | ||
| 305 | + | ||
| 306 | + } else { | ||
| 307 | + callback(@[@"message type unsupported"]); | ||
| 308 | + } | ||
| 309 | + } | ||
| 310 | +} | ||
| 311 | + | ||
| 312 | + | ||
| 313 | +- (void)shareToWeixinWithData:(NSDictionary *)aData scene:(int)aScene callback:(RCTResponseSenderBlock)aCallBack | ||
| 314 | +{ | ||
| 315 | + NSString *imageUrl = aData[RCTWXShareTypeThumbImageUrl]; | ||
| 316 | + if (imageUrl.length && _bridge.imageLoader) { | ||
| 317 | + NSURL *url = [NSURL URLWithString:imageUrl]; | ||
| 318 | + NSURLRequest *imageRequest = [NSURLRequest requestWithURL:url]; | ||
| 319 | + [_bridge.imageLoader loadImageWithURLRequest:imageRequest size:CGSizeMake(100, 100) scale:1 clipped:FALSE resizeMode:RCTResizeModeStretch progressBlock:nil partialLoadBlock:nil | ||
| 320 | + completionBlock:^(NSError *error, UIImage *image) { | ||
| 321 | + [self shareToWeixinWithData:aData thumbImage:image scene:aScene callBack:aCallBack]; | ||
| 322 | + }]; | ||
| 323 | + } else { | ||
| 324 | + [self shareToWeixinWithData:aData thumbImage:nil scene:aScene callBack:aCallBack]; | ||
| 325 | + } | ||
| 326 | + | ||
| 327 | +} | ||
| 328 | + | ||
| 329 | +- (void)shareToWeixinWithTextMessage:(int)aScene | ||
| 330 | + Text:(NSString *)text | ||
| 331 | + callBack:(RCTResponseSenderBlock)callback | ||
| 332 | +{ | ||
| 333 | + SendMessageToWXReq* req = [SendMessageToWXReq new]; | ||
| 334 | + req.bText = YES; | ||
| 335 | + req.scene = aScene; | ||
| 336 | + req.text = text; | ||
| 337 | + | ||
| 338 | + BOOL success = [WXApi sendReq:req]; | ||
| 339 | + callback(@[success ? [NSNull null] : INVOKE_FAILED]); | ||
| 340 | +} | ||
| 341 | + | ||
| 342 | +- (void)shareToWeixinWithMediaMessage:(int)aScene | ||
| 343 | + Title:(NSString *)title | ||
| 344 | + Description:(NSString *)description | ||
| 345 | + Object:(id)mediaObject | ||
| 346 | + MessageExt:(NSString *)messageExt | ||
| 347 | + MessageAction:(NSString *)action | ||
| 348 | + ThumbImage:(UIImage *)thumbImage | ||
| 349 | + MediaTag:(NSString *)tagName | ||
| 350 | + callBack:(RCTResponseSenderBlock)callback | ||
| 351 | +{ | ||
| 352 | + WXMediaMessage *message = [WXMediaMessage message]; | ||
| 353 | + message.title = title; | ||
| 354 | + message.description = description; | ||
| 355 | + message.mediaObject = mediaObject; | ||
| 356 | + message.messageExt = messageExt; | ||
| 357 | + message.messageAction = action; | ||
| 358 | + message.mediaTagName = tagName; | ||
| 359 | + [message setThumbImage:thumbImage]; | ||
| 360 | + | ||
| 361 | + SendMessageToWXReq* req = [SendMessageToWXReq new]; | ||
| 362 | + req.bText = NO; | ||
| 363 | + req.scene = aScene; | ||
| 364 | + req.message = message; | ||
| 365 | + | ||
| 366 | + BOOL success = [WXApi sendReq:req]; | ||
| 367 | + callback(@[success ? [NSNull null] : INVOKE_FAILED]); | ||
| 368 | +} | ||
| 369 | + | ||
| 370 | +#pragma mark - wx callback | ||
| 371 | + | ||
| 372 | +-(void) onReq:(BaseReq*)req | ||
| 373 | +{ | ||
| 374 | + // TODO(Yorkie) | ||
| 375 | +} | ||
| 376 | + | ||
| 377 | +-(void) onResp:(BaseResp*)resp | ||
| 378 | +{ | ||
| 379 | + if([resp isKindOfClass:[SendMessageToWXResp class]]) | ||
| 380 | + { | ||
| 381 | + SendMessageToWXResp *r = (SendMessageToWXResp *)resp; | ||
| 382 | + | ||
| 383 | + NSMutableDictionary *body = @{@"errCode":@(r.errCode)}.mutableCopy; | ||
| 384 | + body[@"errStr"] = r.errStr; | ||
| 385 | + body[@"lang"] = r.lang; | ||
| 386 | + body[@"country"] =r.country; | ||
| 387 | + body[@"type"] = @"SendMessageToWX.Resp"; | ||
| 388 | + [self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body]; | ||
| 389 | + } else if ([resp isKindOfClass:[SendAuthResp class]]) { | ||
| 390 | + SendAuthResp *r = (SendAuthResp *)resp; | ||
| 391 | + NSMutableDictionary *body = @{@"errCode":@(r.errCode)}.mutableCopy; | ||
| 392 | + body[@"errStr"] = r.errStr; | ||
| 393 | + body[@"state"] = r.state; | ||
| 394 | + body[@"lang"] = r.lang; | ||
| 395 | + body[@"country"] =r.country; | ||
| 396 | + body[@"type"] = @"SendAuth.Resp"; | ||
| 397 | + | ||
| 398 | + if (resp.errCode == WXSuccess) | ||
| 399 | + { | ||
| 400 | + [body addEntriesFromDictionary:@{@"appid":self.appId, @"code" :r.code}]; | ||
| 401 | + [self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body]; | ||
| 402 | + } | ||
| 403 | + else { | ||
| 404 | + [self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body]; | ||
| 405 | + } | ||
| 406 | + } else if ([resp isKindOfClass:[PayResp class]]) { | ||
| 407 | + PayResp *r = (PayResp *)resp; | ||
| 408 | + NSMutableDictionary *body = @{@"errCode":@(r.errCode)}.mutableCopy; | ||
| 409 | + body[@"errStr"] = r.errStr; | ||
| 410 | + body[@"type"] = @(r.type); | ||
| 411 | + body[@"returnKey"] =r.returnKey; | ||
| 412 | + body[@"type"] = @"PayReq.Resp"; | ||
| 413 | + [self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body]; | ||
| 414 | + }else if ([resp isKindOfClass:[WXLaunchMiniProgramResp class]]) | ||
| 415 | + { | ||
| 416 | + WXLaunchMiniProgramResp *r = (WXLaunchMiniProgramResp *)resp; | ||
| 417 | + NSMutableDictionary *body = @{@"errCode":@(r.errCode)}.mutableCopy; | ||
| 418 | + body[@"errStr"] = r.errStr; | ||
| 419 | + body[@"extMsg"] = r.extMsg; | ||
| 420 | + body[@"type"] = @"WXLaunchMiniProgramReq.Resp"; | ||
| 421 | + [self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body]; | ||
| 422 | + } | ||
| 423 | +} | ||
| 424 | + | ||
| 425 | +@end |
ios/RCTWeChat.podspec
0 → 100644
| 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 |
-
请 注册 或 登录 后发表评论