This commit is contained in:
2020-02-25 22:39:44 +08:00
commit 94d30a7854
29 changed files with 3648 additions and 0 deletions

1
.npmignore Normal file
View File

@ -0,0 +1 @@
/android/build

172
README.md Normal file
View File

@ -0,0 +1,172 @@
# react-native-qq
React Native的QQ登录插件, react-native版本需要0.33.0及以上
## 如何安装
### 首先安装npm包
```bash
npm install react-native-qq --save
```
### 安装iOS工程
`node_modules/react-native-qq/ios/RCTQQAPI.xcodeproj`加入到工程中
在工程target的`Build Phases->Link Binary with Libraries`中加入`libRCTQQAPI.a、libiconv.tbd、libsqlite3.tbd、libz.tbd、libc++.tbd`
`Build Settings->Search Paths->Framework Search Paths` 中加入路径 `$(SRCROOT)/../node_modules/react-native-qq/ios/RCTQQAPI`
`Build Settings->Link->Other Linker Flags` 中加入 `-framework "TencentOpenAPI"`
`Apple LLVM 7.0 - Custom Compiler Flags->Link->Other C Flags`中加入 `-isystem "$(SRCROOT)/../node_modules/react-native-qq/ios/RCTQQAPI"`
在工程plist文件中加入qq白名单(ios9以上必须)
如果plist中没有 `LSApplicationQueriesSchemes`请先添加该项Type设置为Array。接着`LSApplicationQueriesSchemes`中添加子项:`mqqapi、mqq、mqqOpensdkSSoLogin、mqqconnect、mqqopensdkdataline、mqqopensdkgrouptribeshare、mqqopensdkfriend、mqqopensdkapi、mqqopensdkapiV2、mqqopensdkapiV3、mqzoneopensdk、wtloginmqq、wtloginmqq2、mqqwpa、mqzone、mqzonev2、mqzoneshare、wtloginqzone、mqzonewx、
mqzoneopensdkapiV2、mqzoneopensdkapi19、mqzoneopensdkapi、mqzoneopensdk、`
`Info->URL Types` 中增加QQ的scheme `Identifier` 设置为`qq`, `URL Schemes` 设置为你注册的QQ开发者账号中的APPID需要加前缀`tencent`,例如`tencent1104903684`
在你工程的`AppDelegate.m`文件中添加如下代码:
```
#import "../Libraries/LinkingIOS/RCTLinkingManager.h"
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [RCTLinkingManager application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
}
```
### 安装Android工程
`android/settings.gradle`里添加如下代码:
```
include ':react-native-qq'
project(':react-native-qq').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-qq/android')
```
`app/build.gradle`里添加如下代码:
```
compile project(':react-native-qq')
```
`android/app/build.gradle`里的`dependencies`结构中添加如下代码:
```
dependencies{
... // 原本的代码
compile project(':react-native-qq')
}
```
`android/app/build.gradle`defaultConfig栏目下添加如下代码
```
manifestPlaceholders = [
QQ_APPID: "<平台申请的APPID>"
]
```
以后如果需要修改APPID只需要修改此一处。
`android/app/src/main/java/<你的包名>/MainApplication.java`中添加如下两行:
```java
...
import cn.reactnative.modules.qq.QQPackage; // 在public class MainApplication之前import
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
protected boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
         new QQPackage(), // 然后添加这一行
new MainReactPackage()
);
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
}
```
另外确保你的MainActivity.java中有`onActivityResult`的实现:
```java
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
mReactInstanceManager.onActivityResult(requestCode, resultCode, data);
}
```
## 如何使用
### 引入包
```
import * as QQAPI from 'react-native-qq';
```
### API
#### QQAPI.login([scopes])
- scopes: 登录所申请的权限默认为get_simple_userinfo。 需要多个权限时,以逗号分隔。
调用QQ登录可能会跳转到QQ应用或者打开一个网页浏览器以供用户登录。在本次login返回前所有接下来的login调用都会直接失败。
返回一个`Promise`对象。成功时的回调为一个类似这样的对象:
```javascript
{
"access_token": "CAF0085A2AB8FDE7903C97F4792ECBC3",
"openid": "0E00BA738F6BB55731A5BBC59746E88D"
"expires_in": "1458208143094.6"
"oauth_consumer_key": "12345"
}
```
#### QQAPI.shareToQQ(data)
分享到QQ好友参数同QQAPI.shareToQzone返回一个`Promise`对象
#### QQAPI.shareToQzone(data)
分享到QZone参数为一个object可以有如下的形式
```javascript
// 分享图文消息
{
type: 'news',
title: 分享标题,
description: 描述,
webpageUrl: 网页地址,
imageUrl: 远程图片地址,
}
// 其余格式尚未实现。
```
## 常见问题
#### Android: 调用QQAPI.login()没有反应
通常出现这个原因是因为Manifest没有配置好检查Manifest中有关Activity的配置。
#### Android: 已经成功激活QQ登录但回调没有被执行
通常出现这个原因是因为MainActivity.java中缺少onActivityResult的调用。

33
android/build.gradle Normal file
View File

@ -0,0 +1,33 @@
apply plugin: 'com.android.library'
def safeExtGet(prop, fallback) {
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}
android {
compileSdkVersion safeExtGet("compileSdkVersion", 28)
defaultConfig {
minSdkVersion safeExtGet('minSdkVersion', 16)
targetSdkVersion safeExtGet('targetSdkVersion', 28)
versionCode 1
versionName "1.0"
ndk {
abiFilters "armeabi-v7a", "x86"
}
}
}
repositories {
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
}
dependencies {
implementation 'com.facebook.react:react-native:+'
implementation files('libs/mta-sdk-1.6.2.jar')
implementation files('libs/open_sdk_r2973327_lite.jar')
}

BIN
android/libs/mta-sdk-1.6.2.jar Executable file

Binary file not shown.

Binary file not shown.

BIN
android/libs/open_sdk_r5756.jar Executable file

Binary file not shown.

View File

@ -0,0 +1,28 @@
<manifest
package="cn.reactnative.modules.qq"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application>
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />
<meta-data android:name="QQ_APPID" android:value="${QQ_APPID}"/>
<activity
android:name="com.tencent.tauth.AuthActivity"
android:noHistory="true"
android:launchMode="singleTask" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="tencent${QQ_APPID}" />
</intent-filter>
</activity>
<activity android:name="com.tencent.connect.common.AssistActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:configChanges="orientation|keyboardHidden|screenSize"
/>
</application>
</manifest>

View File

@ -0,0 +1,260 @@
package cn.reactnative.modules.qq;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.app.Activity;
import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.RCTNativeAppEventEmitter;
import com.tencent.connect.common.Constants;
import com.tencent.connect.share.QQShare;
import com.tencent.tauth.IUiListener;
import com.tencent.tauth.Tencent;
import com.tencent.tauth.UiError;
import org.json.JSONObject;
import java.util.Date;
/**
* Created by tdzl2_000 on 2015-10-10.
*
* Modified by Renguang Dong on 2016-05-25.
*/
public class QQModule extends ReactContextBaseJavaModule implements IUiListener, ActivityEventListener {
private String appId;
private Tencent api;
private final static String INVOKE_FAILED = "QQ API invoke returns false.";
private boolean isLogin;
private static final String RCTQQShareTypeNews = "news";
private static final String RCTQQShareTypeImage = "image";
private static final String RCTQQShareTypeText = "text";
private static final String RCTQQShareTypeVideo = "video";
private static final String RCTQQShareTypeAudio = "audio";
private static final String RCTQQShareType = "type";
private static final String RCTQQShareText = "text";
private static final String RCTQQShareTitle = "title";
private static final String RCTQQShareDescription = "description";
private static final String RCTQQShareWebpageUrl = "webpageUrl";
private static final String RCTQQShareImageUrl = "imageUrl";
private static final int SHARE_RESULT_CODE_SUCCESSFUL = 0;
private static final int SHARE_RESULT_CODE_FAILED = 1;
private static final int SHARE_RESULT_CODE_CANCEL = 2;
public QQModule(ReactApplicationContext context) {
super(context);
ApplicationInfo appInfo = null;
try {
appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException e) {
throw new Error(e);
}
if (!appInfo.metaData.containsKey("QQ_APPID")){
throw new Error("meta-data QQ_APPID not found in AndroidManifest.xml");
}
this.appId = appInfo.metaData.get("QQ_APPID").toString();
}
@Override
public void initialize() {
super.initialize();
if (api == null) {
api = Tencent.createInstance(appId, getReactApplicationContext().getApplicationContext());
}
getReactApplicationContext().addActivityEventListener(this);
}
@Override
public void onCatalystInstanceDestroy() {
if (api != null){
api = null;
}
getReactApplicationContext().removeActivityEventListener(this);
super.onCatalystInstanceDestroy();
}
@Override
public String getName() {
return "RCTQQAPI";
}
@ReactMethod
public void isQQInstalled(Promise promise) {
if (api.isSupportSSOLogin(getCurrentActivity())) {
promise.resolve(true);
}
else {
promise.reject("not installed");
}
}
@ReactMethod
public void isQQSupportApi(Promise promise) {
if (api.isSupportSSOLogin(getCurrentActivity())) {
promise.resolve(true);
}
else {
promise.reject("not support");
}
}
@ReactMethod
public void login(String scopes, Promise promise){
this.isLogin = true;
if (!api.isSessionValid()){
api.login(getCurrentActivity(), scopes == null ? "get_simple_userinfo" : scopes, this);
promise.resolve(null);
} else {
promise.reject(INVOKE_FAILED);
}
}
@ReactMethod
public void shareToQQ(ReadableMap data, Promise promise){
this._shareToQQ(data, 0);
promise.resolve(null);
}
@ReactMethod
public void shareToQzone(ReadableMap data, Promise promise){
this._shareToQQ(data, 1);
promise.resolve(null);
}
private void _shareToQQ(ReadableMap data, int scene) {
this.isLogin = false;
Bundle bundle = new Bundle();
if (data.hasKey(RCTQQShareTitle)){
bundle.putString(QQShare.SHARE_TO_QQ_TITLE, data.getString(RCTQQShareTitle));
}
if (data.hasKey(RCTQQShareDescription)){
bundle.putString(QQShare.SHARE_TO_QQ_SUMMARY, data.getString(RCTQQShareDescription));
}
if (data.hasKey(RCTQQShareWebpageUrl)){
bundle.putString(QQShare.SHARE_TO_QQ_TARGET_URL, data.getString(RCTQQShareWebpageUrl));
}
if (data.hasKey(RCTQQShareImageUrl)){
bundle.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, data.getString(RCTQQShareImageUrl));
}
if (data.hasKey("appName")){
bundle.putString(QQShare.SHARE_TO_QQ_APP_NAME, data.getString("appName"));
}
String type = RCTQQShareTypeNews;
if (data.hasKey(RCTQQShareType)) {
type = data.getString(RCTQQShareType);
}
if (type.equals(RCTQQShareTypeNews)){
bundle.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT);
} else if (type.equals(RCTQQShareTypeImage)){
bundle.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_IMAGE);
bundle.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, data.getString(RCTQQShareImageUrl));
} else if (type.equals(RCTQQShareTypeAudio)) {
bundle.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_AUDIO);
if (data.hasKey("flashUrl")){
bundle.putString(QQShare.SHARE_TO_QQ_AUDIO_URL, data.getString("flashUrl"));
}
} else if (type.equals("app")){
bundle.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_APP);
}
Log.e("QQShare", bundle.toString());
if (scene == 0 ) {
// Share to QQ.
bundle.putInt(QQShare.SHARE_TO_QQ_EXT_INT, QQShare.SHARE_TO_QQ_FLAG_QZONE_ITEM_HIDE);
api.shareToQQ(getCurrentActivity(), bundle, this);
}
else if (scene == 1) {
// Share to Qzone.
bundle.putInt(QQShare.SHARE_TO_QQ_EXT_INT, QQShare.SHARE_TO_QQ_FLAG_QZONE_AUTO_OPEN);
api.shareToQQ(getCurrentActivity(), bundle, this);
}
}
private String _getType() {
return (this.isLogin?"QQAuthorizeResponse":"QQShareResponse");
}
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
Tencent.onActivityResultData(requestCode, resultCode, data, this);
}
public void onNewIntent(Intent intent){
}
@Override
public void onComplete(Object o) {
WritableMap resultMap = Arguments.createMap();
if (isLogin) {
resultMap.putString("type", "QQAuthorizeResponse");
try {
JSONObject obj = (JSONObject) (o);
resultMap.putInt("errCode", 0);
resultMap.putString("openid", obj.getString(Constants.PARAM_OPEN_ID));
resultMap.putString("access_token", obj.getString(Constants.PARAM_ACCESS_TOKEN));
resultMap.putString("oauth_consumer_key", this.appId);
resultMap.putDouble("expires_in", (new Date().getTime() + obj.getLong(Constants.PARAM_EXPIRES_IN)));
} catch (Exception e){
WritableMap map = Arguments.createMap();
map.putInt("errCode", Constants.ERROR_UNKNOWN);
map.putString("errMsg", e.getLocalizedMessage());
getReactApplicationContext()
.getJSModule(RCTNativeAppEventEmitter.class)
.emit("QQ_Resp", map);
}
} else {
resultMap.putString("type", "QQShareResponse");
resultMap.putInt("errCode", SHARE_RESULT_CODE_SUCCESSFUL);
resultMap.putString("message", "Share successfully.");
}
this.resolvePromise(resultMap);
}
@Override
public void onError(UiError uiError) {
WritableMap resultMap = Arguments.createMap();
resultMap.putInt("errCode", SHARE_RESULT_CODE_FAILED);
resultMap.putString("message", "Share failed." + uiError.errorDetail);
this.resolvePromise(resultMap);
}
@Override
public void onCancel() {
WritableMap resultMap = Arguments.createMap();
resultMap.putInt("errCode", SHARE_RESULT_CODE_CANCEL);
resultMap.putString("message", "Share canceled.");
this.resolvePromise(resultMap);
}
private void resolvePromise(ReadableMap resultMap) {
getReactApplicationContext()
.getJSModule(RCTNativeAppEventEmitter.class)
.emit("QQ_Resp", resultMap);
}
}

