├── .gitignore ├── README.md ├── android ├── .gitignore ├── .npmignore ├── android.iml ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── libs │ └── core-4.3.1-openDefaultRelease.aar ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── cn │ │ └── reactnative │ │ └── modules │ │ └── weibo │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── cn │ │ │ └── reactnative │ │ │ └── modules │ │ │ └── weibo │ │ │ ├── WeiboModule.java │ │ │ └── WeiboPackage.java │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── cn │ └── reactnative │ └── modules │ └── weibo │ └── ExampleUnitTest.java ├── index.js ├── ios ├── RCTWeiboAPI.xcodeproj │ ├── project.pbxproj │ └── xcuserdata │ │ └── lvbingru.xcuserdatad │ │ └── xcschemes │ │ └── RCTWeiboAPI.xcscheme ├── RCTWeiboAPI │ ├── RCTWeiboAPI.h │ └── RCTWeiboAPI.m └── libWeiboSDK │ ├── WBHttpRequest.h │ ├── WeiboSDK.bundle │ ├── images │ │ ├── common_button_white@2x.png │ │ ├── common_button_white_highlighted@2x.png │ │ └── empty_failed@2x.png │ └── others │ │ └── mfp.cer │ ├── WeiboSDK.h │ └── libWeiboSDK.a └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .gradle 3 | local.properties -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rn-weibo 2 | React Native的新浪微博登录分享插件 3 | 4 | 本仓库fork自[reactnativecn/react-native-weibo](https://github.com/reactnativecn/react-native-weibo),但源仓库许久没维护了,故本人针对react-native和weiboSDK新版做了适配后npm发布了新包`rn-weibo`。 5 | 6 | ## 版本要求 7 | 8 | + 适配react-native版本0.57.5 9 | + weiboSDK的版本分别为ios 3.2.3和安卓端4.3.1 10 | 11 | ## 如何安装 12 | 13 | ### 1.首先安装npm包 14 | 15 | ```bash 16 | npm install rn-weibo --save 17 | ``` 18 | 19 | ### 2.link 20 | #### 自动link方法 21 | 22 | ```bash 23 | react-native link 24 | ``` 25 | 26 | #### 手动link~(如果不能够自动link) 27 | #####ios 28 | a.打开XCode's工程中, 右键点击Libraries文件夹 ➜ Add Files to <...> 29 | b.去node_modules ➜ react-native-weibo ➜ ios ➜ 选择 RCTWeiboAPI.xcodeproj 30 | c.在工程Build Phases ➜ Link Binary With Libraries中添加libRCTWeiboAPI.a 31 | 32 | #####Android 33 | 34 | ``` 35 | // file: android/settings.gradle 36 | ... 37 | 38 | include ':react-native-weibo' 39 | project(':react-native-weibo').projectDir = new File(settingsDir, '../node_modules/react-native-weibo/android') 40 | ``` 41 | 42 | ``` 43 | // file: android/app/build.gradle 44 | ... 45 | 46 | dependencies { 47 | ... 48 | compile project(':react-native-weibo') 49 | } 50 | ``` 51 | 52 | `android/app/src/main/java/<你的包名>/MainApplication.java`中添加如下两行: 53 | 54 | ```java 55 | ... 56 | import cn.reactnative.modules.weibo.WeiboPackage; // 在public class MainApplication之前import 57 | 58 | public class MainApplication extends Application implements ReactApplication { 59 | 60 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 61 | @Override 62 | protected boolean getUseDeveloperSupport() { 63 | return BuildConfig.DEBUG; 64 | } 65 | 66 | @Override 67 | protected List getPackages() { 68 | return Arrays.asList( 69 |          new WeiboPackage(), // 然后添加这一行 70 | new MainReactPackage() 71 | ); 72 | } 73 | }; 74 | 75 | @Override 76 | public ReactNativeHost getReactNativeHost() { 77 | return mReactNativeHost; 78 | } 79 | } 80 | ``` 81 | 82 | ### 3.工程配置 83 | #### ios配置 84 | 将`node_modules/react-native-weibo/ios/libWeiboSDK/WeiboSDK.bundle`加入到工程中(必须,很重要,不然登录的时候会crash) 85 | 86 | 在工程target的`Build Phases->Link Binary with Libraries`中加入`libRCTWeiboAPI.a、libsqlite3.tbd、libz.tbd、ImageIO.framework、SystemConfiguration.framework、Security.framework、CoreTelephony.framework、CoreText.framework` 87 | 88 | 89 | 在`Info->URL Types` 中增加QQ的scheme: `Identifier` 设置为`sina`, `URL Schemes` 设置为你注册的微博开发者账号中的APPID,需要加前缀`wb`,例如`wb1915346979` 90 | 91 | 在你工程的`AppDelegate.m`文件中添加如下代码: 92 | 93 | ``` 94 | #import "../Libraries/LinkingIOS/RCTLinkingManager.h" 95 | 96 | 97 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { 98 | return [RCTLinkingManager application:application openURL:url sourceApplication:sourceApplication annotation:annotation]; 99 | } 100 | 101 | ``` 102 | 103 | ##### iOS9的适配问题 104 | 105 | 由于iOS9的发布影响了微博SDK与应用的集成方式,为了确保好的应用体验,我们需要采取如下措施: 106 | ##### a.对传输安全的支持 107 | 在iOS9系统中,默认需要为每次网络传输建立SSL。解决这个问题: 108 | 109 | - 将NSAllowsArbitraryLoads属性设置为YES,并添加到你应用的plist中 110 | - 111 | NSAppTransportSecurity 112 | 113 | NSAllowsArbitraryLoads 114 | 115 | 116 | 117 | ###### b.对应用跳转的支持 118 | 如果你需要用到微博的相关功能,如登陆,分享等。并且需要实现跳转到微博的功能,在iOS9系统中就需要在你的app的plist中添加下列键值对。否则在canOpenURL函数执行时,就会返回NO。了解详情请至[https://developer.apple.com/videos/wwdc/2015/?id=703](https://developer.apple.com/videos/wwdc/2015/?id=703) 119 | 120 | - 121 | LSApplicationQueriesSchemes 122 | 123 | sinaweibohd 124 | sinaweibo 125 | weibosdk 126 | weibosdk2.5 127 | 128 | 129 | 130 | #### Android 131 | 132 | 在`android/app/build.gradle`里,defaultConfig栏目下添加如下代码: 133 | 134 | ``` 135 | manifestPlaceholders = [ 136 | WB_APPID: "微博的APPID" //在此修改微博APPID 137 | ] 138 | ``` 139 | 140 | 如果react-native版本<0.18.0,确保你的MainActivity.java中有`onActivityResult`的实现: 141 | 142 | ```java 143 | private ReactInstanceManager mReactInstanceManager; 144 | @Override 145 | public void onActivityResult(int requestCode, int resultCode, Intent data){ 146 | super.onActivityResult(requestCode, resultCode, data); 147 | mReactInstanceManager.onActivityResult(requestCode, resultCode, data); 148 | } 149 | ``` 150 | 151 | ## 如何使用 152 | 153 | ### 引入包 154 | 155 | ``` 156 | import * as WeiboAPI from 'react-native-weibo'; 157 | ``` 158 | 159 | ### API 160 | 161 | #### WeiboAPI.login(config) 162 | 163 | ```javascript 164 | // 登录参数 165 | config : { 166 | scope: 权限设置, // 默认 'all' 167 | redirectURI: 重定向地址, // 默认 'https://api.weibo.com/oauth2/default.html'(必须和sina微博开放平台中应用高级设置中的redirectURI设置的一致,不然会登录失败) 168 | } 169 | ``` 170 | 171 | 返回一个`Promise`对象。成功时的回调为一个类似这样的对象: 172 | 173 | ```javascript 174 | { 175 | "accessToken": "2.005e3HMBzh7eFCca6a3854060GQFJf", 176 | "userID": "1098604232" 177 | "expirationDate": "1452884401084.538" 178 | "refreshToken": "2.005e3HMBzh8eFC3db19a18bb00pvbp" 179 | } 180 | ``` 181 | 182 | #### WeiboAPI.share(data) 183 | 184 | 分享到微博 185 | 186 | ```javascript 187 | // 分享文字 188 | { 189 | type: 'text', 190 | text: 文字内容, 191 | } 192 | ``` 193 | 194 | ```javascript 195 | // 分享图片 196 | { 197 | type: 'image', 198 | text: 文字内容, 199 | imageUrl: 图片地址 200 | } 201 | ``` 202 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /android/.npmignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /android/android.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.1" 6 | 7 | defaultConfig { 8 | minSdkVersion 16 9 | targetSdkVersion 23 10 | versionCode 1 11 | versionName "1.0" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | sourceSets.main { 20 | jniLibs.srcDirs = ['libs'] 21 | } 22 | } 23 | 24 | dependencies { 25 | compile 'com.facebook.react:react-native:+' 26 | compile files('libs/core-4.3.1-openDefaultRelease.aar') 27 | } 28 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yun77op/react-native-weibo/ebbaf5d8a4748526475266ecf7cadd1ec63ab6e8/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 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 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /android/libs/core-4.3.1-openDefaultRelease.aar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yun77op/react-native-weibo/ebbaf5d8a4748526475266ecf7cadd1ec63ab6e8/android/libs/core-4.3.1-openDefaultRelease.aar -------------------------------------------------------------------------------- /android/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/lvbingru/Library/Android/sdk/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 | -------------------------------------------------------------------------------- /android/src/androidTest/java/cn/reactnative/modules/weibo/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package cn.reactnative.modules.weibo; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 17 | 18 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /android/src/main/java/cn/reactnative/modules/weibo/WeiboModule.java: -------------------------------------------------------------------------------- 1 | package cn.reactnative.modules.weibo; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.pm.ApplicationInfo; 7 | import android.content.pm.PackageManager; 8 | import android.graphics.Bitmap; 9 | import android.graphics.Canvas; 10 | import android.graphics.PixelFormat; 11 | import android.graphics.drawable.BitmapDrawable; 12 | import android.graphics.drawable.Drawable; 13 | import android.graphics.drawable.NinePatchDrawable; 14 | import android.net.Uri; 15 | import android.os.Bundle; 16 | import android.util.Log; 17 | 18 | import com.facebook.common.executors.UiThreadImmediateExecutorService; 19 | import com.facebook.common.internal.Preconditions; 20 | import com.facebook.common.references.CloseableReference; 21 | import com.facebook.common.util.UriUtil; 22 | import com.facebook.datasource.BaseDataSubscriber; 23 | import com.facebook.datasource.DataSource; 24 | import com.facebook.datasource.DataSubscriber; 25 | import com.facebook.drawee.backends.pipeline.Fresco; 26 | import com.facebook.drawee.drawable.OrientedDrawable; 27 | import com.facebook.imagepipeline.common.ResizeOptions; 28 | import com.facebook.imagepipeline.core.ImagePipeline; 29 | import com.facebook.imagepipeline.image.CloseableImage; 30 | import com.facebook.imagepipeline.image.CloseableStaticBitmap; 31 | import com.facebook.imagepipeline.image.EncodedImage; 32 | import com.facebook.imagepipeline.request.ImageRequest; 33 | import com.facebook.imagepipeline.request.ImageRequestBuilder; 34 | import com.facebook.react.bridge.ActivityEventListener; 35 | import com.facebook.react.bridge.Arguments; 36 | import com.facebook.react.bridge.Callback; 37 | import com.facebook.react.bridge.ReactApplicationContext; 38 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 39 | import com.facebook.react.bridge.ReactMethod; 40 | import com.facebook.react.bridge.ReadableMap; 41 | import com.facebook.react.bridge.WritableMap; 42 | import com.facebook.react.modules.core.DeviceEventManagerModule; 43 | import com.sina.weibo.sdk.api.ImageObject; 44 | import com.sina.weibo.sdk.api.TextObject; 45 | import com.sina.weibo.sdk.api.VideoSourceObject; 46 | import com.sina.weibo.sdk.api.WebpageObject; 47 | import com.sina.weibo.sdk.api.WeiboMultiMessage; 48 | import com.sina.weibo.sdk.auth.WbAuthListener; 49 | import com.sina.weibo.sdk.auth.AuthInfo; 50 | import com.sina.weibo.sdk.auth.Oauth2AccessToken; 51 | import com.sina.weibo.sdk.auth.sso.SsoHandler; 52 | import com.sina.weibo.sdk.auth.WbConnectErrorMessage; 53 | import com.sina.weibo.sdk.share.WbShareCallback; 54 | 55 | import com.sina.weibo.sdk.WbSdk; 56 | import com.sina.weibo.sdk.share.WbShareHandler; 57 | 58 | import java.util.Date; 59 | import javax.annotation.Nullable; 60 | 61 | /** 62 | * Created by lvbingru on 12/22/15. 63 | */ 64 | public class WeiboModule extends ReactContextBaseJavaModule implements ActivityEventListener, WbShareCallback { 65 | 66 | public WeiboModule(ReactApplicationContext reactContext) { 67 | super(reactContext); 68 | ApplicationInfo appInfo = null; 69 | try { 70 | appInfo = reactContext.getPackageManager().getApplicationInfo(reactContext.getPackageName(), PackageManager.GET_META_DATA); 71 | } catch (PackageManager.NameNotFoundException e) { 72 | throw new Error(e); 73 | } 74 | if (!appInfo.metaData.containsKey("WB_APPID")){ 75 | throw new Error("meta-data WB_APPID not found in AndroidManifest.xml"); 76 | } 77 | this.appId = appInfo.metaData.get("WB_APPID").toString(); 78 | } 79 | 80 | private static final String RCTWBEventName = "Weibo_Resp"; 81 | 82 | private SsoHandler mSsoHandler; 83 | private String appId; 84 | private boolean wbSdkInstalled = false; 85 | 86 | private WbShareHandler shareHandler; 87 | 88 | private static final String RCTWBShareTypeNews = "news"; 89 | private static final String RCTWBShareTypeImage = "image"; 90 | private static final String RCTWBShareTypeText = "text"; 91 | private static final String RCTWBShareTypeVideo = "video"; 92 | 93 | private static final String RCTWBShareType = "type"; 94 | private static final String RCTWBShareText = "text"; 95 | private static final String RCTWBShareTitle = "title"; 96 | private static final String RCTWBShareDescription = "description"; 97 | private static final String RCTWBShareWebpageUrl = "webpageUrl"; 98 | private static final String RCTWBSharePropVideoPath = "videoPath"; 99 | private static final String RCTWBShareImageUrl = "imageUrl"; 100 | private static final String RCTWBShareAccessToken = "accessToken"; 101 | 102 | private static WeiboModule gModule = null; 103 | 104 | @Override 105 | public void initialize() { 106 | super.initialize(); 107 | gModule = this; 108 | getReactApplicationContext().addActivityEventListener(this); 109 | } 110 | 111 | @Override 112 | public void onCatalystInstanceDestroy() { 113 | super.onCatalystInstanceDestroy(); 114 | gModule = null; 115 | getReactApplicationContext().removeActivityEventListener(this); 116 | } 117 | 118 | @Override 119 | public String getName() { 120 | return "RCTWeiboAPI"; 121 | } 122 | 123 | private WbShareHandler registerShare() { 124 | if (shareHandler == null) { 125 | shareHandler = new WbShareHandler(getCurrentActivity()); 126 | shareHandler.registerApp(); 127 | } 128 | return shareHandler; 129 | } 130 | 131 | private void _installWbSdk(final ReadableMap config) { 132 | if (!wbSdkInstalled) { 133 | AuthInfo sinaAuthInfo = this._genAuthInfo(config); 134 | WbSdk.install(getCurrentActivity(), sinaAuthInfo); 135 | wbSdkInstalled = true; 136 | } 137 | } 138 | 139 | 140 | @ReactMethod 141 | public void login(final ReadableMap config, final Callback callback){ 142 | 143 | this._installWbSdk(config); 144 | 145 | if (mSsoHandler == null) { 146 | mSsoHandler = new SsoHandler(getCurrentActivity()); 147 | mSsoHandler.authorize(this.genWeiboAuthListener()); 148 | } 149 | 150 | callback.invoke(); 151 | } 152 | 153 | @ReactMethod 154 | public void shareToWeibo(final ReadableMap data, Callback callback){ 155 | 156 | this._installWbSdk(data); 157 | 158 | if (data.hasKey(RCTWBShareImageUrl)) { 159 | String imageUrl = data.getString(RCTWBShareImageUrl); 160 | DataSubscriber> dataSubscriber = 161 | new BaseDataSubscriber>() { 162 | @Override 163 | public void onNewResultImpl(DataSource> dataSource) { 164 | // isFinished must be obtained before image, otherwise we might set intermediate result 165 | // as final image. 166 | boolean isFinished = dataSource.isFinished(); 167 | // float progress = dataSource.getProgress(); 168 | CloseableReference image = dataSource.getResult(); 169 | if (image != null) { 170 | Drawable drawable = _createDrawable(image); 171 | Bitmap bitmap = _drawable2Bitmap(drawable); 172 | _share(data, bitmap); 173 | } else if (isFinished) { 174 | _share(data, null); 175 | } 176 | dataSource.close(); 177 | } 178 | @Override 179 | public void onFailureImpl(DataSource> dataSource) { 180 | dataSource.close(); 181 | _share(data, null); 182 | } 183 | 184 | @Override 185 | public void onProgressUpdate(DataSource> dataSource) { 186 | } 187 | }; 188 | ResizeOptions resizeOptions = null; 189 | if (!data.hasKey(RCTWBShareType) || !data.getString(RCTWBShareType).equals(RCTWBShareTypeImage)) { 190 | resizeOptions = new ResizeOptions(80, 80); 191 | } 192 | 193 | this._downloadImage(imageUrl, resizeOptions, dataSubscriber); 194 | } 195 | else { 196 | this._share(data, null); 197 | } 198 | 199 | callback.invoke(); 200 | } 201 | 202 | public void onActivityResult(int requestCode, int resultCode, Intent data) { 203 | if (mSsoHandler != null) { 204 | mSsoHandler.authorizeCallBack(requestCode, resultCode, data); 205 | mSsoHandler = null; 206 | } 207 | } 208 | 209 | public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data){ 210 | this.onActivityResult(requestCode, resultCode, data); 211 | } 212 | 213 | public void onNewIntent(Intent intent){ 214 | 215 | } 216 | 217 | WbAuthListener genWeiboAuthListener() { 218 | return new WbAuthListener() { 219 | 220 | @Override 221 | public void onSuccess(final Oauth2AccessToken token) { 222 | WritableMap event = Arguments.createMap(); 223 | 224 | if (token.isSessionValid()) { 225 | event.putString("accessToken", token.getToken()); 226 | event.putDouble("expirationDate", token.getExpiresTime()); 227 | event.putString("userID", token.getUid()); 228 | event.putString("refreshToken", token.getRefreshToken()); 229 | event.putInt("errCode", 0); 230 | } else { 231 | // String code = bundle.getString("code", ""); 232 | event.putInt("errCode", -1); 233 | event.putString("errMsg", "token invalid"); 234 | } 235 | event.putString("type", "WBAuthorizeResponse"); 236 | getReactApplicationContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(RCTWBEventName, event); 237 | 238 | // WBAuthActivity.this.runOnUiThread(new Runnable() { 239 | // @Override 240 | // public void run() { 241 | // mAccessToken = token; 242 | // if (mAccessToken.isSessionValid()) { 243 | // // 显示 Token 244 | // updateTokenView(false); 245 | // // 保存 Token 到 SharedPreferences 246 | // AccessTokenKeeper.writeAccessToken(WBAuthActivity.this, mAccessToken); 247 | // Toast.makeText(WBAuthActivity.this, 248 | // R.string.weibosdk_demo_toast_auth_success, Toast.LENGTH_SHORT).show(); 249 | // } 250 | // } 251 | // }); 252 | } 253 | 254 | 255 | @Override 256 | public void onFailure(WbConnectErrorMessage e) { 257 | WritableMap event = Arguments.createMap(); 258 | event.putString("type", "WBAuthorizeResponse"); 259 | event.putString("errMsg", e.getErrorMessage()); 260 | event.putInt("errCode", -1); 261 | getReactApplicationContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(RCTWBEventName, event); 262 | } 263 | 264 | @Override 265 | public void cancel() { 266 | WritableMap event = Arguments.createMap(); 267 | event.putString("type", "WBAuthorizeResponse"); 268 | event.putString("errMsg", "Cancel"); 269 | event.putInt("errCode", -1); 270 | getReactApplicationContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(RCTWBEventName, event); 271 | } 272 | }; 273 | } 274 | 275 | private void _share(ReadableMap data, Bitmap bitmap) { 276 | 277 | this.registerShare(); 278 | WeiboMultiMessage weiboMessage = new WeiboMultiMessage();//初始化微博的分享消息 279 | TextObject textObject = new TextObject(); 280 | if (data.hasKey(RCTWBShareText)) { 281 | textObject.text = data.getString(RCTWBShareText); 282 | } 283 | weiboMessage.textObject = textObject; 284 | 285 | String type = RCTWBShareTypeNews; 286 | if (data.hasKey(RCTWBShareType)){ 287 | type = data.getString(RCTWBShareType); 288 | } 289 | 290 | if (type.equals(RCTWBShareTypeText)) { 291 | } 292 | else if (type.equals(RCTWBShareTypeImage)) { 293 | ImageObject imageObject = new ImageObject(); 294 | if (bitmap != null) { 295 | Log.e("share","hasBitmap"); 296 | imageObject.setImageObject(bitmap); 297 | } 298 | weiboMessage.imageObject = imageObject; 299 | } 300 | else { 301 | if (type.equals(RCTWBShareTypeNews)) { 302 | WebpageObject webpageObject = new WebpageObject(); 303 | if (data.hasKey(RCTWBShareWebpageUrl)) { 304 | webpageObject.actionUrl = data.getString(RCTWBShareWebpageUrl); 305 | } 306 | weiboMessage.mediaObject = webpageObject; 307 | } 308 | else if (type.equals(RCTWBShareTypeVideo)) { 309 | VideoSourceObject videoObject = new VideoSourceObject(); 310 | // if (data.hasKey(RCTWBShareWebpageUrl)) { 311 | // videoObject.dataUrl = data.getString(RCTWBShareWebpageUrl); 312 | // } 313 | 314 | // videoObject.videoPath = data.getString(RCTWBSharePropVideoPath); 315 | weiboMessage.mediaObject = videoObject; 316 | } 317 | if (data.hasKey(RCTWBShareDescription)) { 318 | weiboMessage.mediaObject.description = data.getString(RCTWBShareDescription); 319 | } 320 | if (data.hasKey(RCTWBShareTitle)) { 321 | weiboMessage.mediaObject.title = data.getString(RCTWBShareTitle); 322 | } 323 | if (bitmap != null) { 324 | weiboMessage.mediaObject.setThumbImage(bitmap); 325 | } 326 | weiboMessage.mediaObject.identify = new Date().toString(); 327 | } 328 | 329 | shareHandler.shareMessage(weiboMessage, false); 330 | } 331 | 332 | 333 | @Override 334 | public void onWbShareSuccess() { 335 | WritableMap event = Arguments.createMap(); 336 | event.putString("type", "WBSendMessageToWeiboResponse"); 337 | event.putInt("errCode", 0); 338 | 339 | getReactApplicationContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(RCTWBEventName, event); 340 | } 341 | 342 | @Override 343 | public void onWbShareFail() { 344 | WritableMap map = Arguments.createMap(); 345 | map.putInt("errCode", -1); 346 | map.putString("errMsg", "分享失败"); 347 | map.putString("type", "WBSendMessageToWeiboResponse"); 348 | getReactApplicationContext() 349 | .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 350 | .emit(RCTWBEventName, map); 351 | } 352 | 353 | @Override 354 | public void onWbShareCancel() { 355 | WritableMap map = Arguments.createMap(); 356 | map.putInt("errCode", -1); 357 | map.putString("errMsg", "分享取消"); 358 | map.putString("type", "WBSendMessageToWeiboResponse"); 359 | getReactApplicationContext() 360 | .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 361 | .emit(RCTWBEventName, map); 362 | } 363 | 364 | private AuthInfo _genAuthInfo(ReadableMap config) { 365 | String redirectURI = ""; 366 | if (config.hasKey("redirectURI")) { 367 | redirectURI = config.getString("redirectURI"); 368 | } 369 | String scope = ""; 370 | if (config.hasKey("scope")) { 371 | scope = config.getString("scope"); 372 | } 373 | 374 | final AuthInfo sinaAuthInfo = new AuthInfo(getReactApplicationContext(), this.appId, redirectURI, scope); 375 | return sinaAuthInfo; 376 | } 377 | 378 | private void _downloadImage(String imageUrl, ResizeOptions resizeOptions,DataSubscriber> dataSubscriber) { 379 | Uri uri = null; 380 | try { 381 | uri = Uri.parse(imageUrl); 382 | // Verify scheme is set, so that relative uri (used by static resources) are not handled. 383 | if (uri.getScheme() == null) { 384 | uri = null; 385 | } 386 | } catch (Exception e) { 387 | // ignore malformed uri, then attempt to extract resource ID. 388 | } 389 | if (uri == null) { 390 | uri = _getResourceDrawableUri(getReactApplicationContext(), imageUrl); 391 | } else { 392 | } 393 | 394 | ImageRequestBuilder builder = ImageRequestBuilder.newBuilderWithSource(uri); 395 | if (resizeOptions != null) { 396 | builder.setResizeOptions(resizeOptions); 397 | } 398 | ImageRequest imageRequest = builder.build(); 399 | 400 | ImagePipeline imagePipeline = Fresco.getImagePipeline(); 401 | DataSource> dataSource = imagePipeline.fetchDecodedImage(imageRequest, null); 402 | dataSource.subscribe(dataSubscriber, UiThreadImmediateExecutorService.getInstance()); 403 | } 404 | 405 | private static @Nullable 406 | Uri _getResourceDrawableUri(Context context, @Nullable String name) { 407 | if (name == null || name.isEmpty()) { 408 | return null; 409 | } 410 | name = name.toLowerCase().replace("-", "_"); 411 | int resId = context.getResources().getIdentifier( 412 | name, 413 | "drawable", 414 | context.getPackageName()); 415 | return new Uri.Builder() 416 | .scheme(UriUtil.LOCAL_RESOURCE_SCHEME) 417 | .path(String.valueOf(resId)) 418 | .build(); 419 | } 420 | 421 | private Drawable _createDrawable(CloseableReference image) { 422 | Preconditions.checkState(CloseableReference.isValid(image)); 423 | CloseableImage closeableImage = image.get(); 424 | if (closeableImage instanceof CloseableStaticBitmap) { 425 | CloseableStaticBitmap closeableStaticBitmap = (CloseableStaticBitmap) closeableImage; 426 | BitmapDrawable bitmapDrawable = new BitmapDrawable( 427 | getReactApplicationContext().getResources(), 428 | closeableStaticBitmap.getUnderlyingBitmap()); 429 | if (closeableStaticBitmap.getRotationAngle() == 0 || 430 | closeableStaticBitmap.getRotationAngle() == EncodedImage.UNKNOWN_ROTATION_ANGLE) { 431 | return bitmapDrawable; 432 | } else { 433 | return new OrientedDrawable(bitmapDrawable, closeableStaticBitmap.getRotationAngle()); 434 | } 435 | } else { 436 | throw new UnsupportedOperationException("Unrecognized image class: " + closeableImage); 437 | } 438 | } 439 | 440 | private Bitmap _drawable2Bitmap(Drawable drawable) { 441 | if (drawable instanceof BitmapDrawable) { 442 | return ((BitmapDrawable) drawable).getBitmap(); 443 | } else if (drawable instanceof NinePatchDrawable) { 444 | Bitmap bitmap = Bitmap 445 | .createBitmap( 446 | drawable.getIntrinsicWidth(), 447 | drawable.getIntrinsicHeight(), 448 | drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 449 | : Bitmap.Config.RGB_565); 450 | Canvas canvas = new Canvas(bitmap); 451 | drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), 452 | drawable.getIntrinsicHeight()); 453 | drawable.draw(canvas); 454 | return bitmap; 455 | } else { 456 | return null; 457 | } 458 | } 459 | } 460 | -------------------------------------------------------------------------------- /android/src/main/java/cn/reactnative/modules/weibo/WeiboPackage.java: -------------------------------------------------------------------------------- 1 | package cn.reactnative.modules.weibo; 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 lvbingru on 12/22/15. 15 | */ 16 | public class WeiboPackage implements ReactPackage { 17 | @Override 18 | public List createNativeModules(ReactApplicationContext reactContext) { 19 | return Arrays.asList(new NativeModule[]{ 20 | // Modules from third-party 21 | new WeiboModule(reactContext), 22 | }); 23 | } 24 | 25 | public List> createJSModules() { 26 | return Collections.emptyList(); 27 | } 28 | 29 | @Override 30 | public List createViewManagers(ReactApplicationContext reactContext) { 31 | return Collections.emptyList(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /android/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | react-native-weibo 3 | 4 | -------------------------------------------------------------------------------- /android/src/test/java/cn/reactnative/modules/weibo/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package cn.reactnative.modules.weibo; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * To work on unit tests, switch the Test Artifact in the Build Variants view. 9 | */ 10 | public class ExampleUnitTest { 11 | @Test 12 | public void addition_isCorrect() throws Exception { 13 | assertEquals(4, 2 + 2); 14 | } 15 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by lvbingru on 1/5/16. 3 | */ 4 | 5 | import {NativeModules, Platform, NativeEventEmitter, DeviceEventEmitter} from 'react-native'; 6 | 7 | const {WeiboAPI} = NativeModules; 8 | 9 | // Used only with promisify. Transform callback to promise result. 10 | function translateError(err, result) { 11 | if (!err) { 12 | return this.resolve(result); 13 | } 14 | if (typeof err === 'object') { 15 | if (err instanceof Error) { 16 | return this.reject(ret); 17 | } 18 | return this.reject(Object.assign(new Error(err.message), { errCode: err.errCode })); 19 | } else if (typeof err === 'string') { 20 | return this.reject(new Error(err)); 21 | } 22 | this.reject(Object.assign(new Error(), { origin: err })); 23 | } 24 | 25 | function wrapApi(nativeFunc) { 26 | if (!nativeFunc) { 27 | return undefined; 28 | } 29 | 30 | return (...args) => { 31 | return new Promise((resolve, reject) => { 32 | nativeFunc.apply(this, [...args, (...result) => { 33 | translateError.apply({ 34 | resolve, 35 | reject 36 | }, result); 37 | }]); 38 | }); 39 | }; 40 | } 41 | 42 | // Save callback and wait for future event. 43 | let savedCallback = undefined; 44 | function waitForResponse(type) { 45 | return new Promise((resolve, reject) => { 46 | if (savedCallback) { 47 | savedCallback('User canceled.'); 48 | } 49 | savedCallback = result => { 50 | if (result.type !== type) { 51 | return; 52 | } 53 | savedCallback = undefined; 54 | if (result.errCode !== 0) { 55 | const err = new Error(result.errMsg); 56 | err.errCode = result.errCode; 57 | reject(err); 58 | } else { 59 | resolve(result); 60 | } 61 | }; 62 | }); 63 | } 64 | 65 | 66 | let Emiter; 67 | if (Platform.OS === 'ios') { 68 | Emiter = new NativeEventEmitter(WeiboAPI); 69 | } else { 70 | Emiter = DeviceEventEmitter; 71 | } 72 | 73 | Emiter.addListener('Weibo_Resp', resp => { 74 | const callback = savedCallback; 75 | savedCallback = undefined; 76 | callback && callback(resp); 77 | }); 78 | 79 | const defaultScope = "all" 80 | const defaultRedirectURI = "https://api.weibo.com/oauth2/default.html" 81 | 82 | function checkData(data) { 83 | if(!data.redirectURI) { 84 | data.redirectURI = defaultRedirectURI 85 | } 86 | if(!data.scope) { 87 | data.scope = defaultScope 88 | } 89 | } 90 | 91 | const nativeSendAuthRequest = wrapApi(WeiboAPI.login); 92 | const nativeSendMessageRequest = wrapApi(WeiboAPI.shareToWeibo); 93 | 94 | export function login(config={}) { 95 | checkData(config) 96 | return Promise.all([waitForResponse('WBAuthorizeResponse'), nativeSendAuthRequest(config)]).then(v=>v[0]); 97 | } 98 | 99 | export function share(data) { 100 | checkData(data) 101 | return Promise.all([waitForResponse('WBSendMessageToWeiboResponse'), nativeSendMessageRequest(data)]).then(v=>v[0]); 102 | } 103 | -------------------------------------------------------------------------------- /ios/RCTWeiboAPI.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 915450F91C3D1520000CBFD2 /* RCTWeiboAPI.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 915450F81C3D1520000CBFD2 /* RCTWeiboAPI.h */; }; 11 | 915450FB1C3D1520000CBFD2 /* RCTWeiboAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = 915450FA1C3D1520000CBFD2 /* RCTWeiboAPI.m */; }; 12 | 9154511B1C3D161E000CBFD2 /* libWeiboSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9154510F1C3D161E000CBFD2 /* libWeiboSDK.a */; }; 13 | /* End PBXBuildFile section */ 14 | 15 | /* Begin PBXCopyFilesBuildPhase section */ 16 | 915450F31C3D1520000CBFD2 /* CopyFiles */ = { 17 | isa = PBXCopyFilesBuildPhase; 18 | buildActionMask = 2147483647; 19 | dstPath = "include/$(PRODUCT_NAME)"; 20 | dstSubfolderSpec = 16; 21 | files = ( 22 | 915450F91C3D1520000CBFD2 /* RCTWeiboAPI.h in CopyFiles */, 23 | ); 24 | runOnlyForDeploymentPostprocessing = 0; 25 | }; 26 | /* End PBXCopyFilesBuildPhase section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | 915450F51C3D1520000CBFD2 /* libRCTWeiboAPI.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTWeiboAPI.a; sourceTree = BUILT_PRODUCTS_DIR; }; 30 | 915450F81C3D1520000CBFD2 /* RCTWeiboAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTWeiboAPI.h; sourceTree = ""; }; 31 | 915450FA1C3D1520000CBFD2 /* RCTWeiboAPI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTWeiboAPI.m; sourceTree = ""; }; 32 | 9154510F1C3D161E000CBFD2 /* libWeiboSDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libWeiboSDK.a; sourceTree = ""; }; 33 | 915451101C3D161E000CBFD2 /* WBHttpRequest+WeiboGame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "WBHttpRequest+WeiboGame.h"; sourceTree = ""; }; 34 | 915451111C3D161E000CBFD2 /* WBHttpRequest+WeiboShare.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "WBHttpRequest+WeiboShare.h"; sourceTree = ""; }; 35 | 915451121C3D161E000CBFD2 /* WBHttpRequest+WeiboToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "WBHttpRequest+WeiboToken.h"; sourceTree = ""; }; 36 | 915451131C3D161E000CBFD2 /* WBHttpRequest+WeiboUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "WBHttpRequest+WeiboUser.h"; sourceTree = ""; }; 37 | 915451141C3D161E000CBFD2 /* WBHttpRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WBHttpRequest.h; sourceTree = ""; }; 38 | 915451151C3D161E000CBFD2 /* WBSDKBasicButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WBSDKBasicButton.h; sourceTree = ""; }; 39 | 915451161C3D161E000CBFD2 /* WBSDKCommentButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WBSDKCommentButton.h; sourceTree = ""; }; 40 | 915451171C3D161E000CBFD2 /* WBSDKRelationshipButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WBSDKRelationshipButton.h; sourceTree = ""; }; 41 | 915451181C3D161E000CBFD2 /* WeiboSDK.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = WeiboSDK.bundle; sourceTree = ""; }; 42 | 915451191C3D161E000CBFD2 /* WeiboSDK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeiboSDK.h; sourceTree = ""; }; 43 | 9154511A1C3D161E000CBFD2 /* WeiboUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeiboUser.h; sourceTree = ""; }; 44 | /* End PBXFileReference section */ 45 | 46 | /* Begin PBXFrameworksBuildPhase section */ 47 | 915450F21C3D1520000CBFD2 /* Frameworks */ = { 48 | isa = PBXFrameworksBuildPhase; 49 | buildActionMask = 2147483647; 50 | files = ( 51 | 9154511B1C3D161E000CBFD2 /* libWeiboSDK.a in Frameworks */, 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | 915450EC1C3D1520000CBFD2 = { 59 | isa = PBXGroup; 60 | children = ( 61 | 9154510E1C3D161E000CBFD2 /* libWeiboSDK */, 62 | 915450F71C3D1520000CBFD2 /* RCTWeiboAPI */, 63 | 915450F61C3D1520000CBFD2 /* Products */, 64 | ); 65 | sourceTree = ""; 66 | }; 67 | 915450F61C3D1520000CBFD2 /* Products */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | 915450F51C3D1520000CBFD2 /* libRCTWeiboAPI.a */, 71 | ); 72 | name = Products; 73 | sourceTree = ""; 74 | }; 75 | 915450F71C3D1520000CBFD2 /* RCTWeiboAPI */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 915450F81C3D1520000CBFD2 /* RCTWeiboAPI.h */, 79 | 915450FA1C3D1520000CBFD2 /* RCTWeiboAPI.m */, 80 | ); 81 | path = RCTWeiboAPI; 82 | sourceTree = ""; 83 | }; 84 | 9154510E1C3D161E000CBFD2 /* libWeiboSDK */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 9154510F1C3D161E000CBFD2 /* libWeiboSDK.a */, 88 | 915451101C3D161E000CBFD2 /* WBHttpRequest+WeiboGame.h */, 89 | 915451111C3D161E000CBFD2 /* WBHttpRequest+WeiboShare.h */, 90 | 915451121C3D161E000CBFD2 /* WBHttpRequest+WeiboToken.h */, 91 | 915451131C3D161E000CBFD2 /* WBHttpRequest+WeiboUser.h */, 92 | 915451141C3D161E000CBFD2 /* WBHttpRequest.h */, 93 | 915451151C3D161E000CBFD2 /* WBSDKBasicButton.h */, 94 | 915451161C3D161E000CBFD2 /* WBSDKCommentButton.h */, 95 | 915451171C3D161E000CBFD2 /* WBSDKRelationshipButton.h */, 96 | 915451181C3D161E000CBFD2 /* WeiboSDK.bundle */, 97 | 915451191C3D161E000CBFD2 /* WeiboSDK.h */, 98 | 9154511A1C3D161E000CBFD2 /* WeiboUser.h */, 99 | ); 100 | path = libWeiboSDK; 101 | sourceTree = ""; 102 | }; 103 | /* End PBXGroup section */ 104 | 105 | /* Begin PBXNativeTarget section */ 106 | 915450F41C3D1520000CBFD2 /* RCTWeiboAPI */ = { 107 | isa = PBXNativeTarget; 108 | buildConfigurationList = 915450FE1C3D1520000CBFD2 /* Build configuration list for PBXNativeTarget "RCTWeiboAPI" */; 109 | buildPhases = ( 110 | 915450F11C3D1520000CBFD2 /* Sources */, 111 | 915450F21C3D1520000CBFD2 /* Frameworks */, 112 | 915450F31C3D1520000CBFD2 /* CopyFiles */, 113 | ); 114 | buildRules = ( 115 | ); 116 | dependencies = ( 117 | ); 118 | name = RCTWeiboAPI; 119 | productName = RCTWeiboAPI; 120 | productReference = 915450F51C3D1520000CBFD2 /* libRCTWeiboAPI.a */; 121 | productType = "com.apple.product-type.library.static"; 122 | }; 123 | /* End PBXNativeTarget section */ 124 | 125 | /* Begin PBXProject section */ 126 | 915450ED1C3D1520000CBFD2 /* Project object */ = { 127 | isa = PBXProject; 128 | attributes = { 129 | LastUpgradeCheck = 0720; 130 | ORGANIZATIONNAME = erica; 131 | TargetAttributes = { 132 | 915450F41C3D1520000CBFD2 = { 133 | CreatedOnToolsVersion = 7.2; 134 | }; 135 | }; 136 | }; 137 | buildConfigurationList = 915450F01C3D1520000CBFD2 /* Build configuration list for PBXProject "RCTWeiboAPI" */; 138 | compatibilityVersion = "Xcode 3.2"; 139 | developmentRegion = English; 140 | hasScannedForEncodings = 0; 141 | knownRegions = ( 142 | en, 143 | ); 144 | mainGroup = 915450EC1C3D1520000CBFD2; 145 | productRefGroup = 915450F61C3D1520000CBFD2 /* Products */; 146 | projectDirPath = ""; 147 | projectRoot = ""; 148 | targets = ( 149 | 915450F41C3D1520000CBFD2 /* RCTWeiboAPI */, 150 | ); 151 | }; 152 | /* End PBXProject section */ 153 | 154 | /* Begin PBXSourcesBuildPhase section */ 155 | 915450F11C3D1520000CBFD2 /* Sources */ = { 156 | isa = PBXSourcesBuildPhase; 157 | buildActionMask = 2147483647; 158 | files = ( 159 | 915450FB1C3D1520000CBFD2 /* RCTWeiboAPI.m in Sources */, 160 | ); 161 | runOnlyForDeploymentPostprocessing = 0; 162 | }; 163 | /* End PBXSourcesBuildPhase section */ 164 | 165 | /* Begin XCBuildConfiguration section */ 166 | 915450FC1C3D1520000CBFD2 /* Debug */ = { 167 | isa = XCBuildConfiguration; 168 | buildSettings = { 169 | ALWAYS_SEARCH_USER_PATHS = NO; 170 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 171 | CLANG_CXX_LIBRARY = "libc++"; 172 | CLANG_ENABLE_MODULES = YES; 173 | CLANG_ENABLE_OBJC_ARC = YES; 174 | CLANG_WARN_BOOL_CONVERSION = YES; 175 | CLANG_WARN_CONSTANT_CONVERSION = YES; 176 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 177 | CLANG_WARN_EMPTY_BODY = YES; 178 | CLANG_WARN_ENUM_CONVERSION = YES; 179 | CLANG_WARN_INT_CONVERSION = YES; 180 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 181 | CLANG_WARN_UNREACHABLE_CODE = YES; 182 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 183 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 184 | COPY_PHASE_STRIP = NO; 185 | DEBUG_INFORMATION_FORMAT = dwarf; 186 | ENABLE_STRICT_OBJC_MSGSEND = YES; 187 | ENABLE_TESTABILITY = YES; 188 | GCC_C_LANGUAGE_STANDARD = gnu99; 189 | GCC_DYNAMIC_NO_PIC = NO; 190 | GCC_NO_COMMON_BLOCKS = YES; 191 | GCC_OPTIMIZATION_LEVEL = 0; 192 | GCC_PREPROCESSOR_DEFINITIONS = ( 193 | "DEBUG=1", 194 | "$(inherited)", 195 | ); 196 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 197 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 198 | GCC_WARN_UNDECLARED_SELECTOR = YES; 199 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 200 | GCC_WARN_UNUSED_FUNCTION = YES; 201 | GCC_WARN_UNUSED_VARIABLE = YES; 202 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 203 | MTL_ENABLE_DEBUG_INFO = YES; 204 | ONLY_ACTIVE_ARCH = YES; 205 | SDKROOT = iphoneos; 206 | }; 207 | name = Debug; 208 | }; 209 | 915450FD1C3D1520000CBFD2 /* Release */ = { 210 | isa = XCBuildConfiguration; 211 | buildSettings = { 212 | ALWAYS_SEARCH_USER_PATHS = NO; 213 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 214 | CLANG_CXX_LIBRARY = "libc++"; 215 | CLANG_ENABLE_MODULES = YES; 216 | CLANG_ENABLE_OBJC_ARC = YES; 217 | CLANG_WARN_BOOL_CONVERSION = YES; 218 | CLANG_WARN_CONSTANT_CONVERSION = YES; 219 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 220 | CLANG_WARN_EMPTY_BODY = YES; 221 | CLANG_WARN_ENUM_CONVERSION = YES; 222 | CLANG_WARN_INT_CONVERSION = YES; 223 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 224 | CLANG_WARN_UNREACHABLE_CODE = YES; 225 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 226 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 227 | COPY_PHASE_STRIP = NO; 228 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 229 | ENABLE_NS_ASSERTIONS = NO; 230 | ENABLE_STRICT_OBJC_MSGSEND = YES; 231 | GCC_C_LANGUAGE_STANDARD = gnu99; 232 | GCC_NO_COMMON_BLOCKS = YES; 233 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 234 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 235 | GCC_WARN_UNDECLARED_SELECTOR = YES; 236 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 237 | GCC_WARN_UNUSED_FUNCTION = YES; 238 | GCC_WARN_UNUSED_VARIABLE = YES; 239 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 240 | MTL_ENABLE_DEBUG_INFO = NO; 241 | SDKROOT = iphoneos; 242 | VALIDATE_PRODUCT = YES; 243 | }; 244 | name = Release; 245 | }; 246 | 915450FF1C3D1520000CBFD2 /* Debug */ = { 247 | isa = XCBuildConfiguration; 248 | buildSettings = { 249 | HEADER_SEARCH_PATHS = ( 250 | "$(inherited)", 251 | "$(SRCROOT)/../../react-native/React/**", 252 | "$(SRCROOT)/../../react-native/Libraries/**", 253 | "$(BUILT_PRODUCTS_DIR)/include/**", 254 | ); 255 | LIBRARY_SEARCH_PATHS = ( 256 | "$(inherited)", 257 | "$(PROJECT_DIR)/libWeiboSDK", 258 | ); 259 | OTHER_LDFLAGS = "-ObjC"; 260 | PRODUCT_NAME = "$(TARGET_NAME)"; 261 | SKIP_INSTALL = YES; 262 | }; 263 | name = Debug; 264 | }; 265 | 915451001C3D1520000CBFD2 /* Release */ = { 266 | isa = XCBuildConfiguration; 267 | buildSettings = { 268 | HEADER_SEARCH_PATHS = ( 269 | "$(inherited)", 270 | "$(SRCROOT)/../../react-native/React/**", 271 | "$(SRCROOT)/../../react-native/Libraries/**", 272 | "$(BUILT_PRODUCTS_DIR)/include/**", 273 | ); 274 | LIBRARY_SEARCH_PATHS = ( 275 | "$(inherited)", 276 | "$(PROJECT_DIR)/libWeiboSDK", 277 | ); 278 | OTHER_LDFLAGS = "-ObjC"; 279 | PRODUCT_NAME = "$(TARGET_NAME)"; 280 | SKIP_INSTALL = YES; 281 | }; 282 | name = Release; 283 | }; 284 | /* End XCBuildConfiguration section */ 285 | 286 | /* Begin XCConfigurationList section */ 287 | 915450F01C3D1520000CBFD2 /* Build configuration list for PBXProject "RCTWeiboAPI" */ = { 288 | isa = XCConfigurationList; 289 | buildConfigurations = ( 290 | 915450FC1C3D1520000CBFD2 /* Debug */, 291 | 915450FD1C3D1520000CBFD2 /* Release */, 292 | ); 293 | defaultConfigurationIsVisible = 0; 294 | defaultConfigurationName = Release; 295 | }; 296 | 915450FE1C3D1520000CBFD2 /* Build configuration list for PBXNativeTarget "RCTWeiboAPI" */ = { 297 | isa = XCConfigurationList; 298 | buildConfigurations = ( 299 | 915450FF1C3D1520000CBFD2 /* Debug */, 300 | 915451001C3D1520000CBFD2 /* Release */, 301 | ); 302 | defaultConfigurationIsVisible = 0; 303 | defaultConfigurationName = Release; 304 | }; 305 | /* End XCConfigurationList section */ 306 | }; 307 | rootObject = 915450ED1C3D1520000CBFD2 /* Project object */; 308 | } 309 | -------------------------------------------------------------------------------- /ios/RCTWeiboAPI.xcodeproj/xcuserdata/lvbingru.xcuserdatad/xcschemes/RCTWeiboAPI.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /ios/RCTWeiboAPI/RCTWeiboAPI.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCTWeiboAPI.h 3 | // RCTWeiboAPI 4 | // 5 | // Created by LvBingru on 1/6/16. 6 | // Copyright © 2016 erica. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface RCTWeiboAPI : RCTEventEmitter 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /ios/RCTWeiboAPI/RCTWeiboAPI.m: -------------------------------------------------------------------------------- 1 | // 2 | // RCTWeiboAPI.m 3 | // RCTWeiboAPI 4 | // 5 | // Created by LvBingru on 1/6/16. 6 | // Copyright © 2016 erica. All rights reserved. 7 | // 8 | 9 | #import "RCTWeiboAPI.h" 10 | #import "WeiboSDK.h" 11 | 12 | #import 13 | 14 | #define INVOKE_FAILED (@"WeiBo API invoke returns false.") 15 | #define RCTWBEventName (@"Weibo_Resp") 16 | 17 | #define RCTWBShareTypeImage @"image" 18 | #define RCTWBShareTypeText @"text" 19 | #define RCTWBShareTypeVideo @"video" 20 | 21 | #define RCTWBShareType @"type" 22 | #define RCTWBShareText @"text" 23 | #define RCTWBShareTitle @"title" 24 | #define RCTWBShareDescription @"description" 25 | #define RCTWBShareWebpageUrl @"webpageUrl" 26 | #define RCTWBShareImageUrl @"imageUrl" 27 | #define RCTWBShareAccessToken @"accessToken" 28 | 29 | BOOL gRegister = NO; 30 | 31 | @interface RCTWeiboAPI() 32 | 33 | @end 34 | 35 | @implementation RCTWeiboAPI 36 | 37 | { 38 | bool hasListeners; 39 | } 40 | 41 | 42 | @synthesize bridge = _bridge; 43 | 44 | +(BOOL)requiresMainQueueSetup { 45 | return YES; 46 | } 47 | 48 | // Will be called when this module's first listener is added. 49 | -(void)startObserving { 50 | hasListeners = YES; 51 | // Set up any upstream listeners or background tasks as necessary 52 | } 53 | 54 | 55 | // Will be called when this module's last listener is removed, or on dealloc. 56 | -(void)stopObserving { 57 | hasListeners = NO; 58 | // Remove upstream listeners, stop unnecessary background tasks 59 | } 60 | 61 | 62 | - (NSArray *)supportedEvents 63 | { 64 | return @[RCTWBEventName]; 65 | } 66 | 67 | RCT_EXPORT_MODULE(); 68 | 69 | - (dispatch_queue_t)methodQueue 70 | { 71 | return dispatch_get_main_queue(); 72 | } 73 | 74 | - (instancetype)init 75 | { 76 | self = [super init]; 77 | if (self) { 78 | 79 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleOpenURL:) name:@"RCTOpenURLNotification" object:nil]; 80 | } 81 | return self; 82 | } 83 | 84 | - (void)dealloc 85 | { 86 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 87 | } 88 | 89 | RCT_EXPORT_METHOD(login:(NSDictionary *)config 90 | :(RCTResponseSenderBlock)callback) 91 | { 92 | [self _autoRegisterAPI]; 93 | 94 | WBAuthorizeRequest *request = [self _genAuthRequest:config]; 95 | BOOL success = [WeiboSDK sendRequest:request]; 96 | callback(@[success?[NSNull null]:INVOKE_FAILED]); 97 | } 98 | 99 | RCT_EXPORT_METHOD(logout) 100 | { 101 | [WeiboSDK logOutWithToken:nil delegate:nil withTag:nil]; 102 | } 103 | 104 | RCT_EXPORT_METHOD(shareToWeibo:(NSDictionary *)aData 105 | :(RCTResponseSenderBlock)callback) 106 | { 107 | [self _autoRegisterAPI]; 108 | 109 | NSString *imageUrl = aData[RCTWBShareImageUrl]; 110 | if (imageUrl.length && _bridge.imageLoader) { 111 | CGSize size = CGSizeZero; 112 | if (![aData[RCTWBShareType] isEqualToString:RCTWBShareTypeImage]) { 113 | size = CGSizeMake(80,80); 114 | } 115 | [_bridge.imageLoader loadImageWithURLRequest:[RCTConvert NSURLRequest:imageUrl] size:size scale:1 clipped:FALSE resizeMode:UIViewContentModeScaleToFill progressBlock:nil partialLoadBlock: nil completionBlock:^(NSError *error, UIImage *image) { 116 | [self _shareWithData:aData image:image]; 117 | }]; 118 | } 119 | else { 120 | [self _shareWithData:aData image:nil]; 121 | } 122 | callback(@[[NSNull null]]); 123 | } 124 | 125 | 126 | - (void)handleOpenURL:(NSNotification *)note 127 | { 128 | NSDictionary *userInfo = note.userInfo; 129 | NSString *url = userInfo[@"url"]; 130 | [WeiboSDK handleOpenURL:[NSURL URLWithString:url] delegate:self]; 131 | } 132 | 133 | 134 | #pragma mark - sina delegate 135 | - (void)didReceiveWeiboRequest:(WBBaseRequest *)request 136 | { 137 | if ([request isKindOfClass:WBProvideMessageForWeiboRequest.class]) 138 | { 139 | 140 | } 141 | } 142 | 143 | - (void)didReceiveWeiboResponse:(WBBaseResponse *)response 144 | { 145 | NSMutableDictionary *body = [NSMutableDictionary new]; 146 | body[@"errCode"] = @(response.statusCode); 147 | // 分享 148 | if ([response isKindOfClass:WBSendMessageToWeiboResponse.class]) 149 | { 150 | body[@"type"] = @"WBSendMessageToWeiboResponse"; 151 | if (response.statusCode == WeiboSDKResponseStatusCodeSuccess) 152 | { 153 | WBSendMessageToWeiboResponse *sendResponse = (WBSendMessageToWeiboResponse *)response; 154 | WBAuthorizeResponse *authorizeResponse = sendResponse.authResponse; 155 | if (sendResponse.authResponse != nil) { 156 | body[@"userID"] = authorizeResponse.userID; 157 | body[@"accessToken"] = authorizeResponse.accessToken; 158 | body[@"expirationDate"] = @([authorizeResponse.expirationDate timeIntervalSince1970]); 159 | body[@"refreshToken"] = authorizeResponse.refreshToken; 160 | } 161 | } 162 | else 163 | { 164 | body[@"errMsg"] = [self _getErrMsg:response.statusCode]; 165 | } 166 | } 167 | // 认证 168 | else if ([response isKindOfClass:WBAuthorizeResponse.class]) 169 | { 170 | body[@"type"] = @"WBAuthorizeResponse"; 171 | if (response.statusCode == WeiboSDKResponseStatusCodeSuccess) 172 | { 173 | WBAuthorizeResponse *authorizeResponse = (WBAuthorizeResponse *)response; 174 | body[@"userID"] = authorizeResponse.userID; 175 | body[@"accessToken"] = authorizeResponse.accessToken; 176 | body[@"expirationDate"] = @([authorizeResponse.expirationDate timeIntervalSince1970]*1000); 177 | body[@"refreshToken"] = authorizeResponse.refreshToken; 178 | } 179 | else 180 | { 181 | body[@"errMsg"] = [self _getErrMsg:response.statusCode]; 182 | } 183 | } 184 | 185 | if (hasListeners) { 186 | [self sendEventWithName:RCTWBEventName body:body]; 187 | } 188 | } 189 | 190 | #pragma mark - private 191 | 192 | // 如果js没有调用registerApp,自动从plist中读取appId 193 | - (void)_autoRegisterAPI 194 | { 195 | if (gRegister) { 196 | return; 197 | } 198 | 199 | NSArray *list = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleURLTypes"]; 200 | for (NSDictionary *item in list) { 201 | NSString *name = item[@"CFBundleURLName"]; 202 | if ([name isEqualToString:@"sina"]) { 203 | NSArray *schemes = item[@"CFBundleURLSchemes"]; 204 | if (schemes.count > 0) 205 | { 206 | NSString *appId = [schemes[0] substringFromIndex:@"wb".length]; 207 | if ([WeiboSDK registerApp:appId]) { 208 | gRegister = YES; 209 | } 210 | #ifdef DEBUG 211 | [WeiboSDK enableDebugMode:YES]; 212 | #endif 213 | break; 214 | } 215 | } 216 | } 217 | } 218 | 219 | - (NSString *)_getErrMsg:(NSInteger)errCode 220 | { 221 | NSString *errMsg = @"微博认证失败"; 222 | switch (errCode) { 223 | case WeiboSDKResponseStatusCodeUserCancel: 224 | errMsg = @"用户取消发送"; 225 | break; 226 | case WeiboSDKResponseStatusCodeSentFail: 227 | errMsg = @"发送失败"; 228 | break; 229 | case WeiboSDKResponseStatusCodeAuthDeny: 230 | errMsg = @"授权失败"; 231 | break; 232 | case WeiboSDKResponseStatusCodeUserCancelInstall: 233 | errMsg = @"用户取消安装微博客户端"; 234 | break; 235 | case WeiboSDKResponseStatusCodePayFail: 236 | errMsg = @"支付失败"; 237 | break; 238 | case WeiboSDKResponseStatusCodeShareInSDKFailed: 239 | errMsg = @"分享失败"; 240 | break; 241 | case WeiboSDKResponseStatusCodeUnsupport: 242 | errMsg = @"不支持的请求"; 243 | break; 244 | default: 245 | errMsg = @"位置"; 246 | break; 247 | } 248 | return errMsg; 249 | } 250 | 251 | - (void)_shareWithData:(NSDictionary *)aData image:(UIImage *)aImage 252 | { 253 | WBMessageObject *message = [WBMessageObject message]; 254 | NSString *text = aData[RCTWBShareText]; 255 | message.text = text; 256 | 257 | NSString *type = aData[RCTWBShareType]; 258 | if ([type isEqualToString:RCTWBShareTypeText]) { 259 | } 260 | else if ([type isEqualToString:RCTWBShareTypeImage]) { 261 | // 大小不能超过10M 262 | WBImageObject *imageObject = [WBImageObject new]; 263 | if (aImage) { 264 | imageObject.imageData = UIImageJPEGRepresentation(aImage, 0.7); 265 | } 266 | message.imageObject = imageObject; 267 | } 268 | else { 269 | if ([type isEqualToString:RCTWBShareTypeVideo]) { 270 | WBNewVideoObject *videoObject = [WBNewVideoObject new]; 271 | NSURL *videoUrl = aData[RCTWBShareWebpageUrl]; 272 | [videoObject addVideo:videoUrl]; 273 | message.videoObject = videoObject; 274 | } 275 | else { 276 | WBWebpageObject *webpageObject = [WBWebpageObject new]; 277 | webpageObject.webpageUrl = aData[RCTWBShareWebpageUrl]; 278 | message.mediaObject = webpageObject; 279 | } 280 | message.mediaObject.objectID = [NSDate date].description; 281 | message.mediaObject.description = aData[RCTWBShareDescription]; 282 | message.mediaObject.title = aData[RCTWBShareTitle]; 283 | if (aImage) { 284 | // @warning 大小小于32k 285 | message.mediaObject.thumbnailData = UIImageJPEGRepresentation(aImage, 0.7); 286 | } 287 | } 288 | 289 | WBAuthorizeRequest *authRequest = [self _genAuthRequest:aData]; 290 | NSString *accessToken = aData[RCTWBShareAccessToken]; 291 | WBSendMessageToWeiboRequest *request = [WBSendMessageToWeiboRequest requestWithMessage:message authInfo:authRequest access_token:accessToken]; 292 | 293 | BOOL success = [WeiboSDK sendRequest:request]; 294 | if (!success) { 295 | NSMutableDictionary *body = [NSMutableDictionary new]; 296 | body[@"errMsg"] = INVOKE_FAILED; 297 | body[@"errCode"] = @(-1); 298 | body[@"type"] = @"WBSendMessageToWeiboResponse"; 299 | 300 | if (hasListeners) { 301 | [self sendEventWithName:RCTWBEventName body:body]; 302 | } 303 | } 304 | } 305 | 306 | - (WBAuthorizeRequest *)_genAuthRequest:(NSDictionary *)config 307 | { 308 | NSString *redirectURI = config[@"redirectURI"]; 309 | NSString *scope = config[@"scope"]; 310 | 311 | WBAuthorizeRequest *authRequest = [WBAuthorizeRequest request]; 312 | authRequest.redirectURI = redirectURI; 313 | authRequest.scope = scope; 314 | 315 | return authRequest; 316 | } 317 | 318 | @end 319 | -------------------------------------------------------------------------------- /ios/libWeiboSDK/WBHttpRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBHttpRequest.h 3 | // WeiboSDK 4 | // 5 | // Created by DannionQiu on 14-9-18. 6 | // Copyright (c) 2014年 SINA iOS Team. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #pragma mark - WBHttpRequest and WBHttpRequestDelegate 13 | @class WBHttpRequest; 14 | 15 | /** 16 | 接收并处理来自微博sdk对于网络请求接口的调用响应 以及logOutWithToken的请求 17 | */ 18 | @protocol WBHttpRequestDelegate 19 | 20 | /** 21 | 收到一个来自微博Http请求的响应 22 | 23 | @param response 具体的响应对象 24 | */ 25 | @optional 26 | - (void)request:(WBHttpRequest *)request didReceiveResponse:(NSURLResponse *)response; 27 | 28 | /** 29 | 收到一个来自微博Http请求失败的响应 30 | 31 | @param error 错误信息 32 | */ 33 | @optional 34 | - (void)request:(WBHttpRequest *)request didFailWithError:(NSError *)error; 35 | 36 | /** 37 | 收到一个来自微博Http请求的网络返回 38 | 39 | @param result 请求返回结果 40 | */ 41 | @optional 42 | - (void)request:(WBHttpRequest *)request didFinishLoadingWithResult:(NSString *)result; 43 | 44 | /** 45 | 收到一个来自微博Http请求的网络返回 46 | 47 | @param data 请求返回结果 48 | */ 49 | @optional 50 | - (void)request:(WBHttpRequest *)request didFinishLoadingWithDataResult:(NSData *)data; 51 | 52 | /** 53 | 收到快速SSO授权的重定向 54 | 55 | @param URI 56 | */ 57 | @optional 58 | - (void)request:(WBHttpRequest *)request didReciveRedirectResponseWithURI:(NSURL *)redirectUrl; 59 | 60 | @end 61 | 62 | 63 | /** 64 | 微博封装Http请求的消息结构 65 | 66 | */ 67 | @interface WBHttpRequest : NSObject 68 | { 69 | NSURLConnection *connection; 70 | NSMutableData *responseData; 71 | } 72 | 73 | /** 74 | 用户自定义请求地址URL 75 | */ 76 | @property (nonatomic, strong) NSString *url; 77 | 78 | /** 79 | 用户自定义请求方式 80 | 81 | 支持"GET" "POST" 82 | */ 83 | @property (nonatomic, strong) NSString *httpMethod; 84 | 85 | /** 86 | 用户自定义请求参数字典 87 | */ 88 | @property (nonatomic, strong) NSDictionary *params; 89 | 90 | /** 91 | WBHttpRequestDelegate对象,用于接收微博SDK对于发起的接口请求的请求的响应 92 | */ 93 | @property (nonatomic, weak) id delegate; 94 | 95 | /** 96 | 用户自定义TAG 97 | 98 | 用于区分回调Request 99 | */ 100 | @property (nonatomic, strong) NSString* tag; 101 | 102 | /** 103 | 统一HTTP请求接口 104 | 调用此接口后,将发送一个HTTP网络请求 105 | @param url 请求url地址 106 | @param httpMethod 支持"GET" "POST" 107 | @param params 向接口传递的参数结构 108 | @param delegate WBHttpRequestDelegate对象,用于接收微博SDK对于发起的接口请求的请求的响应 109 | @param tag 用户自定义TAG,将通过回调WBHttpRequest实例的tag属性返回 110 | */ 111 | + (WBHttpRequest *)requestWithURL:(NSString *)url 112 | httpMethod:(NSString *)httpMethod 113 | params:(NSDictionary *)params 114 | delegate:(id)delegate 115 | withTag:(NSString *)tag; 116 | 117 | /** 118 | 统一微博Open API HTTP请求接口 119 | 调用此接口后,将发送一个HTTP网络请求(用于访问微博open api) 120 | @param accessToken 应用获取到的accessToken,用于身份验证 121 | @param url 请求url地址 122 | @param httpMethod 支持"GET" "POST" 123 | @param params 向接口传递的参数结构 124 | @param delegate WBHttpRequestDelegate对象,用于接收微博SDK对于发起的接口请求的请求的响应 125 | @param tag 用户自定义TAG,将通过回调WBHttpRequest实例的tag属性返回 126 | */ 127 | 128 | + (WBHttpRequest *)requestWithAccessToken:(NSString *)accessToken 129 | url:(NSString *)url 130 | httpMethod:(NSString *)httpMethod 131 | params:(NSDictionary *)params 132 | delegate:(id)delegate 133 | withTag:(NSString *)tag; 134 | 135 | 136 | 137 | /** 138 | 取消网络请求接口 139 | 调用此接口后,将取消当前网络请求,建议同时[WBHttpRequest setDelegate:nil]; 140 | 注意:该方法只对使用delegate的request方法有效。无法取消任何使用block的request的网络请求接口。 141 | */ 142 | - (void)disconnect; 143 | 144 | #pragma mark - block extension 145 | 146 | typedef void (^WBRequestHandler)(WBHttpRequest *httpRequest, 147 | id result, 148 | NSError *error); 149 | 150 | /** 151 | 统一微博Open API HTTP请求接口 152 | 调用此接口后,将发送一个HTTP网络请求(用于访问微博open api) 153 | @param url 请求url地址 154 | @param httpMethod 支持"GET" "POST" 155 | @param params 向接口传递的参数结构 156 | @param queue 发起请求的NSOperationQueue对象,如queue为nil,则在主线程([NSOperationQueue mainQueue])发起请求。 157 | @param handler 接口请求返回调用的block方法 158 | */ 159 | + (WBHttpRequest *)requestWithURL:(NSString *)url 160 | httpMethod:(NSString *)httpMethod 161 | params:(NSDictionary *)params 162 | queue:(NSOperationQueue*)queue 163 | withCompletionHandler:(WBRequestHandler)handler; 164 | 165 | 166 | /** 167 | 统一HTTP请求接口 168 | 调用此接口后,将发送一个HTTP网络请求 169 | @param url 请求url地址 170 | @param httpMethod 支持"GET" "POST" 171 | @param params 向接口传递的参数结构 172 | @param queue 发起请求的NSOperationQueue对象,如queue为nil,则在主线程([NSOperationQueue mainQueue])发起请求。 173 | @param handler 接口请求返回调用的block方法 174 | */ 175 | 176 | + (WBHttpRequest *)requestWithAccessToken:(NSString *)accessToken 177 | url:(NSString *)url 178 | httpMethod:(NSString *)httpMethod 179 | params:(NSDictionary *)params 180 | queue:(NSOperationQueue*)queue 181 | withCompletionHandler:(WBRequestHandler)handler; 182 | 183 | 184 | @end 185 | -------------------------------------------------------------------------------- /ios/libWeiboSDK/WeiboSDK.bundle/images/common_button_white@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yun77op/react-native-weibo/ebbaf5d8a4748526475266ecf7cadd1ec63ab6e8/ios/libWeiboSDK/WeiboSDK.bundle/images/common_button_white@2x.png -------------------------------------------------------------------------------- /ios/libWeiboSDK/WeiboSDK.bundle/images/common_button_white_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yun77op/react-native-weibo/ebbaf5d8a4748526475266ecf7cadd1ec63ab6e8/ios/libWeiboSDK/WeiboSDK.bundle/images/common_button_white_highlighted@2x.png -------------------------------------------------------------------------------- /ios/libWeiboSDK/WeiboSDK.bundle/images/empty_failed@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yun77op/react-native-weibo/ebbaf5d8a4748526475266ecf7cadd1ec63ab6e8/ios/libWeiboSDK/WeiboSDK.bundle/images/empty_failed@2x.png -------------------------------------------------------------------------------- /ios/libWeiboSDK/WeiboSDK.bundle/others/mfp.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yun77op/react-native-weibo/ebbaf5d8a4748526475266ecf7cadd1ec63ab6e8/ios/libWeiboSDK/WeiboSDK.bundle/others/mfp.cer -------------------------------------------------------------------------------- /ios/libWeiboSDK/WeiboSDK.h: -------------------------------------------------------------------------------- 1 | // 2 | // WeiboSDKHeaders.h 3 | // WeiboSDKDemo 4 | // 5 | // Created by Wade Cheng on 4/3/13. 6 | // Copyright (c) 2013 SINA iOS Team. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import "WBHttpRequest.h" 13 | 14 | 15 | typedef NS_ENUM(NSInteger, WeiboSDKResponseStatusCode) 16 | { 17 | WeiboSDKResponseStatusCodeSuccess = 0,//成功 18 | WeiboSDKResponseStatusCodeUserCancel = -1,//用户取消发送 19 | WeiboSDKResponseStatusCodeSentFail = -2,//发送失败 20 | WeiboSDKResponseStatusCodeAuthDeny = -3,//授权失败 21 | WeiboSDKResponseStatusCodeUserCancelInstall = -4,//用户取消安装微博客户端 22 | WeiboSDKResponseStatusCodePayFail = -5,//支付失败 23 | WeiboSDKResponseStatusCodeShareInSDKFailed = -8,//分享失败 详情见response UserInfo 24 | WeiboSDKResponseStatusCodeUnsupport = -99,//不支持的请求 25 | WeiboSDKResponseStatusCodeUnknown = -100, 26 | }; 27 | 28 | 29 | @protocol WeiboSDKDelegate; 30 | @protocol WBHttpRequestDelegate; 31 | @class WBBaseRequest; 32 | @class WBBaseResponse; 33 | @class WBMessageObject; 34 | @class WBImageObject; 35 | @class WBBaseMediaObject; 36 | @class WBHttpRequest; 37 | @class PHAsset; 38 | @class WBNewVideoObject; 39 | 40 | /** 41 | 微博SDK接口类 42 | */ 43 | @interface WeiboSDK : NSObject 44 | 45 | /** 46 | 检查用户是否安装了微博客户端程序 47 | @return 已安装返回YES,未安装返回NO 48 | */ 49 | + (BOOL)isWeiboAppInstalled; 50 | 51 | /** 52 | 检查用户是否可以通过微博客户端进行分享 53 | @return 可以使用返回YES,不可以使用返回NO 54 | */ 55 | + (BOOL)isCanShareInWeiboAPP; 56 | 57 | /** 58 | 检查用户是否可以使用微博客户端进行SSO授权 59 | @return 可以使用返回YES,不可以使用返回NO 60 | */ 61 | + (BOOL)isCanSSOInWeiboApp; 62 | 63 | /** 64 | 打开微博客户端程序 65 | @return 成功打开返回YES,失败返回NO 66 | */ 67 | + (BOOL)openWeiboApp; 68 | 69 | 70 | 71 | /** 72 | 获取微博客户端程序的itunes安装地址 73 | @return 微博客户端程序的itunes安装地址 74 | */ 75 | + (NSString *)getWeiboAppInstallUrl; 76 | 77 | /** 78 | 获取当前微博SDK的版本号 79 | @return 当前微博SDK的版本号 80 | */ 81 | + (NSString *)getSDKVersion; 82 | 83 | 84 | extern NSString * const WeiboSDKGetAidSucessNotification; 85 | extern NSString * const WeiboSDKGetAidFailNotification; 86 | /** 87 | 获取当前微博SDK的aid 88 | 返回的aid值可能为 nil ,当值为 nil 时会尝试获取 aid 值。 89 | 当获取成功( aid 值变为有效值)时,SDK会发出名为 WeiboSDKGetAidSucessNotification 的通知,通知中带有 aid 值。 90 | 当获取失败时,SDK会发出名为 WeiboSDKGetAidFailNotification 的通知,通知中带有 NSError 对象。 91 | @return aid 用于广告的与设备信息相关的标识符 92 | */ 93 | + (NSString *)getWeiboAid; 94 | 95 | 96 | /** 97 | 向微博客户端程序注册第三方应用 98 | @param appKey 微博开放平台第三方应用appKey 99 | @return 注册成功返回YES,失败返回NO 100 | */ 101 | + (BOOL)registerApp:(NSString *)appKey; 102 | 103 | /** 104 | 处理微博客户端程序通过URL启动第三方应用时传递的数据 105 | 106 | 需要在 application:openURL:sourceApplication:annotation:或者application:handleOpenURL中调用 107 | @param url 启动第三方应用的URL 108 | @param delegate WeiboSDKDelegate对象,用于接收微博触发的消息 109 | @see WeiboSDKDelegate 110 | */ 111 | + (BOOL)handleOpenURL:(NSURL *)url delegate:(id)delegate; 112 | 113 | /** 114 | 发送请求给微博客户端程序,并切换到微博 115 | 116 | 请求发送给微博客户端程序之后,微博客户端程序会进行相关的处理,处理完成之后一定会调用 [WeiboSDKDelegate didReceiveWeiboResponse:] 方法将处理结果返回给第三方应用 117 | 118 | @param request 具体的发送请求 119 | 120 | @see [WeiboSDKDelegate didReceiveWeiboResponse:] 121 | @see WBBaseResponse 122 | */ 123 | + (BOOL)sendRequest:(WBBaseRequest *)request; 124 | 125 | /** 126 | 收到微博客户端程序的请求后,发送对应的应答给微博客户端端程序,并切换到微博 127 | 128 | 第三方应用收到微博的请求后,异步处理该请求,完成后必须调用该函数将应答返回给微博 129 | 130 | @param response 具体的应答内容 131 | @see WBBaseRequest 132 | */ 133 | + (BOOL)sendResponse:(WBBaseResponse *)response; 134 | 135 | /** 136 | 设置WeiboSDK的调试模式 137 | 138 | 当开启调试模式时,WeiboSDK会在控制台输出详细的日志信息,开发者可以据此调试自己的程序。默认为 NO 139 | @param enabled 开启或关闭WeiboSDK的调试模式 140 | */ 141 | + (void)enableDebugMode:(BOOL)enabled; 142 | 143 | /** 144 | 取消授权,登出接口 145 | 调用此接口后,token将失效 146 | @param token 第三方应用之前申请的Token 147 | @param delegate WBHttpRequestDelegate对象,用于接收微博SDK对于发起的接口请求的请求的响应 148 | @param tag 用户自定义TAG,将通过回调WBHttpRequest实例的tag属性返回 149 | 150 | */ 151 | + (void)logOutWithToken:(NSString *)token delegate:(id)delegate withTag:(NSString*)tag; 152 | 153 | /** 154 | 呼起微博客户端或打开微博H5页面,SDK自动检测是否安装微博客户端,当调用SDK相关方法时: 155 | 156 | 有的话呼起微博客户端定位到对应界面; 157 | 没有的话打开 webView 加载相应的微博H5页面; 158 | @param uid 用户id 159 | @param mid 微博id 160 | @param aid 文章id 161 | */ 162 | 163 | //连接到指定用户的微博个人主页,连接后可进行加关注等互动 164 | + (void)linkToUser:(NSString *)uid; 165 | 166 | //连接到指定的单条微博详情页,连接后可对这条微博进行转、评、赞等互动 167 | + (void)linkToSingleBlog:(NSString *)uid blogID:(NSString *)mid; 168 | 169 | //连接到指定的微博头条文章页 170 | + (void)linkToArticle:(NSString *)aid; 171 | 172 | //分享到微博 173 | + (void)shareToWeibo:(NSString *)content; 174 | 175 | //评论指定的微博 176 | + (void)commentToWeibo:(NSString *)mid; 177 | 178 | //连接到微博搜索内容流 179 | + (void)linkToSearch:(NSString *)keyword; 180 | 181 | //连接到我的微博消息流 182 | + (void)linkToTimeLine; 183 | 184 | //连接到我的微博个人主页 185 | + (void)linkToProfile; 186 | 187 | @end 188 | 189 | /** 190 | 接收并处理来至微博客户端程序的事件消息 191 | */ 192 | @protocol WeiboSDKDelegate 193 | 194 | /** 195 | 收到一个来自微博客户端程序的请求 196 | 197 | 收到微博的请求后,第三方应用应该按照请求类型进行处理,处理完后必须通过 [WeiboSDK sendResponse:] 将结果回传给微博 198 | @param request 具体的请求对象 199 | */ 200 | - (void)didReceiveWeiboRequest:(WBBaseRequest *)request; 201 | 202 | /** 203 | 收到一个来自微博客户端程序的响应 204 | 205 | 收到微博的响应后,第三方应用可以通过响应类型、响应的数据和 WBBaseResponse.userInfo 中的数据完成自己的功能 206 | @param response 具体的响应对象 207 | */ 208 | - (void)didReceiveWeiboResponse:(WBBaseResponse *)response; 209 | 210 | @end 211 | 212 | 213 | #pragma mark - DataTransferObject and Base Request/Response 214 | 215 | /** 216 | 微博客户端程序和第三方应用之间传输数据信息的基类 217 | */ 218 | @interface WBDataTransferObject : NSObject 219 | 220 | /** 221 | 自定义信息字典,用于数据传输过程中存储相关的上下文环境数据 222 | 223 | 第三方应用给微博客户端程序发送 request 时,可以在 userInfo 中存储请求相关的信息。 224 | 225 | @warning userInfo中的数据必须是实现了 `NSCoding` 协议的对象,必须保证能序列化和反序列化 226 | @warning 序列化后的数据不能大于10M 227 | */ 228 | @property (nonatomic, strong) NSDictionary *userInfo; 229 | 230 | 231 | /** 232 | 发送该数据对象的SDK版本号 233 | 234 | 如果数据对象是自己生成的,则sdkVersion为当前SDK的版本号;如果是接收到的数据对象,则sdkVersion为数据发送方SDK版本号 235 | */ 236 | @property (strong, nonatomic, readonly) NSString *sdkVersion; 237 | 238 | 239 | /** 240 | 当用户没有安装微博客户端程序时是否提示用户打开微博安装页面 241 | 242 | 如果设置为YES,当用户未安装微博时会弹出Alert询问用户是否要打开微博App的安装页面。默认为YES 243 | */ 244 | @property (nonatomic, assign) BOOL shouldOpenWeiboAppInstallPageIfNotInstalled; 245 | 246 | 247 | @end 248 | 249 | 250 | /** 251 | 微博SDK所有请求类的基类 252 | */ 253 | @interface WBBaseRequest : WBDataTransferObject 254 | 255 | /** 256 | 返回一个 WBBaseRequest 对象 257 | 258 | @return 返回一个*自动释放的*WBBaseRequest对象 259 | */ 260 | + (id)request; 261 | 262 | @end 263 | 264 | 265 | /** 266 | 微博SDK所有响应类的基类 267 | */ 268 | @interface WBBaseResponse : WBDataTransferObject 269 | 270 | /** 271 | 对应的 request 中的自定义信息字典 272 | 273 | 如果当前 response 是由微博客户端响应给第三方应用的,则 requestUserInfo 中会包含原 request.userInfo 中的所有数据 274 | 275 | @see WBBaseRequest.userInfo 276 | */ 277 | @property (strong, nonatomic, readonly) NSDictionary *requestUserInfo; 278 | 279 | /** 280 | 响应状态码 281 | 282 | 第三方应用可以通过statusCode判断请求的处理结果 283 | */ 284 | @property (nonatomic, assign) WeiboSDKResponseStatusCode statusCode; 285 | 286 | /** 287 | 返回一个 WBBaseResponse 对象 288 | 289 | @return 返回一个*自动释放的*WBBaseResponse对象 290 | */ 291 | + (id)response; 292 | 293 | @end 294 | 295 | #pragma mark - Authorize Request/Response 296 | 297 | /** 298 | 第三方应用向微博客户端请求认证的消息结构 299 | 300 | 第三方应用向微博客户端申请认证时,需要调用 [WeiboSDK sendRequest:] 函数, 向微博客户端发送一个 WBAuthorizeRequest 的消息结构。 301 | 微博客户端处理完后会向第三方应用发送一个结构为 WBAuthorizeResponse 的处理结果。 302 | */ 303 | @interface WBAuthorizeRequest : WBBaseRequest 304 | 305 | /** 306 | 微博开放平台第三方应用授权回调页地址,默认为`http://` 307 | 308 | 参考 http://open.weibo.com/wiki/%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6%E8%AF%B4%E6%98%8E#.E5.AE.A2.E6.88.B7.E7.AB.AF.E9.BB.98.E8.AE.A4.E5.9B.9E.E8.B0.83.E9.A1.B5 309 | 310 | @warning 必须保证和在微博开放平台应用管理界面配置的“授权回调页”地址一致,如未进行配置则默认为`http://` 311 | @warning 不能为空,长度小于1K 312 | */ 313 | @property (nonatomic, strong) NSString *redirectURI; 314 | 315 | /** 316 | 微博开放平台第三方应用scope,多个scrope用逗号分隔 317 | 318 | 参考 http://open.weibo.com/wiki/%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6%E8%AF%B4%E6%98%8E#scope 319 | 320 | @warning 长度小于1K 321 | */ 322 | @property (nonatomic, strong) NSString *scope; 323 | 324 | /** 325 | 当用户没有安装微博客户端或微博客户端过低无法支持SSO的时候是否弹出SDK自带的Webview进行授权 326 | 327 | 如果设置为YES,当用户没有安装微博客户端或微博客户端过低无法支持SSO的时候会自动弹出SDK自带的Webview进行授权。 328 | 329 | 如果设置为NO,会根据 shouldOpenWeiboAppInstallPageIfNotInstalled 属性判断是否弹出安装/更新微博的对话框 330 | 331 | 默认为YES 332 | */ 333 | @property (nonatomic, assign) BOOL shouldShowWebViewForAuthIfCannotSSO; 334 | 335 | 336 | @end 337 | 338 | 339 | /** 340 | 微博客户端处理完第三方应用的认证申请后向第三方应用回送的处理结果 341 | 342 | WBAuthorizeResponse 结构中仅包含常用的 userID 、accessToken 和 expirationDate 信息,其他的认证信息(比如部分应用可以获取的 refresh_token 信息)会统一存放到 userInfo 中 343 | */ 344 | @interface WBAuthorizeResponse : WBBaseResponse 345 | 346 | /** 347 | 用户ID 348 | */ 349 | @property (nonatomic, strong) NSString *userID; 350 | 351 | /** 352 | 认证口令 353 | */ 354 | @property (nonatomic, strong) NSString *accessToken; 355 | 356 | /** 357 | 认证过期时间 358 | */ 359 | @property (nonatomic, strong) NSDate *expirationDate; 360 | 361 | /** 362 | 当认证口令过期时用于换取认证口令的更新口令 363 | */ 364 | @property (nonatomic, strong) NSString *refreshToken; 365 | 366 | @end 367 | 368 | #pragma mark - ProvideMessageForWeibo Request/Response 369 | 370 | /** 371 | 微博客户端向第三方程序请求提供内容的消息结构 372 | */ 373 | @interface WBProvideMessageForWeiboRequest : WBBaseRequest 374 | 375 | @end 376 | 377 | /** 378 | 微博客户端向第三方应用请求提供内容,第三方应用向微博客户端返回的消息结构 379 | */ 380 | @interface WBProvideMessageForWeiboResponse : WBBaseResponse 381 | 382 | /** 383 | 提供给微博客户端的消息 384 | */ 385 | @property (nonatomic, strong) WBMessageObject *message; 386 | 387 | /** 388 | 返回一个 WBProvideMessageForWeiboResponse 对象 389 | @param message 需要回送给微博客户端程序的消息对象 390 | @return 返回一个*自动释放的*WBProvideMessageForWeiboResponse对象 391 | */ 392 | + (id)responseWithMessage:(WBMessageObject *)message; 393 | 394 | @end 395 | 396 | #pragma mark - SendMessageToWeibo Request/Response 397 | 398 | /** 399 | 第三方应用发送消息至微博客户端程序的消息结构体 400 | */ 401 | @interface WBSendMessageToWeiboRequest : WBBaseRequest 402 | 403 | /** 404 | 发送给微博客户端的消息 405 | */ 406 | @property (nonatomic, strong) WBMessageObject *message; 407 | 408 | /** 409 | 返回一个 WBSendMessageToWeiboRequest 对象 410 | 此方法生成对象被[WeiboSDK sendRequest:]会唤起微博客户端的发布器进行分享,如果未安装微博客户端或客户端版本太低 411 | 会根据 shouldOpenWeiboAppInstallPageIfNotInstalled 属性判断是否弹出安装/更新微博的对话框 412 | @param message 需要发送给微博客户端的消息对象 413 | @return 返回一个*自动释放的*WBSendMessageToWeiboRequest对象 414 | */ 415 | + (id)requestWithMessage:(WBMessageObject *)message; 416 | 417 | /** 418 | 返回一个 WBSendMessageToWeiboRequest 对象 419 | 420 | 当用户安装了可以支持微博客户端內分享的微博客户端时,会自动唤起微博并分享 421 | 当用户没有安装微博客户端或微博客户端过低无法支持通过客户端內分享的时候会自动唤起SDK內微博发布器 422 | 423 | @param message 需要发送给微博的消息对象 424 | @param authRequest 授权相关信息,与access_token二者至少有一个不为空,当access_token为空并且需要弹出SDK內发布器时会通过此信息先进行授权后再分享 425 | @param access_token 第三方应用之前申请的Token,当此值不为空并且无法通过客户端分享的时候,会使用此token进行分享。 426 | @return 返回一个*自动释放的*WBSendMessageToWeiboRequest对象 427 | */ 428 | + (id)requestWithMessage:(WBMessageObject *)message 429 | authInfo:(WBAuthorizeRequest *)authRequest 430 | access_token:(NSString *)access_token; 431 | 432 | @end 433 | 434 | /** 435 | WBSendMessageToWeiboResponse 436 | */ 437 | @interface WBSendMessageToWeiboResponse : WBBaseResponse 438 | 439 | /** 440 | 可能在分享过程中用户进行了授权操作,当此值不为空时,为用户相应授权信息 441 | */ 442 | @property (nonatomic,strong) WBAuthorizeResponse *authResponse; 443 | @end 444 | 445 | 446 | 447 | #pragma mark - MessageObject / ImageObject 448 | 449 | /** 450 | 微博客户端程序和第三方应用之间传递的消息结构 451 | 452 | 一个消息结构由三部分组成:文字、图片和多媒体数据。三部分内容中至少有一项不为空,图片和多媒体数据不能共存。(新版的多图和视频属于图片数据,并且图片和视频也不能共存) 453 | */ 454 | @interface WBMessageObject : NSObject 455 | 456 | /** 457 | 消息的文本内容 458 | 459 | @warning 长度小于2000个汉字 460 | */ 461 | @property (nonatomic, strong) NSString *text; 462 | 463 | /** 464 | 消息的图片内容 465 | 466 | @see WBImageObject 467 | */ 468 | @property (nonatomic, strong) WBImageObject *imageObject; 469 | 470 | /** 471 | 消息的多媒体内容 472 | 473 | @see WBBaseMediaObject 474 | */ 475 | @property (nonatomic, strong) WBBaseMediaObject *mediaObject; 476 | 477 | /** 478 | 消息的视频内容 479 | 480 | @see WBVideoObject 481 | */ 482 | @property (nonatomic, strong) WBNewVideoObject *videoObject; 483 | /** 484 | 返回一个 WBMessageObject 对象 485 | 486 | @return 返回一个*自动释放的*WBMessageObject对象 487 | */ 488 | + (id)message; 489 | 490 | @end 491 | 492 | /** 493 | 图片视频分享时错误枚举 494 | */ 495 | 496 | typedef NS_ENUM(NSInteger, WBSDKMediaTransferErrorCode) 497 | { 498 | WBSDKMediaTransferAlbumPermissionError = 0,//相册权限 499 | WBSDKMediaTransferAlbumWriteError = 0,//相册写入错误 500 | WBSDKMediaTransferAlbumAssetTypeError = 0,//资源类型错误 501 | }; 502 | 503 | /** 504 | 图片视频分享协议 505 | */ 506 | @protocol WBMediaTransferProtocol 507 | 508 | /** 509 | 数据准备成功回调 510 | */ 511 | -(void)wbsdk_TransferDidReceiveObject:(id)object; 512 | 513 | /** 514 | 数据准备失败回调 515 | */ 516 | -(void)wbsdk_TransferDidFailWithErrorCode:(WBSDKMediaTransferErrorCode)errorCode andError:(NSError*)error; 517 | 518 | @end 519 | 520 | /** 521 | 消息中包含的图片数据对象 522 | */ 523 | @interface WBImageObject : NSObject 524 | 525 | /** 526 | 图片真实数据内容 527 | 528 | @warning 大小不能超过10M 529 | */ 530 | @property (nonatomic, strong) NSData *imageData; 531 | 532 | /** 533 | 是否分享到story 534 | */ 535 | @property (nonatomic) BOOL isShareToStory; 536 | 537 | /** 538 | 返回一个 WBImageObject 对象 539 | 540 | @return 返回一个*自动释放的*WBImageObject对象 541 | */ 542 | + (id)object; 543 | 544 | /** 545 | 返回一个 UIImage 对象 546 | 547 | @return 返回一个*自动释放的*UIImage对象 548 | */ 549 | - (UIImage *)image; 550 | 551 | 552 | /** 553 | 多图分享委托 554 | */ 555 | @property(nonatomic,weak)id delegate; 556 | 557 | /** 558 | 图片对象添加图片数组 559 | */ 560 | - (void)addImages:(NSArray*)imageArray; 561 | 562 | /** 563 | 图片对象添加照片数组 564 | */ 565 | - (void)addImageAssets:(NSArray*)assetArray; 566 | 567 | /** 568 | 多图最终传递对象 569 | */ 570 | -(NSArray*)finalAssetArray; 571 | 572 | @end 573 | 574 | @interface WBNewVideoObject : NSObject 575 | 576 | /** 577 | 返回一个 WBNewVideoObject 对象 578 | 579 | @return 返回一个*自动释放的*WBNewVideoObject对象 580 | */ 581 | + (id)object; 582 | 583 | /** 584 | 是否分享到story 585 | */ 586 | @property (nonatomic) BOOL isShareToStory; 587 | 588 | /** 589 | 多图分享委托 590 | */ 591 | @property(nonatomic,weak)id delegate; 592 | 593 | /** 594 | 视频对象添加视频 595 | */ 596 | -(void)addVideo:(NSURL*)videoUrl; 597 | 598 | /** 599 | 视频对象添加视频资源 600 | */ 601 | -(void)addVideoAsset:(PHAsset*)videoAsset; 602 | 603 | /** 604 | 视频最终传递对象 605 | */ 606 | -(NSString*)finalAsset; 607 | 608 | @end 609 | 610 | 611 | #pragma mark - Message Media Objects 612 | 613 | /** 614 | 消息中包含的多媒体数据对象基类,该类后期会被废弃,在发布器不再显示为linkcard样式,只显示为普通网络连接 615 | */ 616 | @interface WBBaseMediaObject : NSObject 617 | 618 | /** 619 | 对象唯一ID,用于唯一标识一个多媒体内容 620 | 621 | 当第三方应用分享多媒体内容到微博时,应该将此参数设置为被分享的内容在自己的系统中的唯一标识 622 | @warning 不能为空,长度小于255 623 | */ 624 | @property (nonatomic, strong) NSString *objectID; 625 | 626 | /** 627 | 多媒体内容标题 628 | @warning 不能为空且长度小于1k 629 | */ 630 | @property (nonatomic, strong) NSString *title; 631 | 632 | /** 633 | 多媒体内容描述 634 | @warning 长度小于1k 635 | */ 636 | @property (nonatomic, strong) NSString *description; 637 | 638 | /** 639 | 多媒体内容缩略图 640 | @warning 大小小于32k 641 | */ 642 | @property (nonatomic, strong) NSData *thumbnailData; 643 | 644 | /** 645 | 点击多媒体内容之后呼起第三方应用特定页面的scheme 646 | @warning 长度小于255 647 | */ 648 | @property (nonatomic, strong) NSString *scheme; 649 | 650 | /** 651 | 返回一个 WBBaseMediaObject 对象 652 | 653 | @return 返回一个*自动释放的*WBBaseMediaObject对象 654 | */ 655 | + (id)object; 656 | 657 | @end 658 | 659 | #pragma mark - Message WebPage Objects 660 | 661 | /** 662 | 消息中包含的网页数据对象 663 | */ 664 | @interface WBWebpageObject : WBBaseMediaObject 665 | 666 | /** 667 | 网页的url地址 668 | 669 | @warning 不能为空且长度不能超过255 670 | */ 671 | @property (nonatomic, strong) NSString *webpageUrl; 672 | 673 | @end 674 | 675 | 676 | -------------------------------------------------------------------------------- /ios/libWeiboSDK/libWeiboSDK.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yun77op/react-native-weibo/ebbaf5d8a4748526475266ecf7cadd1ec63ab6e8/ios/libWeiboSDK/libWeiboSDK.a -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rn-weibo", 3 | "version": "3.0.5", 4 | "description": "新浪微博登录和分享模块", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/yun77op/react-native-weibo.git" 12 | }, 13 | "keywords": [ 14 | "react-native", 15 | "ios", 16 | "android", 17 | "weibo", 18 | "sina", 19 | "share", 20 | "login" 21 | ], 22 | "author": "yun77op", 23 | "license": "ISC", 24 | "bugs": { 25 | "url": "https://github.com/yun77op/react-native-weibo/issues" 26 | }, 27 | "homepage": "https://github.com/yun77op/react-native-weibo#readme", 28 | "dependencies": { 29 | } 30 | } 31 | --------------------------------------------------------------------------------