View File

@ -0,0 +1,33 @@
package cn.reactnative.modules.qq;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* Created by tdzl2_000 on 2015-10-10.
*/
public class QQPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Arrays.asList(new NativeModule[]{
// Modules from third-party
new QQModule(reactContext),
});
}
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}

77
index.js Normal file
View File

@ -0,0 +1,77 @@
/**
* Created by Yun on 2015-12-12.
*/
import {NativeModules, NativeAppEventEmitter} from 'react-native';
const {QQAPI} = NativeModules;
function translateError(err, result) {
if (!err) {
return this.resolve(result);
}
if (typeof err === 'object') {
if (err instanceof Error) {
return this.reject(ret);
}
return this.reject(Object.assign(new Error(err.message), { errCode: err.errCode }));
} else if (typeof err === 'string') {
return this.reject(new Error(err));
}
this.reject(Object.assign(new Error(), { origin: err }));
}
export const isQQInstalled = QQAPI.isQQInstalled;
export const isQQSupportApi = QQAPI.isQQSupportApi;
// Save callback and wait for future event.
let savedCallback = undefined;
function waitForResponse(type) {
return new Promise((resolve, reject) => {
if (savedCallback) {
savedCallback('User canceled.');
}
savedCallback = result => {
if (result.type !== type) {
return;
}
savedCallback = undefined;
if (result.errCode !== 0) {
const err = new Error(result.errMsg);
err.errCode = result.errCode;
reject(err);
} else {
const {type, ...r} = result
resolve(r);
}
};
});
}
NativeAppEventEmitter.addListener('QQ_Resp', resp => {
const callback = savedCallback;
savedCallback = undefined;
callback && callback(resp);
});
export function login(scopes) {
return QQAPI.login(scopes)
.then(() => waitForResponse("QQAuthorizeResponse"));
}
export function shareToQQ(data={}) {
return QQAPI.shareToQQ(data)
.then(() => waitForResponse("QQShareResponse"));
}
export function shareToQzone(data={}) {
return QQAPI.shareToQzone(data)
.then(() => waitForResponse("QQShareResponse"));
}
export function logout(){
QQAPI.logout()
}

View File

@ -0,0 +1,15 @@
//
// RCTQQAPI.debug.xcconfig
// RCTQQAPI
//
// Created by LvBingru on 12/18/15.
// Copyright © 2015 erica. All rights reserved.
//
FRAMEWORK_SEARCH_PATHS = $(inherited) "${QQAPI_ROOT}/RCTQQAPI"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited)
HEADER_SEARCH_PATHS = $(inherited) "${QQAPI_ROOT}/RCTQQAPI"
LIBRARY_SEARCH_PATHS = $(inherited)
OTHER_CFLAGS = $(inherited) -isystem "${QQAPI_ROOT}/RCTQQAPI/"
OTHER_LDFLAGS = $(inherited) -ObjC -weak_library /usr/lib/libz.dylib -l"c++" -l"c++abi" -l"iconv" -l"sqlite3" -l"stdc++" -l"z" -framework "CoreGraphics" -framework "CoreTelephony" -framework "CoreText" -framework "CoreVideo" -framework "Foundation" -framework "Security" -framework "SystemConfiguration" -framework "TencentOpenAPI"
QQAPI_ROOT = ${SRCROOT}

View File

@ -0,0 +1,15 @@
//
// RCTQQAPI.release.xcconfig
// RCTQQAPI
//
// Created by LvBingru on 12/18/15.
// Copyright © 2015 erica. All rights reserved.
//
FRAMEWORK_SEARCH_PATHS = $(inherited) "${QQAPI_ROOT}/RCTQQAPI"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited)
HEADER_SEARCH_PATHS = $(inherited) "${QQAPI_ROOT}/RCTQQAPI"
LIBRARY_SEARCH_PATHS = $(inherited)
OTHER_CFLAGS = $(inherited) -isystem "${QQAPI_ROOT}/RCTQQAPI/"
OTHER_LDFLAGS = $(inherited) -ObjC -weak_library /usr/lib/libz.dylib -l"c++" -l"c++abi" -l"iconv" -l"sqlite3" -l"stdc++" -l"z" -framework "CoreGraphics" -framework "CoreTelephony" -framework "CoreText" -framework "CoreVideo" -framework "Foundation" -framework "Security" -framework "SystemConfiguration" -framework "TencentOpenAPI"
QQAPI_ROOT = ${SRCROOT}

View File

@ -0,0 +1,286 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
913932201C232D310085E3BA /* RCTQQAPI.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9139321F1C232D310085E3BA /* RCTQQAPI.h */; };
913932221C232D310085E3BA /* RCTQQAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = 913932211C232D310085E3BA /* RCTQQAPI.m */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9139321A1C232D310085E3BA /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "include/$(PRODUCT_NAME)";
dstSubfolderSpec = 16;
files = (
913932201C232D310085E3BA /* RCTQQAPI.h in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
9139321C1C232D310085E3BA /* libRCTQQAPI.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTQQAPI.a; sourceTree = BUILT_PRODUCTS_DIR; };
9139321F1C232D310085E3BA /* RCTQQAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTQQAPI.h; sourceTree = "<group>"; };
913932211C232D310085E3BA /* RCTQQAPI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTQQAPI.m; sourceTree = "<group>"; };
913932401C232ED60085E3BA /* TencentOpenAPI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = TencentOpenAPI.framework; sourceTree = "<group>"; };
9139325C1C233E370085E3BA /* RCTQQAPI.debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = RCTQQAPI.debug.xcconfig; sourceTree = "<group>"; };
9139325D1C233E480085E3BA /* RCTQQAPI.release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = RCTQQAPI.release.xcconfig; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
913932191C232D310085E3BA /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
913932131C232D310085E3BA = {
isa = PBXGroup;
children = (
9139325C1C233E370085E3BA /* RCTQQAPI.debug.xcconfig */,
9139325D1C233E480085E3BA /* RCTQQAPI.release.xcconfig */,
9139321E1C232D310085E3BA /* RCTQQAPI */,
9139321D1C232D310085E3BA /* Products */,
);
sourceTree = "<group>";
};
9139321D1C232D310085E3BA /* Products */ = {
isa = PBXGroup;
children = (
9139321C1C232D310085E3BA /* libRCTQQAPI.a */,
);
name = Products;
sourceTree = "<group>";
};
9139321E1C232D310085E3BA /* RCTQQAPI */ = {
isa = PBXGroup;
children = (
913932401C232ED60085E3BA /* TencentOpenAPI.framework */,
9139321F1C232D310085E3BA /* RCTQQAPI.h */,
913932211C232D310085E3BA /* RCTQQAPI.m */,
);
path = RCTQQAPI;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
9139321B1C232D310085E3BA /* RCTQQAPI */ = {
isa = PBXNativeTarget;
buildConfigurationList = 913932251C232D310085E3BA /* Build configuration list for PBXNativeTarget "RCTQQAPI" */;
buildPhases = (
913932181C232D310085E3BA /* Sources */,
913932191C232D310085E3BA /* Frameworks */,
9139321A1C232D310085E3BA /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = RCTQQAPI;
productName = RCTQQAPI;
productReference = 9139321C1C232D310085E3BA /* libRCTQQAPI.a */;
productType = "com.apple.product-type.library.static";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
913932141C232D310085E3BA /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0710;
ORGANIZATIONNAME = erica;
TargetAttributes = {
9139321B1C232D310085E3BA = {
CreatedOnToolsVersion = 7.1.1;
};
};
};
buildConfigurationList = 913932171C232D310085E3BA /* Build configuration list for PBXProject "RCTQQAPI" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 913932131C232D310085E3BA;
productRefGroup = 9139321D1C232D310085E3BA /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
9139321B1C232D310085E3BA /* RCTQQAPI */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
913932181C232D310085E3BA /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
913932221C232D310085E3BA /* RCTQQAPI.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
913932231C232D310085E3BA /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
913932241C232D310085E3BA /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
913932261C232D310085E3BA /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9139325C1C233E370085E3BA /* RCTQQAPI.debug.xcconfig */;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/RCTQQAPI",
);
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/../../react-native/React/**",
"$(SRCROOT)/../../react-native/Libraries/**",
"$(SRCROOT)/RCTQQAPI/**",
"$(BUILT_PRODUCTS_DIR)/include",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Debug;
};
913932271C232D310085E3BA /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9139325D1C233E480085E3BA /* RCTQQAPI.release.xcconfig */;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/RCTQQAPI",
);
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/../../react-native/React/**",
"$(SRCROOT)/../../react-native/Libraries/**",
"$(SRCROOT)/RCTQQAPI/**",
"$(BUILT_PRODUCTS_DIR)/include",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
913932171C232D310085E3BA /* Build configuration list for PBXProject "RCTQQAPI" */ = {
isa = XCConfigurationList;
buildConfigurations = (
913932231C232D310085E3BA /* Debug */,
913932241C232D310085E3BA /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
913932251C232D310085E3BA /* Build configuration list for PBXNativeTarget "RCTQQAPI" */ = {
isa = XCConfigurationList;
buildConfigurations = (
913932261C232D310085E3BA /* Debug */,
913932271C232D310085E3BA /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 913932141C232D310085E3BA /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0710"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9139321B1C232D310085E3BA"
BuildableName = "libRCTQQAPI.a"
BlueprintName = "RCTQQAPI"
ReferencedContainer = "container:RCTQQAPI.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9139321B1C232D310085E3BA"
BuildableName = "libRCTQQAPI.a"
BlueprintName = "RCTQQAPI"
ReferencedContainer = "container:RCTQQAPI.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9139321B1C232D310085E3BA"
BuildableName = "libRCTQQAPI.a"
BlueprintName = "RCTQQAPI"
ReferencedContainer = "container:RCTQQAPI.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>RCTQQAPI.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>13</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>9139321B1C232D310085E3BA</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0820"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9139321B1C232D310085E3BA"
BuildableName = "libRCTQQAPI.a"
BlueprintName = "RCTQQAPI"
ReferencedContainer = "container:RCTQQAPI.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9139321B1C232D310085E3BA"
BuildableName = "libRCTQQAPI.a"
BlueprintName = "RCTQQAPI"
ReferencedContainer = "container:RCTQQAPI.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9139321B1C232D310085E3BA"
BuildableName = "libRCTQQAPI.a"
BlueprintName = "RCTQQAPI"
ReferencedContainer = "container:RCTQQAPI.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>RCTQQAPI.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>9139321B1C232D310085E3BA</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

29
ios/RCTQQAPI/RCTQQAPI.h Normal file
View File

@ -0,0 +1,29 @@
//
// RCTQQAPI.h
// RNThirdShareMangager
//
// Created by LvBingru on 10/10/15.
// Copyright © 2015 erica. All rights reserved.
//
#if __has_include(<React/RCTBridge.h>)
#import <React/RCTBridgeModule.h>
#else
#import "RCTBridgeModule.h"
#endif
#define RCTQQShareTypeNews @"news"
#define RCTQQShareTypeImage @"image"
#define RCTQQShareTypeText @"text"
#define RCTQQShareTypeVideo @"video"
#define RCTQQShareTypeAudio @"audio"
#define RCTQQShareType @"type"
#define RCTQQShareTitle @"title"
#define RCTQQShareDescription @"description"
#define RCTQQShareWebpageUrl @"webpageUrl"
#define RCTQQShareImageUrl @"imageUrl"
@interface RCTQQAPI : NSObject<RCTBridgeModule>
@end

301
ios/RCTQQAPI/RCTQQAPI.m Normal file
View File

@ -0,0 +1,301 @@
//
// QQAPI.m
// RNThirdShareMangager
//
// Created by LvBingru on 10/10/15.
// Copyright © 2015 erica. All rights reserved.
//
#import "RCTQQAPI.h"
#import <TencentOpenAPI/TencentOAuth.h>
#import <TencentOpenAPI/TencentOAuthObject.h>
#import <TencentOpenAPI/QQApiInterface.h>
#import <TencentOpenAPI/QQApiInterfaceObject.h>
#if __has_include(<React/RCTBridge.h>)
#import <React/RCTLog.h>
#import <React/RCTBridge.h>
#import <React/RCTEventDispatcher.h>
#import <React/RCTImageLoader.h>
#else
#import "RCTLog.h"
#import "RCTEventDispatcher.h"
#import "RCTBridge.h"
#import "RCTImageLoader.h"
#endif
//#define NOT_REGISTERED (@"registerApp required.")
#define INVOKE_FAILED (@"QQ API invoke returns false.")
@interface RCTQQAPI()<QQApiInterfaceDelegate, TencentSessionDelegate> {
TencentOAuth* _qqapi;
}
@end
@implementation RCTQQAPI
@synthesize bridge = _bridge;
RCT_EXPORT_MODULE();
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
- (instancetype)init
{
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleOpenURL:) name:@"RCTOpenURLNotification" object:nil];
[self _autoRegisterAPI];
}
return self;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)handleOpenURL:(NSNotification *)note
{
NSDictionary *userInfo = note.userInfo;
NSString *url = userInfo[@"url"];
if ([TencentOAuth HandleOpenURL:[NSURL URLWithString:url]]) {
}
else {
[QQApiInterface handleOpenURL:[NSURL URLWithString:url] delegate:self];
}
}
RCT_EXPORT_METHOD(isQQInstalled:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
{
if ([QQApiInterface isQQInstalled]) {
resolve(@[[NSNull null]]);
}
else {
reject(@"-1",INVOKE_FAILED,nil);
}
}
RCT_EXPORT_METHOD(isQQSupportApi:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
{
if ([QQApiInterface isQQSupportApi]) {
resolve(@[[NSNull null]]);
}
else {
reject(@"-1",INVOKE_FAILED,nil);
}
}
RCT_EXPORT_METHOD(login:(NSString *)scopes resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
{
NSArray *scopeArray = nil;
if (scopes && scopes.length) {
scopeArray = [scopes componentsSeparatedByString:@","];
}
if (scopeArray == nil) {
scopeArray = @[@"get_user_info", @"get_simple_userinfo"];
}
BOOL success = [_qqapi authorize:scopeArray];
if (success) {
resolve(@[[NSNull null]]);
}
else {
reject(@"-1",INVOKE_FAILED,nil);
}
}
RCT_EXPORT_METHOD(shareToQQ:(NSDictionary *)data resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
{
[self _shareToQQWithData:data scene:0 resolve:resolve reject:reject];
}
RCT_EXPORT_METHOD(shareToQzone:(NSDictionary *)data resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
{
[self _shareToQQWithData:data scene:1 resolve:resolve reject:reject];
}
RCT_EXPORT_METHOD(logout)
{
[_qqapi logout:nil];
}
- (void)_shareToQQWithData:(NSDictionary *)aData scene:(int)aScene resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject{
NSString *imageUrl = aData[RCTQQShareImageUrl];
if (imageUrl.length && _bridge.imageLoader) {
CGSize size = CGSizeZero;
if (![aData[RCTQQShareType] isEqualToString:RCTQQShareTypeImage]) {
CGFloat thumbImageSize = 80;
size = CGSizeMake(thumbImageSize,thumbImageSize);
}
[_bridge.imageLoader loadImageWithURLRequest:[RCTConvert NSURLRequest:imageUrl] callback:^(NSError *error, UIImage *image) {
dispatch_async(dispatch_get_main_queue(), ^{
[self _shareToQQWithData:aData image:image scene:aScene resolve:resolve reject:reject];
});
}];
}
else {
[self _shareToQQWithData:aData image:nil scene:aScene resolve:resolve reject:reject];
}
}
- (void)_shareToQQWithData:(NSDictionary *)aData image:(UIImage*) image scene:(int)aScene resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
NSString *type = aData[RCTQQShareType];
NSString *title = aData[RCTQQShareTitle];
NSString *description= aData[RCTQQShareDescription];
NSString *imgPath = aData[RCTQQShareImageUrl];
NSString *webpageUrl = aData[RCTQQShareWebpageUrl]? :@"";
NSString *flashUrl = aData[@"flashUrl"];
QQApiObject *message = nil;
if (type.length <=0 || [type isEqualToString: RCTQQShareTypeNews]) {
message = [QQApiNewsObject
objectWithURL:[NSURL URLWithString:webpageUrl]
title:title
description:description
previewImageURL:[NSURL URLWithString:imgPath]];
}
else if ([type isEqualToString: RCTQQShareTypeText]) {
message = [QQApiTextObject objectWithText:description];
}
else if ([type isEqualToString: RCTQQShareTypeImage]) {
NSData *imgData = UIImageJPEGRepresentation(image, 1);
message = [QQApiImageObject objectWithData:imgData
previewImageData:imgData
title:title
description:description];
}
else if ([type isEqualToString: RCTQQShareTypeAudio]) {
QQApiAudioObject *audioObj = [QQApiAudioObject objectWithURL:[NSURL URLWithString:webpageUrl]
title:title
description:description
previewImageURL:[NSURL URLWithString:imgPath]];
if (flashUrl) {
[audioObj setFlashURL:[NSURL URLWithString:flashUrl]];
}
message = audioObj;
}
else if ([type isEqualToString: RCTQQShareTypeVideo]) {
QQApiVideoObject *videoObj = [QQApiVideoObject objectWithURL:[NSURL URLWithString:webpageUrl]
title:title
description:description
previewImageURL:[NSURL URLWithString:imgPath]];
if (flashUrl) {
[videoObj setFlashURL:[NSURL URLWithString:flashUrl]];
}
message = videoObj;
}
QQApiSendResultCode sent = EQQAPISENDFAILD;
if (message != nil) {
SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:message];
if (aScene == 0) {
sent = [QQApiInterface sendReq:req];
}
else {
sent = [QQApiInterface SendReqToQZone:req];
}
}
if (sent == EQQAPISENDSUCESS) {
resolve(@[[NSNull null]]);
}
else if (sent == EQQAPIAPPSHAREASYNC) {
resolve(@[[NSNull null]]);
}
else {
reject(@"-1",INVOKE_FAILED,nil);
}
}
- (void)_autoRegisterAPI
{
NSString *appId = nil;
NSArray *list = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleURLTypes"];
for (NSDictionary *item in list) {
NSString *name = item[@"CFBundleURLName"];
if ([name isEqualToString:@"qq"]) {
NSArray *schemes = item[@"CFBundleURLSchemes"];
if (schemes.count > 0)
{
appId = [schemes[0] substringFromIndex:@"tencent".length];
break;
}
}
}
_qqapi = [[TencentOAuth alloc] initWithAppId:appId andDelegate:self];
}
#pragma mark - qq delegate
- (void)onReq:(QQBaseReq *)req
{
}
- (void)onResp:(QQBaseResp *)resp
{
if ([resp isKindOfClass:[SendMessageToQQResp class]]) {
}
NSMutableDictionary *body = @{@"type":@"QQShareResponse"}.mutableCopy;
body[@"errMsg"] = resp.errorDescription;
if (resp.errorDescription) {
body[@"errCode"] = @(-1);
}
else {
body[@"errCode"] = @(0);
}
body[@"result"] =resp.result;
body[@"extendInfo"] =resp.extendInfo;
[self.bridge.eventDispatcher sendAppEventWithName:@"QQ_Resp" body:body];
}
- (void)isOnlineResponse:(NSDictionary *)response
{
}
#pragma mark - oauth delegate
- (void)tencentDidLogin
{
NSMutableDictionary *body = @{@"type":@"QQAuthorizeResponse"}.mutableCopy;
body[@"errCode"] = @(0);
body[@"openid"] = _qqapi.openId;
body[@"access_token"] = _qqapi.accessToken;
body[@"expires_in"] = @([_qqapi.expirationDate timeIntervalSince1970]*1000);
body[@"oauth_consumer_key"] =_qqapi.appId;
[self.bridge.eventDispatcher sendAppEventWithName:@"QQ_Resp" body:body];
}
- (void)tencentDidNotLogin:(BOOL)cancelled
{
NSMutableDictionary *body = @{@"type":@"QQAuthorizeResponse"}.mutableCopy;
body[@"errCode"] = @(-1);
if (cancelled) {
body[@"errMsg"] = @"login canceled";
}
else {
body[@"errMsg"] = @"login failed";
}
[self.bridge.eventDispatcher sendAppEventWithName:@"QQ_Resp" body:body];
}
- (void)tencentDidNotNetWork
{
}
@end

View File

@ -0,0 +1,158 @@
///
/// \file QQApiInterface.h
/// \brief QQApi接口简化封装
///
/// Created by Tencent on 12-5-15.
/// Copyright (c) 2012年 Tencent. All rights reserved.
///
#import <Foundation/Foundation.h>
#import "QQApiInterfaceObject.h"
typedef void (^sendResultBlock)(NSDictionary *result);
/**
\brief 处理来至QQ的请求及响应的回调协议
*/
@protocol QQApiInterfaceDelegate <NSObject>
/**
处理来至QQ的请求
*/
- (void)onReq:(QQBaseReq *)req;
/**
处理来至QQ的响应
*/
- (void)onResp:(QQBaseResp *)resp;
/**
处理QQ在线状态的回调
*/
- (void)isOnlineResponse:(NSDictionary *)response;
@end
/**
\brief 对QQApi的简单封装类
*/
@interface QQApiInterface : NSObject
/**
处理由手Q唤起的普通跳转请求
\param url 待处理的url跳转请求
\param delegate 第三方应用用于处理来至QQ请求及响应的委托对象
\return 跳转请求处理结果YES表示成功处理NO表示不支持的请求协议或处理失败
*/
+ (BOOL)handleOpenURL:(NSURL *)url delegate:(id<QQApiInterfaceDelegate>)delegate;
/**
处理由手Q唤起的universallink跳转请求
\param universallink 待处理的universallink跳转请求
\param delegate 第三方应用用于处理来至QQ请求及响应的委托对象
\return 跳转请求处理结果YES表示成功处理NO表示不支持的请求协议或处理失败
*/
+ (BOOL)handleOpenUniversallink:(NSURL*)universallink delegate:(id<QQApiInterfaceDelegate>)delegate;
/**
向手Q发起分享请求
\param req 分享内容的请求
\return 请求发送结果码
*/
+ (QQApiSendResultCode)sendReq:(QQBaseReq *)req;
/**
向手Q QZone结合版发起分享请求
\note H5分享只支持单张网络图片的传递
\param req 分享内容的请求
\return 请求发送结果码
*/
+ (QQApiSendResultCode)SendReqToQZone:(QQBaseReq *)req;
/**
向手Q发起设置QQ头像
\param req 分享内容的请求
\return 请求发送结果码
*/
+ (QQApiSendResultCode)sendMessageToQQAvatarWithReq:(QQBaseReq*)req;
/**
向手Q发起组图分享到表情收藏
\param req 分享内容的请求
\return 请求发送结果码
*/
+ (QQApiSendResultCode)sendMessageToFaceCollectionWithReq:(QQBaseReq*)req;
/**
检测是否已安装QQ
\return 如果QQ已安装则返回YES否则返回NO
\note SDK目前已经支持QQ、TIM授权登录及分享功能 会按照QQ>TIM的顺序进行调用。
只要用户安装了QQ、TIM中任意一个应用都可为第三方应用进行授权登录、分享功能。
第三方应用在接入SDK时不需要判断是否安装QQ、TIM。若有判断安装QQ、TIM的逻辑建议移除。
*/
+ (BOOL)isQQInstalled;
/**
检测是否已安装TIM
\return 如果TIM已安装则返回YES否则返回NO
\note SDK目前已经支持QQ、TIM授权登录及分享功能 会按照QQ>TIM的顺序进行调用。
只要用户安装了QQ、TIM中任意一个应用都可为第三方应用进行授权登录、分享功能。
第三方应用在接入SDK时不需要判断是否安装QQ、TIM。若有判断安装QQ、TIM的逻辑建议移除。
*/
+ (BOOL)isTIMInstalled;
/**
检测QQ是否支持API调用
\return 如果当前安装QQ版本支持API调用则返回YES否则返回NO
*/
+ (BOOL)isQQSupportApi;
/**
检测TIM是否支持API调用
\return 如果当前安装TIM版本支持API调用则返回YES否则返回NO
*/
+ (BOOL)isTIMSupportApi __attribute__((deprecated("已过期, 建议删除调用调用地方用YES替代。")));
/**
检测是否支持分享
\return 如果当前已安装QQ且QQ版本支持API调用 或者 当前已安装TIM且TIM版本支持API调用则返回YES否则返回NO
*/
+ (BOOL)isSupportShareToQQ;
/**
检测是否支持分享到QQ结合版QZone
\return 如果当前已安装QQ且QQ版本支持API调用则返回YES否则返回NO
*/
+ (BOOL)isSupportPushToQZone;
/**
启动QQ
\return 成功返回YES否则返回NO
*/
+ (BOOL)openQQ;
/**
启动TIM
\return 成功返回YES否则返回NO
*/
+ (BOOL)openTIM;
/**
获取QQ下载地址
如果App通过<code>QQApiInterface#isQQInstalled</code>和<code>QQApiInterface#isQQSupportApi</code>检测发现QQ没安装或当前版本QQ不支持API调用可引导用户通过打开此链接下载最新版QQ。
\return iPhoneQQ下载地址
*/
+ (NSString *)getQQInstallUrl;
/**
获取TIM下载地址
如果App通过<code>QQApiInterface#isTIMInstalled</code>检测发现TIM没安装或当前版本TIM不支持API调用可引导用户通过打开此链接下载最新版TIM。
\return iPhoneTIM下载地址
*/
+ (NSString *)getTIMInstallUrl;
@end

View File

@ -0,0 +1,645 @@
///
/// \file QQApiInterfaceObject.h
/// \brief QQApiInterface所依赖的请求及应答消息对象封装帮助类
///
/// Created by Tencent on 12-5-15.
/// Copyright (c) 2012年 Tencent. All rights reserved.
///
#ifndef QQApiInterface_QQAPIOBJECT_h
#define QQApiInterface_QQAPIOBJECT_h
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger,QQApiSendResultCode) {
EQQAPISENDSUCESS = 0,
EQQAPIQQNOTINSTALLED = 1, //QQ未安装
EQQAPIQQNOTSUPPORTAPI = 2, // QQ api不支持
EQQAPIMESSAGETYPEINVALID = 3,
EQQAPIMESSAGECONTENTNULL = 4,
EQQAPIMESSAGECONTENTINVALID = 5,
EQQAPIAPPNOTREGISTED = 6,
EQQAPIAPPSHAREASYNC = 7,
EQQAPIQQNOTSUPPORTAPI_WITH_ERRORSHOW = 8, //QQ api不支持 && SDK显示error提示已废弃
EQQAPIMESSAGEARKCONTENTNULL = 9, //ark内容为空
EQQAPIMESSAGE_MINI_CONTENTNULL = 10, //小程序参数为空
EQQAPISENDFAILD = -1, //发送失败
EQQAPISHAREDESTUNKNOWN = -2, //未指定分享到QQ或TIM
EQQAPITIMSENDFAILD = -3, //发送失败
EQQAPITIMNOTINSTALLED = 11, //TIM未安装
EQQAPITIMNOTSUPPORTAPI = 12, // TIM api不支持
EQQAPI_INCOMING_PARAM_ERROR = 13, // 外部传参错误
EQQAPI_THIRD_APP_GROUP_ERROR_APP_NOT_AUTHORIZIED = 14, // APP未获得授权
EQQAPI_THIRD_APP_GROUP_ERROR_CGI_FAILED = 15, // CGI请求失败
EQQAPI_THIRD_APP_GROUP_ERROR_HAS_BINDED = 16, // 该组织已经绑定群聊
EQQAPI_THIRD_APP_GROUP_ERROR_NOT_BINDED = 17, // 该组织尚未绑定群聊
EQQAPIQZONENOTSUPPORTTEXT = 10000, //qzone分享不支持text类型分享
EQQAPIQZONENOTSUPPORTIMAGE = 10001, //qzone分享不支持image类型分享
EQQAPIVERSIONNEEDUPDATE = 10002, //当前QQ版本太低需要更新至新版本才可以支持
ETIMAPIVERSIONNEEDUPDATE = 10004, //当前TIM版本太低需要更新至新版本才可以支持
};
#pragma mark - QQApiObject(分享对象类型)
// QQApiObject control flags
typedef NS_ENUM(NSUInteger,kQQAPICtrlFlag) {
kQQAPICtrlFlagQZoneShareOnStart = 0x01,
kQQAPICtrlFlagQZoneShareForbid = 0x02,
kQQAPICtrlFlagQQShare = 0x04,
kQQAPICtrlFlagQQShareFavorites = 0x08, //收藏
kQQAPICtrlFlagQQShareDataline = 0x10, //数据线
kQQAPICtrlFlagQQShareEnableArk = 0x20, //支持ARK
kQQAPICtrlFlagQQShareEnableMiniProgram = 0x40, //支持小程序
};
// 分享到QQ或TIM
typedef NS_ENUM(NSUInteger, ShareDestType) {
ShareDestTypeQQ = 0,
ShareDestTypeTIM,
};
//小程序的类型
typedef NS_ENUM(NSUInteger, MiniProgramType) {
MiniProgramType_Develop=0, // 开发版
MiniProgramType_Test=1, // 测试版
MiniProgramType_Online=3, // 正式版,默认
MiniProgramType_Preview=4, // 预览版
};
// QQApiObject
/** \brief 所有在QQ及插件间发送的数据对象的根类。
*/
__attribute__((visibility("default"))) @interface QQApiObject : NSObject
@property(nonatomic, retain) NSString* title; ///< 标题最长128个字符
@property(nonatomic, retain) NSString* description; ///<简要描述最长512个字符
@property(nonatomic, retain) NSString* universalLink; ///(>=3.3.7)支持第三方传入在互联开放平台注册的universallink
@property(nonatomic, assign) uint64_t cflag;
/*
* 分享到QQ/TIM
* SDK根据是否安装对应客户端进行判断判断顺序QQ > TIM
* 默认分享到QQ如果QQ未安装检测TIM是否安装
*/
@property (nonatomic, assign) ShareDestType shareDestType;
@end
// ArkObject
/** \brief 支持Ark的根类。
*/
__attribute__((visibility("default"))) @interface ArkObject : NSObject
@property(nonatomic,retain) NSString* arkData; ///< 显示Ark所需的数据json串长度暂不限制
@property(nonatomic,assign) QQApiObject* qqApiObject; ///<原有老版本的QQApiObject
- (id)initWithData:(NSString *)arkData qqApiObject:(QQApiObject*)qqApiObject;
+ (id)objectWithData:(NSString *)arkData qqApiObject:(QQApiObject*)qqApiObject;
@end
#pragma mark QQ小程序
//分享小程序消息 - QQ 8.0.8
__attribute__((visibility("default"))) @interface QQApiMiniProgramObject : NSObject
@property(nonatomic,retain) QQApiObject* qqApiObject; //原有老版本的QQApiObject
@property(nonatomic,retain) NSString* miniAppID; //必填小程序的AppId必须在QQ互联平台中将该小程序与分享的App绑定
@property(nonatomic,retain) NSString* miniPath; //必填,小程序的展示路径
@property(nonatomic,retain) NSString* webpageUrl; //必填,兼容低版本的网页链接
@property(nonatomic,assign) MiniProgramType miniprogramType; //非必填,小程序的类型,默认正式版(3),可选测试版(1)、预览版(4)
@end
//唤起小程序 - QQ 8.1.8
__attribute__((visibility("default"))) @interface QQApiLaunchMiniProgramObject : QQApiObject
@property(nonatomic,retain) NSString* miniAppID; //必填小程序的AppId必须在QQ互联平台中将该小程序与分享的App绑定
@property(nonatomic,retain) NSString* miniPath; //必填,小程序的展示路径
@property(nonatomic,assign) MiniProgramType miniprogramType; //非必填,小程序的类型,默认正式版(3),可选测试版(1)、开发版(0)
@end
// QQApiResultObject
/** \brief 用于请求回应的数据类型。
<h3>可能错误码及描述如下:</h3>
<TABLE>
<TR><TD>error</TD><TD>errorDescription</TD><TD>注释</TD></TR>
<TR><TD>0</TD><TD>nil</TD><TD>成功</TD></TR>
<TR><TD>-1</TD><TD>param error</TD><TD>参数错误</TD></TR>
<TR><TD>-2</TD><TD>group code is invalid</TD><TD>该群不在自己的群列表里面</TD></TR>
<TR><TD>-3</TD><TD>upload photo failed</TD><TD>上传图片失败</TD></TR>
<TR><TD>-4</TD><TD>user give up the current operation</TD><TD>用户放弃当前操作</TD></TR>
<TR><TD>-5</TD><TD>client internal error</TD><TD>客户端内部处理错误</TD></TR>
</TABLE>
*/
__attribute__((visibility("default"))) @interface QQApiResultObject : QQApiObject
@property(nonatomic,retain) NSString* error; ///<错误
@property(nonatomic,retain) NSString* errorDescription; ///<错误描述
@property(nonatomic,retain) NSString* extendInfo; ///<扩展信息
@end
// QQApiTextObject
/** \brief 文本对象
*/
@interface QQApiTextObject : QQApiObject
@property(nonatomic,retain)NSString* text; ///<文本内容必填最长1536个字符
-(id)initWithText:(NSString*)text; ///<初始化方法
+(id)objectWithText:(NSString*)text;///<工厂方法获取一个QQApiTextObject对象.
@end
// QQApiURLObject
typedef NS_ENUM(NSUInteger, QQApiURLTargetType) {
QQApiURLTargetTypeNotSpecified = 0x00,
QQApiURLTargetTypeAudio = 0x01,
QQApiURLTargetTypeVideo = 0x02,
QQApiURLTargetTypeNews = 0x03
};
/** @brief URL对象类型。
包括URL地址URL地址所指向的目标类型及预览图像。
*/
__attribute__((visibility("default"))) @interface QQApiURLObject : QQApiObject
/**
URL地址所指向的目标类型.
@note 参见QQApi.h 中的 QQApiURLTargetType 定义.
*/
@property(nonatomic)QQApiURLTargetType targetContentType;
@property(nonatomic,retain)NSURL* url; ///<URL地址,必填最长512个字符
@property(nonatomic,retain)NSData* previewImageData;///<预览图像数据最大1M字节
@property(nonatomic, retain) NSURL *previewImageURL; ///<预览图像URL **预览图像数据与预览图像URL可二选一
/**
初始化方法
*/
-(id)initWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageData:(NSData*)data targetContentType:(QQApiURLTargetType)targetContentType;
-(id)initWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageURL:(NSURL*)previewURL targetContentType:(QQApiURLTargetType)targetContentType;
/**
工厂方法,获取一个QQApiURLObject对象
*/
+(id)objectWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageData:(NSData*)data targetContentType:(QQApiURLTargetType)targetContentType;
+(id)objectWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageURL:(NSURL*)previewURL targetContentType:(QQApiURLTargetType)targetContentType;
@end
// QQApiExtendObject
/** @brief 扩展数据类型
*/
@interface QQApiExtendObject : QQApiObject
@property(nonatomic,retain) NSData* data;///<具体数据内容必填最大5M字节
@property(nonatomic,retain) NSData* previewImageData;///<预览图像最大1M字节
@property(nonatomic,retain) NSArray* imageDataArray;///图片数组(多图暂只支持分享到手机QQ收藏功能)
/**
初始化方法
@param data 数据内容
@param previewImageData 用于预览的图片
@param title 标题
@param description 此对象,分享的描述
*/
- (id)initWithData:(NSData*)data previewImageData:(NSData*)previewImageData title:(NSString*)title description:(NSString*)description;
/**
初始化方法
@param data 数据内容
@param title 标题
@param description 此对象,分享的描述
@param imageDataArray 发送的多张图片队列
*/
- (id)initWithData:(NSData *)data previewImageData:(NSData*)previewImageData title:(NSString *)title description:(NSString *)description imageDataArray:(NSArray *)imageDataArray;
/**
helper方法获取一个autorelease的<code>QQApiExtendObject</code>对象
@param data 数据内容
@param previewImageData 用于预览的图片
@param title 标题
@param description 此对象,分享的描述
@return
一个自动释放的<code>QQApiExtendObject</code>实例
*/
+ (id)objectWithData:(NSData*)data previewImageData:(NSData*)previewImageData title:(NSString*)title description:(NSString*)description;
/**
helper方法获取一个autorelease的<code>QQApiExtendObject</code>对象
@param data 数据内容
@param previewImageData 用于预览的图片
@param title 标题
@param description 此对象,分享的描述
@param imageDataArray 发送的多张图片队列
@return
一个自动释放的<code>QQApiExtendObject</code>实例
*/
+ (id)objectWithData:(NSData*)data previewImageData:(NSData*)previewImageData title:(NSString*)title description:(NSString*)description imageDataArray:(NSArray*)imageDataArray;
@end
// QQApiImageObject
/** @brief 图片对象
用于分享图片内容的对象,是一个指定为图片类型的<code>QQApiExtendObject</code>
*/
@interface QQApiImageObject : QQApiExtendObject
@end
// QQApiImageForQQAvatarObject
/** @brief 图片对象
用于设置QQ头像内容的对象是一个指定为图片类型的<code>QQApiExtendObject</code>
*/
@interface QQApiImageForQQAvatarObject : QQApiExtendObject
@end
/**
* @brief 视频对象
* 用于设置动态头像
* assetURL可传ALAsset的ALAssetPropertyAssetURL或者PHAsset的localIdentifier
从手Q返回的错误码
//第三方设置动态头像结果
@"ret=0"//设置成功
@"ret=-10&error_des=user cancel"//用户取消设置
@"ret=-11&error_des=pasteboard have no video data"//剪切板没有数据
@"ret=-12&error_des=export data failed"//从剪切板导出数据到本地失败
@"ret=-13&error_des=url param invalid"//sdk传递过来的数据有误
@"ret=-14&error_des=video param invalid"//视频的参数不符合要求检测第三方视频源方案1、分辨率跟480*480保持一致2、视频长度0.5s8s
@"ret=-15&error_des=app authorised failed"//应用鉴权失败
@"ret=-16&error_des=upload video failed"//设置头像,上传到后台失败
@"ret=-17&error_des=account diff"//账号不一致
*/
@interface QQApiVideoForQQAvatarObject : QQApiExtendObject
@property(nonatomic, retain) NSString *assetURL;
@end
// QQApiImageArrayForFaceCollectionObject
/** @brief 图片数组对象
用于分享图片组到表情收藏,是一个指定为图片类型的<code>QQApiObject</code>
*/
@interface QQApiImageArrayForFaceCollectionObject : QQApiObject
@property(nonatomic,retain) NSArray* imageDataArray;///图片数组
/**
初始化方法
@param imageDataArray 图片数组
*/
- (id)initWithImageArrayData:(NSArray*)imageDataArray;
/**
helper方法获取一个autorelease的<code>QQApiObject</code>对象
@param imageDataArray 发送的多张图片队列
@return
一个自动释放的<code>QQApiObject</code>实例
*/
+ (id)objectWithimageDataArray:(NSArray *)imageDataArray;
@end
// QQApiImageArrayForQZoneObject
/** @brief 图片对象
用于分享图片到空间,走写说说路径,是一个指定为图片类型的,当图片数组为空时,默认走文本写说说<code>QQApiObject</code>
*/
@interface QQApiImageArrayForQZoneObject : QQApiObject
@property(nonatomic,retain) NSArray* imageDataArray;///图片数组
@property(nonatomic,retain) NSDictionary* extMap; // 扩展字段
/**
初始化方法
@param imageDataArray 图片数组
@param title 写说说的内容,可以为空
@param extMap 扩展字段
*/
- (id)initWithImageArrayData:(NSArray*)imageDataArray title:(NSString*)title extMap:(NSDictionary *)extMap;
/**
helper方法获取一个autorelease的<code>QQApiExtendObject</code>对象
@param title 写说说的内容,可以为空
@param imageDataArray 发送的多张图片队列
@param extMap 扩展字段
@return
一个自动释放的<code>QQApiExtendObject</code>实例
*/
+ (id)objectWithimageDataArray:(NSArray*)imageDataArray title:(NSString*)title extMap:(NSDictionary *)extMap;
@end
// QQApiVideoForQZoneObject
/** @brief 视频对象
用于分享视频到空间,走写说说路径<code>QQApiObject</code>,assetURL和videoData两个参数必须设置至少一个参数如果assetURL设置了忽略videoData参数
@param assetURL可传ALAsset的ALAssetPropertyAssetURL或者PHAsset的localIdentifier
@param extMap 扩展字段
@param videoData 视频数据大小不超过50M
*/
@interface QQApiVideoForQZoneObject : QQApiObject
@property(nonatomic, retain) NSString *assetURL;
@property(nonatomic,retain) NSDictionary* extMap; // 扩展字段
@property(nonatomic,retain) NSData* videoData;
- (id)initWithAssetURL:(NSString*)assetURL title:(NSString*)title extMap:(NSDictionary *)extMap;
+ (id)objectWithAssetURL:(NSString*)assetURL title:(NSString*)title extMap:(NSDictionary *)extMap;
- (id)initWithVideoData:(NSData*)videoData title:(NSString*)title extMap:(NSDictionary *)extMap;
+ (id)objectWithVideoData:(NSData*)videoData title:(NSString*)title extMap:(NSDictionary *)extMap;
@end
// QQApiWebImageObject
/** @brief 图片对象
用于分享网络图片内容的对象是一个指定网络图片url的: 该类型只在2.9.0的h5分享中才支持
原有的手q分享是不支持该类型的。
*/
@interface QQApiWebImageObject : QQApiObject
@property(nonatomic, retain) NSURL *previewImageURL; ///<预览图像URL
/**
初始化方法
@param previewImageURL 用于预览的图片
@param title 标题
@param description 此对象,分享的描述
*/
- (id)initWithPreviewImageURL:(NSURL*)previewImageURL title:(NSString*)title description:(NSString*)description;
/**
helper方法获取一个autorelease的<code>QQApiWebImageObject</code>对象
@param previewImageURL 用于预览的图片
@param title 标题
@param description 此对象,分享的描述
*/
+ (id)objectWithPreviewImageURL:(NSURL*)previewImageURL title:(NSString*)title description:(NSString*)description;
@end
//QQApiFileObject
/** @brief 本地文件对象(暂只支持分享到手机QQ数据线功能)
用于分享文件内容的对象,是一个指定为文件类型的<code>QQApiExtendObject</code>
*/
@interface QQApiFileObject : QQApiExtendObject
{
NSString* _fileName;
}
@property(nonatomic, retain)NSString* fileName;
@end
// QQApiAudioObject
/** @brief 音频URL对象
用于分享目标内容为音频的URL的对象
*/
@interface QQApiAudioObject : QQApiURLObject
@property (nonatomic, retain) NSURL *flashURL; ///<音频URL地址最长512个字符
/**
获取一个autorelease的<code>QQApiAudioObject</code>
@param url 音频内容的目标URL
@param title 分享内容的标题
@param description 分享内容的描述
@param data 分享内容的预览图像
@note 如果url为空调用<code>QQApi#sendMessage:</code>时将返回FALSE
*/
+(id)objectWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageData:(NSData*)data;
/**
获取一个autorelease的<code>QQApiAudioObject</code>
@param url 音频内容的目标URL
@param title 分享内容的标题
@param description 分享内容的描述
@param previewURL 分享内容的预览图像URL
@note 如果url为空调用<code>QQApi#sendMessage:</code>时将返回FALSE
*/
+(id)objectWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageURL:(NSURL*)previewURL;
@end
// QQApiVideoObject
/** @brief 视频URL对象
用于分享目标内容为视频的URL的对象
QQApiVideoObject类型的分享目前在Android和PC QQ上接收消息时展现有待完善待手机QQ版本以后更新支持
目前如果要分享视频,推荐使用 QQApiNewsObject 类型
*/
@interface QQApiVideoObject : QQApiURLObject
@property (nonatomic, retain) NSURL *flashURL; ///<视频URL地址最长512个字符
/**
获取一个autorelease的<code>QQApiVideoObject</code>
@param url 视频内容的目标URL
@param title 分享内容的标题
@param description 分享内容的描述
@param data 分享内容的预览图像
@note 如果url为空调用<code>QQApi#sendMessage:</code>时将返回FALSE
*/
+(id)objectWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageData:(NSData*)data;
/**
获取一个autorelease的<code>QQApiVideoObject</code>
@param url 视频内容的目标URL
@param title 分享内容的标题
@param description 分享内容的描述
@param previewURL 分享内容的预览图像URL
@note 如果url为空调用<code>QQApi#sendMessage:</code>时将返回FALSE
*/
+(id)objectWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageURL:(NSURL*)previewURL;
@end
// QQApiNewsObject
/** @brief 新闻URL对象
用于分享目标内容为新闻的URL的对象
*/
@interface QQApiNewsObject : QQApiURLObject
/**
获取一个autorelease的<code>QQApiNewsObject</code>
@param url 视频内容的目标URL
@param title 分享内容的标题
@param description 分享内容的描述
@param data 分享内容的预览图像
@note 如果url为空调用<code>QQApi#sendMessage:</code>时将返回FALSE
*/
+(id)objectWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageData:(NSData*)data;
/**
获取一个autorelease的<code>QQApiNewsObject</code>
@param url 视频内容的目标URL
@param title 分享内容的标题
@param description 分享内容的描述
@param previewURL 分享内容的预览图像URL
@note 如果url为空调用<code>QQApi#sendMessage:</code>时将返回FALSE
*/
+(id)objectWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageURL:(NSURL*)previewURL;
@end
// QQApiCommonContentObject;
/** @brief 通用模板类型对象
用于分享一个固定显示模板的图文混排对象
@note 图片列表和文本列表不能同时为空
*/
@interface QQApiCommonContentObject : QQApiObject
/**
预定义的界面布局类型
*/
@property(nonatomic,assign) unsigned int layoutType;
@property(nonatomic,assign) NSData* previewImageData;///<预览图
@property(nonatomic,retain) NSArray* textArray;///<文本列表
@property(nonatomic,retain) NSArray* pictureDataArray;///<图片列表
+(id)objectWithLayoutType:(int)layoutType textArray:(NSArray*)textArray pictureArray:(NSArray*)pictureArray previewImageData:(NSData*)data;
/**
将一个NSDictionary对象转化为QQApiCommomContentObject如果无法转换则返回空
*/
+(id)objectWithDictionary:(NSDictionary*)dic;
-(NSDictionary*)toDictionary;
@end
// QQApiExtraServiceObject;
/**
@brief OpenSDK扩展支持的服务通用接口后续会扩充能力
@param serviceID [必选] 扩展支持的服务类型ID参考官方文档说明
@param openID [必选] 授权登录后对该用户的唯一标识
@param toUin [可选] 对方的QQ号码
@param extraInfo [可选] 扩展字段
@note 该接口的使用须先登录
*/
@interface QQApiExtraServiceObject : QQApiObject
@property (nonatomic,retain) NSString* serviceID;
@property (nonatomic,retain) NSString* openID;
@property (nonatomic,retain) NSString* toUin;
@property (nonatomic,retain) NSDictionary* extraInfo;
- (id)initWithOpenID:(NSString *)openID serviceID:(NSString *)serviceID;
+ (id)objecWithOpenID:(NSString *)openID serviceID:(NSString *)serviceID;
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Ad item object definition
////////////////////////////////////////////////////////////////////////////////////////////////////////////
/** @brief 广告数据对象
*/
@interface QQApiAdItem : NSObject
@property(nonatomic,retain) NSString* title; ///<名称
@property(nonatomic,retain) NSString* description;///<描述
@property(nonatomic,retain) NSData* imageData;///<广告图片
@property(nonatomic,retain) NSURL* target;///<广告目标链接
@end
#pragma mark - QQApi请求消息类型
/**
QQApi请求消息类型
*/
typedef NS_ENUM(NSUInteger, QQApiInterfaceReqType) {
EGETMESSAGEFROMQQREQTYPE = 0, ///< 手Q -> 第三方应用请求第三方应用向手Q发送消息
ESENDMESSAGETOQQREQTYPE = 1, ///< 第三方应用 -> 手Q第三方应用向手Q分享消息
ESHOWMESSAGEFROMQQREQTYPE = 2, ///< 手Q -> 第三方应用,请求第三方应用展现消息中的数据
ESENDMESSAGEARKTOQQREQTYPE = 3, ///< 第三方应用 -> 手Q第三方应用向手Q分享Ark消息
ESENDMESSAGE_MINI_TOQQREQTYPE = 4 ///< 第三方应用 -> 手Q第三方应用向手Q分享小程序消息
};
/**
QQApi应答消息类型
*/
typedef NS_ENUM(NSUInteger, QQApiInterfaceRespType) {
ESHOWMESSAGEFROMQQRESPTYPE = 0, ///< 第三方应用 -> 手Q第三方应用应答消息展现结果
EGETMESSAGEFROMQQRESPTYPE = 1, ///< 第三方应用 -> 手Q第三方应用回应发往手Q的消息
ESENDMESSAGETOQQRESPTYPE = 2 ///< 手Q -> 第三方应用手Q应答处理分享消息的结果
};
/**
QQApi请求消息基类
*/
@interface QQBaseReq : NSObject
/** 请求消息类型,参见\ref QQApiInterfaceReqType */
@property (nonatomic, assign) int type;
@end
/**
QQApi应答消息基类
*/
@interface QQBaseResp : NSObject
/** 请求处理结果 */
@property (nonatomic, copy) NSString* result;
/** 具体错误描述信息 */
@property (nonatomic, copy) NSString* errorDescription;
/** 应答消息类型,参见\ref QQApiInterfaceRespType */
@property (nonatomic, assign) int type;
/** 扩展信息 */
@property (nonatomic, assign) NSString* extendInfo;
@end
/**
GetMessageFromQQReq请求帮助类
*/
@interface GetMessageFromQQReq : QQBaseReq
/**
创建一个GetMessageFromQQReq请求实例
*/
+ (GetMessageFromQQReq *)req;
@end
@interface SendMessageToQQReq : QQBaseReq
/**
创建一个SendMessageToQQReq请求实例
\param message 具体分享消息实例
\return 新创建的SendMessageToQQReq请求实例
*/
+ (SendMessageToQQReq *)reqWithContent:(QQApiObject *)message;
/**
创建一个支持Ark的SendMessageToQQReq请求实例
\param message 具体分享消息实例
\return 新创建的SendMessageToQQReq请求实例
*/
+ (SendMessageToQQReq *)reqWithArkContent:(ArkObject *)message;
/**
* 创建一个支持小程序的消息请求实例
* @param miniMessage 小程序实例对象
* @return 消息请求实例
*/
+(SendMessageToQQReq*) reqWithMiniContent:(QQApiMiniProgramObject *)miniMessage;
/** 具体分享消息 */
@property (nonatomic, retain) QQApiObject *message;
/** 支持Ark的具体分享消息 */
@property (nonatomic, retain) ArkObject *arkMessage;
/** 支持小程序的具体分享消息 */
@property (nonatomic, retain) QQApiMiniProgramObject *miniMessage;
@end
/**
SendMessageToQQResp应答帮助类
*/
@interface SendMessageToQQResp : QQBaseResp
/**
创建一个SendMessageToQQResp应答实例
\param result 请求处理结果
\param errDesp 具体错误描述信息
\param extendInfo 扩展信息
\return 新创建的SendMessageToQQResp应答实例
*/
+ (SendMessageToQQResp *)respWithResult:(NSString *)result errorDescription:(NSString *)errDesp extendInfo:(NSString*)extendInfo;
@end
/**
ShowMessageFromQQReq请求帮助类
*/
@interface ShowMessageFromQQReq : QQBaseReq
/**
创建一个ShowMessageFromQQReq请求实例
\param message 具体待展现消息实例
\return 新创建的ShowMessageFromQQReq请求实例
*/
+ (ShowMessageFromQQReq *)reqWithContent:(QQApiObject *)message;
/** 具体待展现消息 */
@property (nonatomic, retain) QQApiObject *message;
@end
#endif

View File

@ -0,0 +1,494 @@
///
/// \file TencentOAuth.h
/// \brief QQ互联开放平台授权登录及相关开放接口实现类
///
/// Created by Tencent on 12-12-21.
/// Copyright (c) 2012年 Tencent. All rights reserved.
///
#import <UIKit/UIKit.h>
#import "sdkdef.h"
@protocol TencentSessionDelegate;
@protocol TencentLoginDelegate;
@protocol TencentApiInterfaceDelegate;
@protocol TencentWebViewDelegate;
@class TencentApiReq;
@class TencentApiResp;
typedef NS_ENUM(NSUInteger, TencentAuthorizeState) {
kTencentNotAuthorizeState,
kTencentSSOAuthorizeState,
kTencentWebviewAuthorzieState,
};
typedef NS_ENUM(NSUInteger, TencentAuthMode) {
kAuthModeClientSideToken,
kAuthModeServerSideCode,
};
#pragma mark - TencentOAuth(授权登录及相关开放接口调用)
/**
* \brief TencentOpenAPI授权登录及相关开放接口调用
*
* TencentOAuth实现授权登录逻辑以及相关开放接口的请求调用
*/
@interface TencentOAuth : NSObject
{
NSMutableDictionary* _apiRequests;
NSString* _accessToken;
NSDate* _expirationDate;
id<TencentSessionDelegate> _sessionDelegate;
NSString* _localAppId;
NSString* _openId;
NSString* _redirectURI;
NSArray* _permissions;
}
/** Access Token凭证用于后续访问各开放接口 */
@property(nonatomic, copy) NSString* accessToken;
/** Access Token的失效期 */
@property(nonatomic, copy) NSDate* expirationDate;
/** 已实现的开放接口的回调委托对象 */
@property(nonatomic, assign) id<TencentSessionDelegate> sessionDelegate;
/** 第三方应用在开发过程中设置的URLSchema用于浏览器登录后后跳到第三方应用 */
@property(nonatomic, copy) NSString* localAppId;
/** 用户授权登录后对该用户的唯一标识 */
@property(nonatomic, copy) NSString* openId;
/** 用户登录成功过后的跳转页面地址 */
@property(nonatomic, copy) NSString* redirectURI;
/** 第三方应用在互联开放平台申请的appID */
@property(nonatomic, retain) NSString* appId;
/** 第三方应用在互联开放平台注册的UniversalLink */
@property(nonatomic, retain) NSString* universalLink;
/** 主要是互娱的游戏设置uin */
@property(nonatomic, retain) NSString* uin;
/** 主要是互娱的游戏设置鉴定票据 */
@property(nonatomic, retain) NSString* skey;
/** 登陆透传的数据 */
@property(nonatomic, copy) NSDictionary* passData;
/** 授权方式(Client Side Token或者Server Side Code) */
@property(nonatomic, assign) TencentAuthMode authMode;
/** union id */
@property(nonatomic, retain) NSString* unionid;
/** 第三方在授权登录/分享 时选择 QQ还是TIM 。在授权前一定要指定其中一个类型*/
@property(nonatomic, assign) TencentAuthShareType authShareType;
/**
* 获取上次登录得到的token
*
**/
- (NSString *)getCachedToken;
/**
* 获取上次登录得到的openid
*
**/
- (NSString *)getCachedOpenID;
/**
* 获取上次登录的token过期日期
*
**/
- (NSDate *)getCachedExpirationDate;
/**
* 上次登录的token是否过期(本地判断)
**/
- (BOOL)isCachedTokenValid;
/**
* 删除上次登录登录的token信息
*
**/
- (BOOL)deleteCachedToken;
/**
* 用来获得当前sdk的版本号
* \return 返回sdk版本号
**/
+ (NSString*)sdkVersion;
/**
* 用来获得当前sdk的小版本号
* \return 返回sdk小版本号
**/
+ (NSString*)sdkSubVersion;
/**
* 用来获得当前sdk的是否精简版
* \return 返回YES表示精简版
**/
+ (BOOL)isLiteSDK;
/**
* 主要是用来帮助判断是否有登陆被发起,但是还没有过返回结果
* \return
* kTencentNotAuthorizeState:无授权
* kTencentSSOAuthorizeState:有人发起了sso授权但无返回
* kTencentWebviewAuthorzieState:有人发起了webview授权还未返回
**/
+ (TencentAuthorizeState *)authorizeState;
/**
* 用来获得当前手机qq的版本号
* \return 返回手机qq版本号
**/
+ (int)iphoneQQVersion __attribute__((deprecated("已过期, 建议删除调用")));
/**
* 用来获得当前手机TIM的版本号
* \return 返回手机qq版本号
**/
+ (int)iphoneTIMVersion __attribute__((deprecated("已过期, 建议删除调用")));
/**
* 初始化TencentOAuth对象
* \param appId 第三方应用在互联开放平台申请的唯一标识
* \param delegate 第三方应用用于接收请求返回结果的委托对象
* \return 初始化后的授权登录对象
*/
- (id)initWithAppId:(NSString *)appId
andDelegate:(id<TencentSessionDelegate>)delegate;
/**
* 初始化TencentOAuth对象>=3.3.7
* \param appId 第三方应用在互联开放平台申请的唯一标识
* \param universalLink 第三方应用在互联开放平台注册的universallink和bundleID一一对应
* \param delegate 第三方应用用于接收请求返回结果的委托对象
* \return 初始化后的授权登录对象
*/
- (id)initWithAppId:(NSString *)appId
andUniversalLink:(NSString *)universalLink
andDelegate:(id<TencentSessionDelegate>)delegate;
/**
* 判断用户手机上是否安装手机QQ
* \return YES:安装 NO:没安装
*
* \note SDK目前已经支持QQ、TIM授权登录及分享功能 会按照QQ>TIM的顺序进行调用。
* 只要用户安装了QQ、TIM中任意一个应用都可为第三方应用进行授权登录、分享功能。
* 第三方应用在接入SDK时不需要判断是否安装QQ、TIM。若有判断安装QQ、TIM的逻辑建议移除。
*/
+ (BOOL)iphoneQQInstalled;
/**
* 判断用户手机上是否安装手机TIM
* \return YES:安装 NO:没安装
*
* \note SDK目前已经支持QQ、TIM授权登录及分享功能 会按照QQ>TIM的顺序进行调用。
* 只要用户安装了QQ、TIM中任意一个应用都可为第三方应用进行授权登录、分享功能。
* 第三方应用在接入SDK时不需要判断是否安装QQ、TIM。若有判断安装QQ、TIM的逻辑建议移除。
*/
+ (BOOL)iphoneTIMInstalled;
/**
* 判断用户手机上的手机QQ是否支持SSO登录
* \return YES:支持 NO:不支持
*/
+ (BOOL)iphoneQQSupportSSOLogin __attribute__((deprecated("QQ版本均支持SSO登录。该接口已过期, 建议删除调用")));
/**
* 判断用户手机上的手机TIM是否支持SSO登录
* \return YES:支持 NO:不支持
*/
+ (BOOL)iphoneTIMSupportSSOLogin __attribute__((deprecated("TIM版本均支持SSO登录。该接口已过期, 建议删除调用")));
/**
* 登录授权
*
* \param permissions 授权信息列
*/
- (BOOL)authorize:(NSArray *)permissions;
/**
* 登录授权
* \param permissions 授权信息列表
* \param bInSafari 是否使用safari进行登录.<b>IOS SDK 1.3版本开始此参数废除</b>
*/
- (BOOL)authorize:(NSArray *)permissions
inSafari:(BOOL)bInSafari;
/**
* 登录授权
* \param permissions 授权信息列表
* \param localAppId 应用APPID
* \param bInSafari 是否使用safari进行登录.<b>IOS SDK 1.3版本开始此参数废除</b>
*/
- (BOOL)authorize:(NSArray *)permissions
localAppId:(NSString *)localAppId
inSafari:(BOOL)bInSafari;
/**
* 登录授权<web为二维码扫码方式>
*
* \param permissions 授权信息列
*/
- (BOOL)authorizeWithQRlogin:(NSArray *)permissions;
/**
* 增量授权,因用户没有授予相应接口调用的权限,需要用户确认是否授权
* \param permissions 需增量授权的信息列表
* \return 增量授权调用是否成功
*/
- (BOOL)incrAuthWithPermissions:(NSArray *)permissions;
/**
* 重新授权因token废除或失效导致接口调用失败需用户重新授权
* \param permissions 授权信息列表,同登录授权
* \return 授权调用是否成功
*/
- (BOOL)reauthorizeWithPermissions:(NSArray *)permissions;
/**
* 获取UnindID,可以根据UnindID的比较来确定OpenID是否属于同一个用户
* \return NO未登录信息不足YES条件满足发送请求成功请等待回调
*/
- (BOOL)RequestUnionId;
/**
* (静态方法)处理应用拉起协议
* \param url 处理被其他应用呼起时的逻辑
* \return 处理结果YES表示成功NO表示失败
*/
+ (BOOL)HandleOpenURL:(NSURL *)url;
/**
* (静态方法)sdk是否可以处理应用拉起协议
* \param url 处理被其他应用呼起时的逻辑
* \return 处理结果YES表示可以 NO表示不行
*/
+ (BOOL)CanHandleOpenURL:(NSURL *)url;
/**
* (静态方法)处理应用的UniversalLink拉起协议
* \param url 处理被其他应用呼起时的逻辑
* \return 处理结果YES表示成功NO表示失败
*/
+ (BOOL)HandleUniversalLink:(NSURL *)url;
/**
* (静态方法)sdk是否可以处理应用的Universallink拉起协议
* \param url 处理被其他应用呼起时的逻辑(应用的Universallink链接须满足官网注册时的格式要求)
* \return 处理结果YES表示可以 NO表示不行
* 注在调用其他Universallink相关处理接口之前均需进行此项判断
*/
+ (BOOL)CanHandleUniversalLink:(NSURL *)url;
/**
* (静态方法)获取TencentOAuth调用的上一次错误信息
*/
+ (NSString *)getLastErrorMsg;
/**
* 以Server Side Code模式授权登录时通过此接口获取返回的code值;
* 以Client Side Token模式授权登录时忽略此接口。
*/
- (NSString *)getServerSideCode;
/**
* 退出登录(退出登录后TecentOAuth失效需要重新初始化)
* \param delegate 第三方应用用于接收请求返回结果的委托对象
*/
- (void)logout:(id<TencentSessionDelegate>)delegate;
/**
* 判断登录态是否有效
* \return 处理结果YES表示有效NO表示无效请用户重新登录授权
*/
- (BOOL)isSessionValid;
/**
* 获取用户个人信息
* \return 处理结果YES表示API调用成功NO表示API调用失败登录态失败重新登录
*/
- (BOOL)getUserInfo;
/**
* 退出指定API调用
* \param userData 用户调用某条API的时候传入的保留参数
* \return 处理结果YES表示成功 NO表示失败
*/
- (BOOL)cancel:(id)userData;
/**
* CGI类任务创建接口
* \param apiURL CGI请求的URL地址
* \param method CGI请求方式"GET""POST"
* \param params CGI请求参数字典
* \param callback CGI请求结果的回调接口对象
* \return CGI请求任务实例用于取消任务返回nil代表任务创建失败
*/
- (TCAPIRequest *)cgiRequestWithURL:(NSURL *)apiURL method:(NSString *)method params:(NSDictionary *)params callback:(id<TCAPIRequestDelegate>)callback;
/**
* TencentOpenApi发送任务统一接口
* \param request 请求发送的任务
* \param callback 任务发送后的回调地址
*/
- (BOOL)sendAPIRequest:(TCAPIRequest *)request callback:(id<TCAPIRequestDelegate>)callback;
- (NSString *)getUserOpenID;
@end
#pragma mark - TencentLoginDelegate(授权登录回调协议)
/**
* \brief TencentLoginDelegate iOS Open SDK 1.3 API回调协议
*
* 第三方应用实现登录的回调协议
*/
@protocol TencentLoginDelegate <NSObject>
@required
/**
* 登录成功后的回调
*/
- (void)tencentDidLogin;
/**
* 登录失败后的回调
* \param cancelled 代表用户是否主动退出登录
*/
- (void)tencentDidNotLogin:(BOOL)cancelled;
/**
* 登录时网络有问题的回调
*/
- (void)tencentDidNotNetWork;
@optional
/**
* 登录时权限信息的获得
*/
- (NSArray *)getAuthorizedPermissions:(NSArray *)permissions withExtraParams:(NSDictionary *)extraParams;
/**
* unionID获得
*/
- (void)didGetUnionID;
/**
* 强制网页登录,包括账号密码登录和二维码登录
* return YES时就算本地有手Q也会打开web界面
*/
- (BOOL)forceWebLogin;
@end
#pragma mark - TencentSessionDelegate(开放接口回调协议)
/**
* \brief TencentSessionDelegate iOS Open SDK 1.3 API回调协议
*
* 第三方应用需要实现每条需要调用的API的回调协议
*/
@protocol TencentSessionDelegate<NSObject, TencentLoginDelegate,
TencentWebViewDelegate>
@optional
/**
* 退出登录的回调
*/
- (void)tencentDidLogout;
/**
* 因用户未授予相应权限而需要执行增量授权。在用户调用某个api接口时如果服务器返回操作未被授权则触发该回调协议接口由第三方决定是否跳转到增量授权页面让用户重新授权。
* \param tencentOAuth 登录授权对象。
* \param permissions 需增量授权的权限列表。
* \return 是否仍然回调返回原始的api请求结果。
* \note 不实现该协议接口则默认为不开启增量授权流程。若需要增量授权请调用\ref TencentOAuth#incrAuthWithPermissions: \n注意增量授权时用户可能会修改登录的帐号
*/
- (BOOL)tencentNeedPerformIncrAuth:(TencentOAuth *)tencentOAuth withPermissions:(NSArray *)permissions;
/**
* [该逻辑未实现]因token失效而需要执行重新登录授权。在用户调用某个api接口时如果服务器返回token失效则触发该回调协议接口由第三方决定是否跳转到登录授权页面让用户重新授权。
* \param tencentOAuth 登录授权对象。
* \return 是否仍然回调返回原始的api请求结果。
* \note 不实现该协议接口则默认为不开启重新登录授权流程。若需要重新登录授权请调用\ref TencentOAuth#reauthorizeWithPermissions: \n注意重新登录授权时用户可能会修改登录的帐号
*/
- (BOOL)tencentNeedPerformReAuth:(TencentOAuth *)tencentOAuth;
/**
* 用户通过增量授权流程重新授权登录token及有效期限等信息已被更新。
* \param tencentOAuth token及有效期限等信息更新后的授权实例对象
* \note 第三方应用需更新已保存的token及有效期限等信息。
*/
- (void)tencentDidUpdate:(TencentOAuth *)tencentOAuth;
/**
* 用户增量授权过程中因取消或网络问题导致授权失败
* \param reason 授权失败原因具体失败原因参见sdkdef.h文件中\ref UpdateFailType
*/
- (void)tencentFailedUpdate:(UpdateFailType)reason;
/**
* 获取用户个人信息回调
* \param response API返回结果具体定义参见sdkdef.h文件中\ref APIResponse
* \remarks 正确返回示例: \snippet example/getUserInfoResponse.exp success
* 错误返回示例: \snippet example/getUserInfoResponse.exp fail
*/
- (void)getUserInfoResponse:(APIResponse*) response;
/**
* 社交API统一回调接口
* \param response API返回结果具体定义参见sdkdef.h文件中\ref APIResponse
* \param message 响应的消息目前支持SendStory,AppInvitationAppChallengeAppGiftRequest
*/
- (void)responseDidReceived:(APIResponse*)response forMessage:(NSString *)message;
/**
* post请求的上传进度
* \param tencentOAuth 返回回调的tencentOAuth对象
* \param bytesWritten 本次回调上传的数据字节数
* \param totalBytesWritten 总共已经上传的字节数
* \param totalBytesExpectedToWrite 总共需要上传的字节数
* \param userData 用户自定义数据
*/
- (void)tencentOAuth:(TencentOAuth *)tencentOAuth didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite userData:(id)userData;
/**
* 通知第三方界面需要被关闭
* \param tencentOAuth 返回回调的tencentOAuth对象
* \param viewController 需要关闭的viewController
*/
- (void)tencentOAuth:(TencentOAuth *)tencentOAuth doCloseViewController:(UIViewController *)viewController;
@end
#pragma mark - TencentWebViewDelegate(H5登录webview旋转方向回调)
/**
* \brief TencentWebViewDelegate: H5登录webview旋转方向回调协议
*
* 第三方应用可以根据自己APP的旋转方向限制通过此协议设置
*/
@protocol TencentWebViewDelegate <NSObject>
@optional
- (BOOL) tencentWebViewShouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation;
- (NSUInteger) tencentWebViewSupportedInterfaceOrientationsWithWebkit;
- (BOOL) tencentWebViewShouldAutorotateWithWebkit;
@end

View File

@ -0,0 +1,452 @@
///
/// \file TencentOAuthObject.h
/// 对开放接口的调用提供参数字典封装的辅助类
///
/// Created by Tencent on 12-12-28.
/// Copyright (c) 2012年 Tencent. All rights reserved.
///
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "sdkdef.h"
#pragma mark -
#pragma mark TCAddTopicDic
/**
* \brief 发表说说的参数字典定义
*
* 可以直接填写相应参数后将对象当作参数传入API中
*/
@interface TCAddTopicDic : TCAPIRequest
/**
* 返回一个对象用来进行API参数的填充
* \note 不用释放,返回的对象是自动释放的
*/
+ (TCAddTopicDic *) dictionary;
/**
* 发布心情时引用的信息的类型。
* \note 1表示图片 2表示网页 3表示视频
*/
@property (nonatomic, retain) TCOptionalStr paramRichtype;
/**
* 发布心情时引用的信息的值。有richtype时必须有richval
*
* \note
* -# 当richtype为图片即richtype为1应用场景为发布心情时引用某张图片\n
* richval需要传入该图片的相关参数。引用的图片来源分为两种一种为网站图片\n
* 一种为QQ空间相册中的某张图片。
* - 当引用的图片来自网站richval包含下列参数的值\n
* | 参数名称 | 是否必须 | 类型 | 描述 |
* | ------ | ------- | ------ | ----------------- |
* | url | 必须 | string | 网站图片的URL |
* | height | 必须 | string | 图片高度,单位: px |
* | width | 必须 | string | 图片宽度,单位: px |
* \n
* 输入时每个值中间用“&”分隔,如下所示:\n
* “url=http://qq.com/logo.png&width=25&height=21”
*
* - 当引用的图片来自QQ空间相册richval包含下列参数的值。\n
* 这些值都需要通过调用相册OpenAPI来获得。参数意义如下\n
* | 参数名称 | 是否必须 | 类型 | 描述 |
* | --------- | ------ | ------ | ---------------------------------- |
* | albumid | 必须 | string | 图片所属空间相册的ID |
* | pictureid | 必须 | string | 图片ID |
* | sloc | 必须 | string | 小图ID |
* | pictype | | string | 图片类型JPG = 1GIF = 2PNG = 3 |
* | picheight | | string | 图片高度,单位: px |
* | picwidth | | string | 图片宽度,单位: px |
* 输入时每个值中间用逗号分隔,如下所示 \n
* “albumid,pictureid,sloc,pictype,picheight,picwidth”
* -# 当richtype为网页即richtype为2应用场景为针对某网页发表评论\n
* richval需要传入该网页的URL发表为feeds时后台会自动将该URL转换为短URL。
* -# 当richtype为视频即richtype为3应用场景为针对某视频发表评论\n
* richval需要传入该视频的URL发表为feeds时后台会对该URL进行解析\n
* 在feeds上显示播放器视频源及缩略图。
*/
@property (nonatomic, retain) TCOptionalStr paramRichval;
/**
* 发布的心情的内容。
*/
@property (nonatomic, retain) TCRequiredStr paramCon;
/**
* 地址文。例如广东省深圳市南山区高新科技园腾讯大厦。lbs_nmlbs_xlbs_y通常一起使用来明确标识一个地址。
*/
@property (nonatomic, retain) TCOptionalStr paramLbs_nm;
/**
* 经度。-180.0到+180.0+表示东经。lbs_nmlbs_xlbs_y通常一起使用来明确标识一个地址。
*/
@property (nonatomic, retain) TCOptionalStr paramLbs_x;
/**
* 纬度。-90.0到+90.0+表示北纬。lbs_nmlbs_xlbs_y通常一起使用来明确标识一个地址。
*/
@property (nonatomic, retain) TCOptionalStr paramLbs_y;
/**
* 第三方应用的平台类型。
* \note 1表示QQ空间 2表示腾讯朋友 3表示腾讯微博平台 4表示腾讯Q+平台。
*/
@property (nonatomic, retain) TCOptionalStr paramThirdSource;
@end
#pragma mark -
#pragma mark TCAddOneBlogDic
/**
* \brief 发表日志的参数字典定义
*
* 可以直接填写相应参数后将对象当作参数传入API中
*/
@interface TCAddOneBlogDic : TCAPIRequest
/**
* 返回一个对象用来进行API参数的填充
* \note 不用释放,返回的对象是自动释放的
*/
+ (TCAddOneBlogDic *) dictionary;
/**
* 日志标题纯文本最大长度128个字节utf-8编码
*/
@property (nonatomic, retain) TCRequiredStr paramTitle;
/**
* content 文章内容html数据最大长度100*1024个字节utf-8编码
*/
@property (nonatomic, retain) TCRequiredStr paramContent;
@end
#pragma mark -
#pragma mark TCAddAlbumDic
/**
* \brief 创建空间相册的参数字典定义
*
* 可以直接填写相应参数后将对象当作参数传入API中
*/
@interface TCAddAlbumDic : TCAPIRequest
/**
* 返回一个对象用来进行API参数的填充
*
* \note 不用释放,返回的对象是自动释放的
*/
+ (TCAddAlbumDic *) dictionary;
/**
* albumname 必须 string 相册名 不能超过30个字符。
*/
@property (nonatomic, retain) TCRequiredStr paramAlbumname;
/**
* albumdesc string 相册描述不能超过200个字符。
*/
@property (nonatomic, retain) TCOptionalStr paramAlbumdesc;
/**
* priv string 相册权限
*
* \note 其取值含义为: 1=公开3=只主人可见; 4=QQ好友可见 5=问答加密。\n
* 不传则相册默认为公开权限。\n
* 如果priv取值为5即相册是问答加密的则必须包含问题和答案两个参数\n
* - question: 问题不能超过30个字符。
* - answer: 答案不能超过30个字符。
*/
@property (nonatomic, retain) TCOptionalStr paramPriv;
/**
* question 问题不能超过30个字符。
* \note 如果priv取值为5必须包含这个参数
**/
@property (nonatomic, retain) TCOptionalStr paramQuestion;
/**
* answer 答案不能超过30个字符。
* \note 如果priv取值为5必须包含这个参数
**/
@property (nonatomic, retain) TCOptionalStr paramAnswer;
@end
#pragma mark -
#pragma mark TCUploadPicDic
/**
* \brief 上传一张照片到QQ空间相册的参数字典定义
*
* 可以直接填写相应参数后将对象当作参数传入API中
*/
@interface TCUploadPicDic : TCAPIRequest
/**
* 返回一个对象用来进行API参数的填充
* \note 不用释放,返回的对象是自动释放的
*/
+ (TCUploadPicDic *) dictionary;
/**
* photodesc string 照片描述注意照片描述不能超过200个字符。
*/
@property (nonatomic, retain) TCOptionalStr paramPhotodesc;
/**
* string 照片的命名,必须以.jpg, .gif, .png, .jpeg, .bmp此类后缀结尾。
*/
@property (nonatomic, retain) TCOptionalStr paramTitle;
/**
* string 相册id。可不填不填时则根据“mobile”标识选择默认上传的相册。
*/
@property (nonatomic, retain) TCOptionalStr paramAlbumid;
/**
* 标志位
*
* \note 0表示PC1表示手机。用于当不传相册id时即albumid为空时控制是否传到手机相册。\n
* -# 如果传1则当albumid为空时图片会上传到手机相册
* -# 如果不传或传0则当albumid为空时图片会上传到贴图相册
*/
@property (nonatomic, assign) TCOptionalStr paramMobile;
/**
* x string 照片拍摄时的地理位置的经度。请使用原始数据纯经纬度0-360
*/
@property (nonatomic, retain) TCOptionalStr paramX;
/**
* y string 照片拍摄时的地理位置的纬度。请使用原始数据纯经纬度0-360
*/
@property (nonatomic, retain) TCOptionalStr paramY;
/**
* picture 必须 string 上传照片的文件名以及图片的内容在发送请求时图片内容以二进制数据流的形式发送见下面的请求示例注意照片名称不能超过30个字符。
*/
@property (nonatomic, retain) TCRequiredImage paramPicture;
/**
* needfeed int 标识上传照片时是否要发feed
* \note0不发feed 1发feed。如果不填则默认为发feed。
*/
@property (nonatomic, assign)TCOptionalStr paramNeedfeed;
/**
* successnum int 批量上传照片时,已成功上传的张数,指明上传完成情况。
* \note 单张上传时可以不填不填则默认为0。
*/
@property (nonatomic, assign)TCOptionalStr paramSuccessnum;
/**
* picnum int 批量上传照片的总张数如果不填则默认为1。
* \note
* - 如果picnum=1为单张上传发送单张上传feed
* - 如果picnum>1为批量上传发送批量上传feed。
* 批量上传方式picnum为一次上传照片的张数successnum初始值为0每调用一次照片上传接口后递增其值。
* 信息中心中的feed表现形式批量上传时最新的7张在feed中展示。其中最新上传的一张图片展示为大图剩下的
* 六张按从新到旧的顺序展示为小图其他图片不在feed中展示。
*/
@property (nonatomic, assign)TCOptionalStr paramPicnum;
@end
#pragma mark -
#pragma mark TCAddShareDic
/**
* \brief 同步分享到QQ空间,腾讯微博的参数字典定义
*
* 可以直接填写相应参数后将对象当作参数传入API中
*/
@interface TCAddShareDic : TCAPIRequest
/**
* 返回一个对象用来进行API参数的填充
*
* \note 不用释放,返回的对象是自动释放的
*/
+ (TCAddShareDic *) dictionary;
/**
* title 必须 string feeds的标题 最长36个中文字超出部分会被截断。
*/
@property (nonatomic, retain) TCRequiredStr paramTitle;
/**
* url 必须 string 分享所在网页资源的链接点击后跳转至第三方网页对应上文接口说明中2的超链接。请以http://开头。
*/
@property (nonatomic, retain) TCRequiredStr paramUrl;
/**
* comment string 用户评论内容,也叫发表分享时的分享理由 禁止使用系统生产的语句进行代替。
* 最长40个中文字超出部分会被截断。
*/
@property (nonatomic, retain) TCOptionalStr paramComment;
/**
* summary string 所分享的网页资源的摘要内容,或者是网页的概要描述 最长80个中文字超出部分会被截断。
*/
@property (nonatomic, retain) TCOptionalStr paramSummary;
/**
* images string 所分享的网页资源的代表性图片链接"请以http://开头长度限制255字符。多张图片以竖线|分隔目前只有第一张图片有效图片规格100*100为佳。
*/
@property (nonatomic, retain) TCOptionalStr paramImages;
/**
* type string 分享内容的类型。
*
* \note 4表示网页5表示视频type=5时必须传入playurl
*/
@property (nonatomic, retain) TCOptionalStr paramType;
/**
* playurl string 长度限制为256字节。仅在type=5的时候有效表示视频的swf播放地址。
*/
@property (nonatomic, retain) TCOptionalStr paramPlayurl;
/**
* site 必须 string 分享的来源网站名称,请填写网站申请接入时注册的网站名称
*/
@property (nonatomic, retain) TCRequiredStr paramSite;
/**
* fromurl 必须 string 分享的来源网站对应的网站地址url 请以http://开头。
*/
@property (nonatomic, retain) TCRequiredStr paramFromurl;
/**
* nswb string 值为1时表示分享不默认同步到微博其他值或者不传此参数表示默认同步到微博。
*/
@property (nonatomic, retain) TCOptionalStr paramNswb;
@end
#pragma mark -
#pragma mark TCCheckPageFansDic
/**
* \brief 验证是否认证空间粉丝tttyttyyyu的参数字典定义
*
* 可以直接填写相应参数后将对象当作参数传入API中
*/
@interface TCCheckPageFansDic : TCAPIRequest
/**
* 返回一个对象用来进行API参数的填充
*
* \note 不用释放,返回的对象是自动释放的
*/
+ (TCCheckPageFansDic *) dictionary;
/**
* 表示认证空间的QQ号码
*/
@property (nonatomic, retain) TCRequiredStr paramPage_id;
@end
#pragma mark -
#pragma mark TCSetUserHeadpic
/**
* \brief 设置用户头像
*
* 可以直接填写相应参数后将对象当作参数传入API中
*/
@interface TCSetUserHeadpic : TCAPIRequest
/**
* 返回一个对象用来进行API参数的填充
* \note 不用释放,返回的对象是自动释放的
*/
+ (TCSetUserHeadpic *) dictionary;
/**
* 设置用户头像的图片
*/
@property (nonatomic, retain) TCRequiredImage paramImage;
/**
* 图片的文件名
*/
@property (nonatomic, retain) TCOptionalStr paramFileName;
@end
#pragma mark -
#pragma mark TCListPhotoDic
/**
* \brief 获取用户QQ空间相册中的照片列表
*
* 可以直接填写相应参数后将对象当作参数传入API中
*/
@interface TCListPhotoDic : TCAPIRequest
/**
* 返回一个对象用来进行API参数的填充
*
* \note 不用释放,返回的对象是自动释放的
*/
+ (TCListPhotoDic *) dictionary;
/**
* 表示要获取的照片列表所在的相册ID
*/
@property (nonatomic, retain) TCRequiredStr paramAlbumid;
@end
#pragma mark -
#pragma mark TCSendStoryDic
/**
* \brief QQ空间定向分享的参数字典定义
*
* 该分享支持@到指定好友最多支持10个好友。
* 其中第三方应用可预传最多5个指定好友的openid其余好友由用户自行选择。
* 该分享形式仅提供跳QZone分享和本地Html5分享两种形式。
* sendStroy不支持userData参数
*/
@interface TCSendStoryDic : TCAPIRequest
/**
* 返回一个对象用来进行API参数的填充
*
* \note 不用释放,返回的对象是自动释放的
*/
+ (TCSendStoryDic *) dictionary;
/**
* 分享的标题
*/
@property (nonatomic, retain) TCRequiredStr paramTitle;
/**
* 故事摘要最多不超过50个汉字可以为空
*/
@property (nonatomic, retain) TCOptionalStr paramSummary;
/**
* 默认展示在输入框里的分享理由最多120个汉字可以为空
*/
@property (nonatomic, retain) TCOptionalStr paramDescription;
/**
* 图片url
*/
@property (nonatomic, retain) TCOptionalStr paramPics;
/**
* 如果不填,则默认为"进入应用"
*/
@property (nonatomic, retain) TCRequiredStr paramAct;
/**
* 点击分享的Url
*/
@property (nonatomic, retain) TCOptionalStr paramShareUrl;
@end

View File

@ -0,0 +1,414 @@
///
/// \file sdkdef.h
/// \brief SDK中相关常量定义
///
/// Created by Tencent on 12-12-25.
/// Copyright (c) 2012年 Tencent. All rights reserved.
///
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
/**
* \brief 设置sdk的log等级
*/
typedef enum {
TCOLogLevel_Disabled = -1, // 关闭所有log
TCOLogLevel_Error = 0,
TCOLogLevel_Warning,
TCOLogLevel_Info,
TCOLogLevel_Debug,
} TCOLogLevel;
/**
* \breif 授权/分享 方式
*/
typedef enum TencentAuthShareType {
AuthShareType_QQ,
AuthShareType_TIM,
}TencentAuthShareType;
/**
* \brief APIResponse.retCode可能的枚举常量
*/
typedef enum
{
URLREQUEST_SUCCEED = 0, /**< 网络请求成功发送至服务器,并且服务器返回数据格式正确
* \note 这里包括所请求业务操作失败的情况,例如没有授权等原因导致
*/
URLREQUEST_FAILED = 1, /**< 网络异常,或服务器返回的数据格式不正确导致无法解析 */
} REPONSE_RESULT;
/**
* \brief 增量授权失败原因
*
* \note 增量授权失败不影响原token的有效性原token已失效的情况除外
*/
typedef enum
{
kUpdateFailUnknown = 1, ///< 未知原因
kUpdateFailUserCancel, ///< 用户取消
kUpdateFailNetwork, ///< 网络问题
} UpdateFailType;
/**
* \brief 封装服务器返回的结果
*
* APIResponse用于封装所有请求的返回结果包括错误码、错误信息、原始返回数据以及返回数据的json格式字典
*/
@interface APIResponse : NSObject<NSCoding> {
int _detailRetCode;
int _retCode;
int _seq;
NSString *_errorMsg;
NSDictionary *_jsonResponse;
NSString *_message;
id _userData;
}
/**
* 新增的详细错误码\n
* detailRetCode主要用于区分不同的错误情况参见\ref OpenSDKError
*/
@property (nonatomic, assign) int detailRetCode;
/**
* 网络请求是否成功送达服务器,以及服务器返回的数据格式是否正确\n
* retCode具体取值可参考\ref REPONSE_RESULT
*/
@property (nonatomic, assign) int retCode;
/**
* 网络请求对应的递增序列号,方便内部管理
*/
@property (nonatomic, assign) int seq;
/**
* 错误提示语
*/
@property (nonatomic, retain) NSString *errorMsg;
/**
* 服务器返回数据的json格式字典\n
* 字典内具体参数的命名和含义请参考\ref api_spec
*/
@property (nonatomic, retain) NSDictionary *jsonResponse;
/**
* 服务器返回的原始数据字符串
*/
@property (nonatomic, retain) NSString *message;
/**
* 用户保留数据
*/
@property (nonatomic, retain) id userData;
@end
/**
* 用户自定义的保留字段
*/
FOUNDATION_EXTERN NSString * const PARAM_USER_DATA;
/**
* \name 应用邀请参数字段定义
*/
///@{
/** 应用邀请展示图片url的key */
FOUNDATION_EXTERN NSString * const PARAM_APP_ICON;
/** 应用邀请描述文本的key */
FOUNDATION_EXTERN NSString * const PARAM_APP_DESC;
/** 应用邀请好友列表的key */
FOUNDATION_EXTERN NSString * const PARAM_APP_INVITED_OPENIDS;
///@}
/**
* \name sendStory新分享参数字段定义
*/
///@{
/** 预填入接受人列表的key */
FOUNDATION_EXTERN NSString * const PARAM_SENDSTORY_RECEIVER;
/** 分享feeds标题的key */
FOUNDATION_EXTERN NSString * const PARAM_SENDSTORY_TITLE;
/** 分享feeds评论内容的key */
FOUNDATION_EXTERN NSString * const PARAM_SENDSTORY_COMMENT;
/** 分享feeds摘要的key */
FOUNDATION_EXTERN NSString * const PARAM_SENDSTORY_SUMMARY;
/** 分享feeds展示图片url的key */
FOUNDATION_EXTERN NSString * const PARAM_SENDSTORY_IMAGE;
/** 分享feeds跳转链接url的key */
FOUNDATION_EXTERN NSString * const PARAM_SENDSTORY_URL;
/** 分享feeds点击操作默认行为的key */
FOUNDATION_EXTERN NSString * const PARAM_SENDSTORY_ACT;
///@}
/**
* \name 设置头像参数字段定义
*/
///@{
/** 头像图片数据的key */
FOUNDATION_EXTERN NSString * const PARAM_SETUSERHEAD_PIC;
/** 头像图片文件名的key */
FOUNDATION_EXTERN NSString * const PARAM_SETUSERHEAD_FILENAME;
///@}
/**
* \name 服务器返回数据的参数字段定义
*/
///@{
/** 服务器返回码的key */
FOUNDATION_EXTERN NSString * const PARAM_RETCODE;
/** 服务器返回错误信息的key */
FOUNDATION_EXTERN NSString * const PARAM_MESSAGE;
/** 服务器返回额外数据的key */
FOUNDATION_EXTERN NSString * const PARAM_DATA;
///@}
/**
* \name 错误信息相关常量定义
*/
///@{
/** 详细错误信息字典中额外信息的key */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorKeyExtraInfo;
/** 详细错误信息字典中返回码的key */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorKeyRetCode;
/** 详细错误信息字典中错误语句的key */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorKeyMsg;
/** 不支持的接口 */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgUnsupportedAPI;
/** 操作成功 */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgSuccess;
/** 未知错误 */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgUnknown;
/** 用户取消 */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgUserCancel;
/** 请重新登录 */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgReLogin;
/** 应用没有操作权限 */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgOperationDeny;
/** 网络异常或没有网络 */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgNetwork;
/** URL格式或协议错误 */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgURL;
/** 解析数据出错 */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgDataParse;
/** 传入参数有误 */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgParam;
/** 连接超时 */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgTimeout;
/** 安全问题 */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgSecurity;
/** 文件读写错误 */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgIO;
/** 服务器端错误 */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgServer;
/** 页面错误 */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgWebPage;
/** 设置头像图片过大 */
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgUserHeadPicLarge;
///@}
/**
* \brief SDK新增详细错误常量
*/
typedef enum
{
kOpenSDKInvalid = -1, ///< 无效的错误码
kOpenSDKErrorUnsupportedAPI = -2, ///< 不支持的接口
/**
* \name CommonErrorCode
* 公共错误码
*/
///@{
kOpenSDKErrorSuccess = 0, ///< 成功
kOpenSDKErrorUnknown, ///< 未知错误
kOpenSDKErrorUserCancel, ///< 用户取消
kOpenSDKErrorReLogin, ///< token无效或用户未授权相应权限需要重新登录
kOpenSDKErrorOperationDeny, ///< 第三方应用没有该api操作的权限
///@}
/**
* \name NetworkRelatedErrorCode
* 网络相关错误码
*/
///@{
kOpenSDKErrorNetwork, ///< 网络错误,网络不通或连接不到服务器
kOpenSDKErrorURL, ///< URL格式或协议错误
kOpenSDKErrorDataParse, ///< 数据解析错误,服务器返回的数据解析出错
kOpenSDKErrorParam, ///< 传入参数错误
kOpenSDKErrorConnTimeout, ///< http连接超时
kOpenSDKErrorSecurity, ///< 安全问题
kOpenSDKErrorIO, ///< 下载和文件IO错误
kOpenSDKErrorServer, ///< 服务器端错误
///@}
/**
* \name WebViewRelatedError
* webview特有错误
*/
///@{
kOpenSDKErrorWebPage, ///< 页面错误
///@}
/**
* \name SetUserHeadRelatedErrorCode
* 设置头像自定义错误码段
*/
///@{
kOpenSDKErrorUserHeadPicLarge = 0x010000, ///< 图片过大 设置头像自定义错误码
///@}
} OpenSDKError;
/**
* \name SDK版本(v1.3)支持的授权列表常量
*/
///@{
/** 发表一条说说到QQ空间(<b>需要申请权限</b>) */
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_ADD_TOPIC;
/** 创建一个QQ空间相册(<b>需要申请权限</b>) */
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_ADD_ALBUM;
/** 上传一张照片到QQ空间相册(<b>需要申请权限</b>) */
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_UPLOAD_PIC;
/** 获取用户QQ空间相册列表(<b>需要申请权限</b>) */
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_LIST_ALBUM;
/** 验证是否认证空间粉丝 */
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_CHECK_PAGE_FANS;
/** 获取登录用户自己的详细信息 */
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_GET_INFO;
/** 获取其他用户的详细信息 */
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_GET_OTHER_INFO;
/** 获取会员用户基本信息 */
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_GET_VIP_INFO;
/** 获取会员用户详细信息 */
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_GET_VIP_RICH_INFO;
/** 获取用户信息 */
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_GET_USER_INFO;
/** 移动端获取用户信息 */
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_GET_SIMPLE_USER_INFO;
///@}
/**
* \name CGI接口相关参数类型定义
*/
/** 必填的字符串类型参数 */
typedef NSString *TCRequiredStr;
/** 必填的UIImage类型参数 */
typedef UIImage *TCRequiredImage;
/** 必填的整型参数 */
typedef NSInteger TCRequiredInt;
/** 必填的数字类型 */
typedef NSNumber *TCRequiredNumber;
/** 必填的NSData参数 */
typedef NSData *TCRequiredData;
/** 可选的字符串类型参数 */
typedef NSString *TCOptionalStr;
/** 可选的UIImage类型参数 */
typedef UIImage *TCOptionalImage;
/** 可选的整型参数 */
typedef NSInteger TCOptionalInt;
/** 可选的数字类型 */
typedef NSNumber *TCOptionalNumber;
/** 可选的不定类型参数 */
typedef id TCRequiredId;
///@}
/**
* \brief CGI请求的参数字典封装辅助基类
*
* 将相应属性的值以key-value的形式保存到参数字典中
*/
@interface TCAPIRequest : NSMutableDictionary
/** CGI请求的URL地址 */
@property (nonatomic, readonly) NSURL *apiURL;
/** CGI请求方式"GET""POST" */
@property (nonatomic, readonly) NSString *method;
/**
* API参数中的保留字段可以塞入任意字典支持的类型再调用完成后会带回给调用方
*/
@property (nonatomic, retain) TCRequiredId paramUserData;
/**
* APIResponse,API的返回结果
*/
@property (nonatomic, readonly) APIResponse *response;
/** 取消相应的CGI请求任务 */
- (void)cancel;
@end
@protocol TCAPIRequestDelegate <NSObject>
@optional
- (void)cgiRequest:(TCAPIRequest *)request didResponse:(APIResponse *)response;
@end

Binary file not shown.

24
package.json Normal file
View File

@ -0,0 +1,24 @@
{
"name": "react-native-qq",
"version": "2.0.5",
"description": "QQ Login&Share support in React Native.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/reactnativecn/react-native-qq.git"
},
"keywords": [
"react-native",
"ios",
"android"
],
"author": "tdzl2003",
"license": "ISC",
"bugs": {
"url": "https://github.com/reactnativecn/react-native-qq/issues"
},
"homepage": "https://github.com/reactnativecn/react-native-qq#readme"
}