"cordova-plugin-fingerprint-aio": {
"FACEID_USAGE_DESCRIPTION": " "
},
- "cordova-plugin-prevent-screenshot-coffice": {}
+ "cordova-plugin-prevent-screenshot-coffice": {},
+ "cordova-plugin-qqsdk": {
+ "QQ_APP_ID": "101885581"
+ }
},
"platforms": [
"android",
{
"xml": "<feature name=\"screenshotName\"><param name=\"android-package\" value=\"com.coffice.ScreenshotBlocker\" /><param name=\"onload\" value=\"true\" /></feature>",
"count": 1
+ },
+ {
+ "xml": "<feature name=\"QQSDK\"><param name=\"android-package\" value=\"me.vanpan.qqsdk.QQSDKPlugin\" /></feature>",
+ "count": 1
+ },
+ {
+ "xml": "<access origin=\"https://openmobile.qq.com/*\" />",
+ "count": 1
+ },
+ {
+ "xml": "<access origin=\"http://qzonestyle.gtimg.cn/*\" />",
+ "count": 1
+ },
+ {
+ "xml": "<access origin=\"http://pub.idqqimg.com/*\" />",
+ "count": 1
+ },
+ {
+ "xml": "<access origin=\"http://qzs.qq.com/*\" />",
+ "count": 1
+ },
+ {
+ "xml": "<access origin=\"http://m.qzone.com/*\" />",
+ "count": 1
+ },
+ {
+ "xml": "<access origin=\"http://*.ptlogin2.qq.com/*\" />",
+ "count": 1
+ },
+ {
+ "xml": "<access origin=\"http://*.qq.com/*\" />",
+ "count": 1
+ },
+ {
+ "xml": "<access origin=\"http://q2.qlogo.cn/*\" />",
+ "count": 1
+ },
+ {
+ "xml": "<preference name=\"QQ_APP_ID\" value=\"101885581\" />",
+ "count": 1
}
]
}
}
]
}
+ },
+ "app/src/main/AndroidManifest.xml": {
+ "parents": {
+ "/manifest": [
+ {
+ "xml": "<uses-permission android:name=\"android.permission.INTERNET\" />",
+ "count": 1
+ },
+ {
+ "xml": "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />",
+ "count": 1
+ },
+ {
+ "xml": "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />",
+ "count": 1
+ }
+ ],
+ "/manifest/application": [
+ {
+ "xml": "<activity android:launchMode=\"singleTask\" android:name=\"com.tencent.tauth.AuthActivity\" android:noHistory=\"true\"><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=\"tencent101885581\" /></intent-filter></activity>",
+ "count": 1
+ },
+ {
+ "xml": "<activity android:configChanges=\"orientation|keyboardHidden\" android:name=\"com.tencent.connect.common.AssistActivity\" android:screenOrientation=\"portrait\" android:theme=\"@android:style/Theme.Translucent.NoTitleBar\"></activity>",
+ "count": 1
+ }
+ ]
+ }
}
}
},
},
"cordova-plugin-prevent-screenshot-coffice": {
"PACKAGE_NAME": "com.dalipolice.app"
+ },
+ "cordova-plugin-qqsdk": {
+ "QQ_APP_ID": "101885581",
+ "PACKAGE_NAME": "com.dalipolice.app"
}
},
"dependent_plugins": {},
"clobbers": [
"window.plugins.preventscreenshot"
]
+ },
+ {
+ "id": "cordova-plugin-qqsdk.QQSDK",
+ "file": "plugins/cordova-plugin-qqsdk/www/qq.js",
+ "pluginId": "cordova-plugin-qqsdk",
+ "clobbers": [
+ "QQSDK"
+ ]
}
],
"plugin_metadata": {
"cordova-plugin-wkwebview-engine": "1.2.1",
"cordova-plugin-brightness": "0.1.5",
"cordova-plugin-fingerprint-aio": "3.0.1",
- "cordova-plugin-prevent-screenshot-coffice": "1.0.1"
+ "cordova-plugin-prevent-screenshot-coffice": "1.0.1",
+ "cordova-plugin-qqsdk": "0.9.7"
}
}
<meta-data android:name="JPUSH_CHANNEL" android:value="developer-default" />
<meta-data android:name="JPUSH_APPKEY" android:value="1fc62c8c6204ec4b0ae65ee2" />
<activity android:exported="true" android:name="de.niklasmerz.cordova.biometric.BiometricActivity" android:theme="@style/TransparentTheme" />
+ <activity android:launchMode="singleTask" android:name="com.tencent.tauth.AuthActivity" android:noHistory="true">
+ <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="tencent101885581" />
+ </intent-filter>
+ </activity>
+ <activity android:configChanges="orientation|keyboardHidden" android:name="com.tencent.connect.common.AssistActivity" android:screenOrientation="portrait" android:theme="@android:style/Theme.Translucent.NoTitleBar" />
</application>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" android:required="false" />
"clobbers": [
"window.plugins.preventscreenshot"
]
+ },
+ {
+ "id": "cordova-plugin-qqsdk.QQSDK",
+ "file": "plugins/cordova-plugin-qqsdk/www/qq.js",
+ "pluginId": "cordova-plugin-qqsdk",
+ "clobbers": [
+ "QQSDK"
+ ]
}
];
module.exports.metadata = {
"cordova-plugin-wkwebview-engine": "1.2.1",
"cordova-plugin-brightness": "0.1.5",
"cordova-plugin-fingerprint-aio": "3.0.1",
- "cordova-plugin-prevent-screenshot-coffice": "1.0.1"
+ "cordova-plugin-prevent-screenshot-coffice": "1.0.1",
+ "cordova-plugin-qqsdk": "0.9.7"
};
});
\ No newline at end of file
--- /dev/null
+package me.vanpan.qqsdk;
+
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Base64;
+import android.util.Log;
+import android.webkit.URLUtil;
+import com.tencent.connect.common.Constants;
+import com.tencent.connect.share.QQShare;
+import com.tencent.connect.share.QzonePublish;
+import com.tencent.connect.share.QzoneShare;
+import com.tencent.open.GameAppOperation;
+import com.tencent.tauth.IUiListener;
+import com.tencent.tauth.Tencent;
+import com.tencent.tauth.UiError;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import org.apache.cordova.CallbackContext;
+import org.apache.cordova.CordovaArgs;
+import org.apache.cordova.CordovaPlugin;
+import org.apache.cordova.PluginResult;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import static org.apache.cordova.CordovaActivity.TAG;
+
+/**
+ * Project: QQSDKPlugin
+ * Created by Van on 2016/12/16.
+ */
+
+class ShareScene {
+ public static final int QQ = 0;
+ public static final int QQZone = 1;
+ public static final int Favorite = 2;
+}
+
+public class QQSDKPlugin extends CordovaPlugin {
+ private static Tencent mTencent;
+ private CallbackContext currentCallbackContext;
+ private String APP_ID;
+ private static final String QQ_APP_ID = "qq_app_id";
+ private static final String QQ_CANCEL_BY_USER = "cancelled by user";
+ private static final String QQ_RESPONSE_ERROR = "QQ response is error";
+ private static final String QZONE_SHARE_CANCEL = "QZone share is cancelled";
+ private static final String QQFAVORITES_CANCEL = "QQ Favorites is cancelled";
+ private static final String QQ_Client_NOT_INSYALLED_ERROR = "QQ client is not installed";
+ private static final String QQ_PARAM_ERROR = "param incorrect";
+
+ @Override protected void pluginInitialize() {
+ super.pluginInitialize();
+ APP_ID = webView.getPreferences().getString(QQ_APP_ID, "");
+ mTencent = Tencent.createInstance(APP_ID, this.cordova.getActivity().getApplicationContext());
+ }
+
+ @Override
+ public boolean execute(String action, final CordovaArgs args, final CallbackContext callbackContext)
+ throws JSONException {
+ if (action.equalsIgnoreCase("checkClientInstalled")) {
+ return checkClientInstalled(callbackContext);
+ }
+ if (action.equals("ssoLogin")) {
+ return ssoLogin(callbackContext);
+ }
+ if (action.equals("logout")) {
+ return logout(callbackContext);
+ }
+ if (action.equals("shareText")) {
+ return shareText(args,callbackContext);
+ }
+ if (action.equals("shareImage")) {
+ return shareImage(args,callbackContext);
+ }
+ if (action.equals("shareNews")) {
+ return shareNews(args,callbackContext);
+ }
+ if (action.equals("shareAudio")) {
+ return shareAudio(args,callbackContext);
+ }
+ return super.execute(action, args, callbackContext);
+ }
+
+ /**
+ * 检查手机QQ客户端是否安装
+ */
+ private boolean checkClientInstalled(CallbackContext callbackContext) {
+ Boolean installed = mTencent.isSupportSSOLogin(QQSDKPlugin.this.cordova.getActivity());
+ if (installed) {
+ callbackContext.success();
+ } else {
+ callbackContext.error(QQ_Client_NOT_INSYALLED_ERROR);
+ }
+ return true;
+ }
+
+ /**
+ * QQ 单点登录
+ */
+ private boolean ssoLogin(CallbackContext callbackContext) {
+ currentCallbackContext = callbackContext;
+ Runnable runnable = new Runnable() {
+ @Override public void run() {
+ mTencent.login(QQSDKPlugin.this.cordova.getActivity(), "all", loginListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(runnable);
+ this.cordova.setActivityResultCallback(this);
+ return true;
+ }
+
+ /**
+ * QQ 登出
+ */
+ private boolean logout(CallbackContext callbackContext) {
+ mTencent.logout(this.cordova.getActivity());
+ callbackContext.success();
+ return true;
+ }
+
+ public boolean shareText(CordovaArgs args, CallbackContext callbackContext) {
+ final Bundle params = new Bundle();
+ currentCallbackContext = callbackContext;
+ final JSONObject data;
+ try {
+ data = args.getJSONObject(0);
+ String text = data.has("text")? data.getString("text"): "";
+ int shareScene = data.has("scene")? data.getInt("scene"): 0;
+ switch (shareScene) {
+ case ShareScene.QQ:
+ callbackContext.error("Android 不支持分享文字到 QQ");
+ break;
+ case ShareScene.Favorite:
+ params.putInt(GameAppOperation.QQFAV_DATALINE_REQTYPE,
+ GameAppOperation.QQFAV_DATALINE_TYPE_TEXT);
+ params.putString(GameAppOperation.QQFAV_DATALINE_TITLE, getAppName());
+ params.putString(GameAppOperation.QQFAV_DATALINE_DESCRIPTION, text);
+ params.putString(GameAppOperation.QQFAV_DATALINE_APPNAME, getAppName());
+ Runnable favoritesRunnable = new Runnable() {
+ @Override public void run() {
+ mTencent.addToQQFavorites(QQSDKPlugin.this.cordova.getActivity(), params,
+ addToQQFavoritesListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(favoritesRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ case ShareScene.QQZone:
+ params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE,
+ QzonePublish.PUBLISH_TO_QZONE_TYPE_PUBLISHMOOD);
+ params.putString(QzoneShare.SHARE_TO_QQ_TITLE, text);
+ Runnable zoneRunnable = new Runnable() {
+
+ @Override public void run() {
+ mTencent.publishToQzone(QQSDKPlugin.this.cordova.getActivity(), params,
+ qZoneShareListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(zoneRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ default:
+ break;
+ }
+ } catch (JSONException e) {
+ callbackContext.error(QQ_PARAM_ERROR);
+ return true;
+ }
+ return true;
+ }
+
+ public boolean shareImage(CordovaArgs args, CallbackContext callbackContext) {
+ currentCallbackContext = callbackContext;
+ final JSONObject data;
+ try {
+ data = args.getJSONObject(0);
+ String title = data.has("title")? data.getString("title"): "";
+ String description = data.has("description")? data.getString("description"): "";
+ String image = data.has("image")? data.getString("image"): "";
+ int shareScene = data.has("scene")? data.getInt("scene"): 0;
+ image = processImage(image);
+ final Bundle params = new Bundle();
+ switch (shareScene) {
+ case ShareScene.QQ:
+ params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_IMAGE);
+ params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, image);
+ params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
+ params.putString(QQShare.SHARE_TO_QQ_SUMMARY, description);
+ Runnable qqRunnable = new Runnable() {
+
+ @Override public void run() {
+ mTencent.shareToQQ(QQSDKPlugin.this.cordova.getActivity(), params, qqShareListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(qqRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ case ShareScene.Favorite:
+ ArrayList<String> imageUrls = new ArrayList<String>();
+ imageUrls.add(image);
+ params.putInt(GameAppOperation.QQFAV_DATALINE_REQTYPE,
+ GameAppOperation.QQFAV_DATALINE_TYPE_IMAGE_TEXT);
+ params.putString(GameAppOperation.QQFAV_DATALINE_TITLE, title);
+ params.putString(GameAppOperation.QQFAV_DATALINE_DESCRIPTION, description);
+ params.putString(GameAppOperation.QQFAV_DATALINE_IMAGEURL, image);
+ params.putString(GameAppOperation.QQFAV_DATALINE_APPNAME, getAppName());
+ params.putStringArrayList(GameAppOperation.QQFAV_DATALINE_FILEDATA, imageUrls);
+ Runnable favoritesRunnable = new Runnable() {
+ @Override public void run() {
+ mTencent.addToQQFavorites(QQSDKPlugin.this.cordova.getActivity(), params,
+ addToQQFavoritesListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(favoritesRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ case ShareScene.QQZone:
+ params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_IMAGE);
+ params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, image);
+ params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
+ params.putString(QQShare.SHARE_TO_QQ_SUMMARY, description);
+ params.putInt(QQShare.SHARE_TO_QQ_EXT_INT, QQShare.SHARE_TO_QQ_FLAG_QZONE_AUTO_OPEN);
+ Runnable zoneRunnable = new Runnable() {
+
+ @Override public void run() {
+ mTencent.shareToQQ(QQSDKPlugin.this.cordova.getActivity(), params, qqShareListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(zoneRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ default:
+ break;
+ }
+ } catch (JSONException e) {
+ callbackContext.error(QQ_PARAM_ERROR);
+ return true;
+ }
+ return true;
+ }
+
+ public boolean shareNews(CordovaArgs args, CallbackContext callbackContext) {
+ currentCallbackContext = callbackContext;
+ final JSONObject data;
+ try {
+ data = args.getJSONObject(0);
+ String title = data.has("title")? data.getString("title"): "";
+ String description = data.has("description")? data.getString("description"): "";
+ String image = data.has("image")? data.getString("image"): "";
+ String url = data.has("url")? data.getString("url"): "";
+ int shareScene = data.has("scene")? data.getInt("scene"): 0;
+ final Bundle params = new Bundle();
+ switch (shareScene) {
+ case ShareScene.QQ:
+ params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT);
+ if(URLUtil.isHttpUrl(image) || URLUtil.isHttpsUrl(image)) {
+ params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL,image);
+ } else {
+ params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL,processImage(image));
+ }
+ params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
+ params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, url);
+ params.putString(QQShare.SHARE_TO_QQ_SUMMARY, description);
+ Runnable qqRunnable = new Runnable() {
+
+ @Override public void run() {
+ mTencent.shareToQQ(QQSDKPlugin.this.cordova.getActivity(), params, qqShareListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(qqRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ case ShareScene.Favorite:
+ image = processImage(image);
+ params.putInt(GameAppOperation.QQFAV_DATALINE_REQTYPE,
+ GameAppOperation.QQFAV_DATALINE_TYPE_DEFAULT);
+ params.putString(GameAppOperation.QQFAV_DATALINE_TITLE, title);
+ params.putString(GameAppOperation.QQFAV_DATALINE_DESCRIPTION, description);
+ params.putString(GameAppOperation.QQFAV_DATALINE_IMAGEURL, image);
+ params.putString(GameAppOperation.QQFAV_DATALINE_URL, url);
+ params.putString(GameAppOperation.QQFAV_DATALINE_APPNAME, getAppName());
+ Runnable favoritesRunnable = new Runnable() {
+ @Override public void run() {
+ mTencent.addToQQFavorites(QQSDKPlugin.this.cordova.getActivity(), params,
+ addToQQFavoritesListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(favoritesRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ case ShareScene.QQZone:
+ image = processImage(image);
+ ArrayList<String> imageUrls = new ArrayList<String>();
+ imageUrls.add(image);
+ params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE,
+ QzoneShare.SHARE_TO_QZONE_TYPE_IMAGE_TEXT);
+ params.putString(QzoneShare.SHARE_TO_QQ_TITLE, title);
+ params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, description);
+ params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL, url);
+ params.putStringArrayList(QzoneShare.SHARE_TO_QQ_IMAGE_URL, imageUrls);
+ Runnable zoneRunnable = new Runnable() {
+
+ @Override public void run() {
+ mTencent.shareToQzone(QQSDKPlugin.this.cordova.getActivity(), params,
+ qZoneShareListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(zoneRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ default:
+ break;
+ }
+ } catch (JSONException e) {
+ callbackContext.error(QQ_PARAM_ERROR);
+ return true;
+ }
+ return true;
+ }
+
+ public boolean shareAudio(CordovaArgs args, CallbackContext callbackContext) {
+ currentCallbackContext = callbackContext;
+ final JSONObject data;
+ try {
+ data = args.getJSONObject(0);
+ String title = data.has("title")? data.getString("title"): "";
+ String description = data.has("description")? data.getString("description"): "";
+ String image = data.has("image")? data.getString("image"): "";
+ String url = data.has("url")? data.getString("url"): "";
+ String flashUrl = data.has("flashUrl")? data.getString("flashUrl"): "";
+ int shareScene = data.has("scene")? data.getInt("scene"): 0;
+ final Bundle params = new Bundle();
+ switch (shareScene) {
+ case ShareScene.QQ:
+ params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT);
+ if(URLUtil.isHttpUrl(image) || URLUtil.isHttpsUrl(image)) {
+ params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL,image);
+ } else {
+ params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL,processImage(image));
+ }
+ params.putString(QQShare.SHARE_TO_QQ_AUDIO_URL, flashUrl);
+ params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
+ params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, url);
+ params.putString(QQShare.SHARE_TO_QQ_SUMMARY, description);
+ Runnable qqRunnable = new Runnable() {
+
+ @Override public void run() {
+ mTencent.shareToQQ(QQSDKPlugin.this.cordova.getActivity(), params, qqShareListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(qqRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ case ShareScene.Favorite:
+ image = processImage(image);
+ params.putInt(GameAppOperation.QQFAV_DATALINE_REQTYPE,
+ GameAppOperation.QQFAV_DATALINE_TYPE_DEFAULT);
+ params.putString(GameAppOperation.QQFAV_DATALINE_TITLE, title);
+ params.putString(GameAppOperation.QQFAV_DATALINE_DESCRIPTION, description);
+ params.putString(GameAppOperation.QQFAV_DATALINE_IMAGEURL, image);
+ params.putString(GameAppOperation.QQFAV_DATALINE_URL, url);
+ params.putString(GameAppOperation.QQFAV_DATALINE_APPNAME, getAppName());
+ params.putString(GameAppOperation.QQFAV_DATALINE_AUDIOURL, flashUrl);
+ Runnable favoritesRunnable = new Runnable() {
+ @Override public void run() {
+ mTencent.addToQQFavorites(QQSDKPlugin.this.cordova.getActivity(), params,
+ addToQQFavoritesListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(favoritesRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ case ShareScene.QQZone:
+ image = processImage(image);
+ ArrayList<String> imageUrls = new ArrayList<String>();
+ imageUrls.add(image);
+ params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE,
+ QzoneShare.SHARE_TO_QZONE_TYPE_IMAGE_TEXT);
+ params.putString(QzoneShare.SHARE_TO_QQ_TITLE, title);
+ params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, description);
+ params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL, url);
+ params.putString(QzoneShare.SHARE_TO_QQ_AUDIO_URL, flashUrl);
+ params.putStringArrayList(QzoneShare.SHARE_TO_QQ_IMAGE_URL, imageUrls);
+ Runnable zoneRunnable = new Runnable() {
+
+ @Override public void run() {
+ mTencent.shareToQzone(QQSDKPlugin.this.cordova.getActivity(), params,
+ qZoneShareListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(zoneRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ default:
+ break;
+ }
+ } catch (JSONException e) {
+ callbackContext.error(QQ_PARAM_ERROR);
+ return true;
+ }
+ return true;
+ }
+
+ /**
+ * 保存token 和 openid
+ */
+ public static void initOpenidAndToken(JSONObject jsonObject) {
+ try {
+ String token = jsonObject.getString(Constants.PARAM_ACCESS_TOKEN);
+ String expires = jsonObject.getString(Constants.PARAM_EXPIRES_IN);
+ String openId = jsonObject.getString(Constants.PARAM_OPEN_ID);
+ if (!TextUtils.isEmpty(token) && !TextUtils.isEmpty(expires) && !TextUtils.isEmpty(openId)) {
+ mTencent.setAccessToken(token, expires);
+ mTencent.setOpenId(openId);
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ /**
+ * 获取应用的名称
+ */
+ private String getAppName() {
+ PackageManager packageManager = this.cordova.getActivity().getPackageManager();
+ ApplicationInfo applicationInfo = null;
+ try {
+ applicationInfo =
+ packageManager.getApplicationInfo(this.cordova.getActivity().getPackageName(), 0);
+ } catch (final PackageManager.NameNotFoundException e) {
+ }
+ final String AppName =
+ (String) ((applicationInfo != null) ? packageManager.getApplicationLabel(applicationInfo)
+ : "AppName");
+ return AppName;
+ }
+
+ /**
+ * 处理图片
+ * @param image
+ * @return
+ */
+ private String processImage(String image) {
+ if(URLUtil.isHttpUrl(image) || URLUtil.isHttpsUrl(image)) {
+ return saveBitmapToFile(getBitmapFromURL(image));
+ } else if (isBase64(image)) {
+ return saveBitmapToFile(decodeBase64ToBitmap(image));
+ } else if (image.startsWith("/") ){
+ File file = new File(image);
+ return file.getAbsolutePath();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * 检查图片字符串是不是Base64
+ * @param image
+ * @return
+ */
+ private boolean isBase64(String image) {
+ try {
+ byte[] decodedString = Base64.decode(image, Base64.DEFAULT);
+ Bitmap bitmap = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
+ if (bitmap == null) {
+ return false;
+ }
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+
+ public static Bitmap getBitmapFromURL(String src) {
+ try {
+ URL url = new URL(src);
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setDoInput(true);
+ connection.connect();
+ InputStream input = connection.getInputStream();
+ Bitmap bitmap = BitmapFactory.decodeStream(input);
+ return bitmap;
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ /**
+ * 将Base64解码成Bitmap
+ */
+
+ private Bitmap decodeBase64ToBitmap(String Base64String) {
+ byte[] decode = Base64.decode(Base64String, Base64.DEFAULT);
+ Bitmap bitmap = BitmapFactory.decodeByteArray(decode, 0, decode.length);
+ return bitmap;
+ }
+
+ /**
+ * 将bitmap 保存成文件
+ */
+ private String saveBitmapToFile(Bitmap bitmap) {
+ File pictureFile = getOutputMediaFile();
+ if (pictureFile == null) {
+ return null;
+ }
+ try {
+ FileOutputStream fos = new FileOutputStream(pictureFile);
+ bitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
+ fos.close();
+ } catch (FileNotFoundException e) {
+ Log.d(TAG, "File not found: " + e.getMessage());
+ } catch (IOException e) {
+ Log.d(TAG, "Error accessing file: " + e.getMessage());
+ }
+ return pictureFile.getAbsolutePath();
+ }
+
+ /**
+ * 生成文件用来存储图片
+ */
+ private File getOutputMediaFile() {
+ File mediaStorageDir = this.cordova.getActivity().getExternalCacheDir();
+ if (!mediaStorageDir.exists()) {
+ if (!mediaStorageDir.mkdirs()) {
+ return null;
+ }
+ }
+ String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date());
+ File mediaFile;
+ String mImageName = "Cordova_" + timeStamp + ".jpg";
+ mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
+ return mediaFile;
+ }
+
+ /**
+ * 登录监听
+ */
+ IUiListener loginListener = new IUiListener() {
+ @Override public void onComplete(Object response) {
+ if (null == response) {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, QQ_RESPONSE_ERROR),
+ currentCallbackContext.getCallbackId());
+ return;
+ }
+ JSONObject jsonResponse = (JSONObject) response;
+ if (null != jsonResponse && jsonResponse.length() == 0) {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, QQ_RESPONSE_ERROR),
+ currentCallbackContext.getCallbackId());
+ return;
+ }
+ initOpenidAndToken(jsonResponse);
+ JSONObject jo =
+ makeJson(mTencent.getAccessToken(), mTencent.getOpenId(), mTencent.getExpiresIn());
+ QQSDKPlugin.this.webView.sendPluginResult(new PluginResult(PluginResult.Status.OK, jo),
+ currentCallbackContext.getCallbackId());
+ }
+
+ @Override public void onError(UiError e) {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, e.errorMessage),
+ currentCallbackContext.getCallbackId());
+ }
+
+ @Override public void onCancel() {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, QQ_CANCEL_BY_USER),
+ currentCallbackContext.getCallbackId());
+ }
+ };
+ /**
+ * QQ分享监听
+ */
+ IUiListener qqShareListener = new IUiListener() {
+ @Override public void onCancel() {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, QQ_CANCEL_BY_USER),
+ currentCallbackContext.getCallbackId());
+ }
+
+ @Override public void onComplete(Object response) {
+ QQSDKPlugin.this.webView.sendPluginResult(new PluginResult(PluginResult.Status.OK),
+ currentCallbackContext.getCallbackId());
+ }
+
+ @Override public void onError(UiError e) {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, e.errorMessage),
+ currentCallbackContext.getCallbackId());
+ }
+ };
+ /**
+ * QQZONE 分享监听
+ */
+ IUiListener qZoneShareListener = new IUiListener() {
+
+ @Override public void onCancel() {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, QZONE_SHARE_CANCEL),
+ currentCallbackContext.getCallbackId());
+ }
+
+ @Override public void onError(UiError e) {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, e.errorMessage),
+ currentCallbackContext.getCallbackId());
+ }
+
+ @Override public void onComplete(Object response) {
+ QQSDKPlugin.this.webView.sendPluginResult(new PluginResult(PluginResult.Status.OK),
+ currentCallbackContext.getCallbackId());
+ }
+ };
+ /**
+ * 添加到QQ收藏监听
+ */
+ IUiListener addToQQFavoritesListener = new IUiListener() {
+ @Override public void onCancel() {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, QQFAVORITES_CANCEL),
+ currentCallbackContext.getCallbackId());
+ }
+
+ @Override public void onComplete(Object response) {
+ QQSDKPlugin.this.webView.sendPluginResult(new PluginResult(PluginResult.Status.OK),
+ currentCallbackContext.getCallbackId());
+ }
+
+ @Override public void onError(UiError e) {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, e.errorMessage),
+ currentCallbackContext.getCallbackId());
+ }
+ };
+
+ /**
+ * 组装JSON
+ */
+ private JSONObject makeJson(String access_token, String userid, long expires_time) {
+ String json = "{\"access_token\": \"" + access_token + "\", " +
+ " \"userid\": \"" + userid + "\", " +
+ " \"expires_time\": \"" + String.valueOf(expires_time) + "\"" +
+ "}";
+ JSONObject jo = null;
+ try {
+ jo = new JSONObject(json);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ return jo;
+ }
+
+ @Override public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+ if (resultCode == Constants.ACTIVITY_OK) {
+ if (requestCode == Constants.REQUEST_LOGIN) {
+ Tencent.onActivityResultData(requestCode, resultCode, intent, loginListener);
+ }
+ if (requestCode == Constants.REQUEST_QQ_SHARE) {
+ Tencent.onActivityResultData(requestCode, resultCode, intent, qqShareListener);
+ }
+ if (requestCode == Constants.REQUEST_QQ_FAVORITES) {
+ Tencent.onActivityResultData(requestCode, resultCode, intent, addToQQFavoritesListener);
+ }
+ }
+ super.onActivityResult(requestCode, resultCode, intent);
+ }
+
+ @Override public void onDestroy() {
+ super.onDestroy();
+ if (mTencent != null) {
+ mTencent.releaseResource();
+ }
+ }
+}
<param name="android-package" value="com.coffice.ScreenshotBlocker" />
<param name="onload" value="true" />
</feature>
+ <feature name="QQSDK">
+ <param name="android-package" value="me.vanpan.qqsdk.QQSDKPlugin" />
+ </feature>
+ <access origin="https://openmobile.qq.com/*" />
+ <access origin="http://qzonestyle.gtimg.cn/*" />
+ <access origin="http://pub.idqqimg.com/*" />
+ <access origin="http://qzs.qq.com/*" />
+ <access origin="http://m.qzone.com/*" />
+ <access origin="http://*.ptlogin2.qq.com/*" />
+ <access origin="http://*.qq.com/*" />
+ <access origin="http://q2.qlogo.cn/*" />
<name short="大理智警">dlapp</name>
<description>
A sample Apache Cordova application that responds to the deviceready event.
</edit-config>
<allow-intent href="market:*" />
<preference name="loglevel" value="DEBUG" />
+ <preference name="QQ_APP_ID" value="101885581" />
<preference name="AutoHideSplashScreen" value="true" />
<preference name="SplashScreenDelay" value="0" />
<preference name="SplashShowOnlyFirstTime" value="true" />
"clobbers": [
"window.plugins.preventscreenshot"
]
+ },
+ {
+ "id": "cordova-plugin-qqsdk.QQSDK",
+ "file": "plugins/cordova-plugin-qqsdk/www/qq.js",
+ "pluginId": "cordova-plugin-qqsdk",
+ "clobbers": [
+ "QQSDK"
+ ]
}
];
module.exports.metadata = {
"cordova-plugin-wkwebview-engine": "1.2.1",
"cordova-plugin-brightness": "0.1.5",
"cordova-plugin-fingerprint-aio": "3.0.1",
- "cordova-plugin-prevent-screenshot-coffice": "1.0.1"
+ "cordova-plugin-prevent-screenshot-coffice": "1.0.1",
+ "cordova-plugin-qqsdk": "0.9.7"
};
});
\ No newline at end of file
--- /dev/null
+cordova.define("cordova-plugin-qqsdk.QQSDK", function(require, exports, module) {
+
+var cordova = require('cordova');
+module.exports = {
+ Scene: {
+ QQ: 0, // QQ 好友
+ QQZone: 1, // QQ 空间
+ Favorite: 2 // 收藏
+ },
+ ClientType: {
+ QQ: 0, // QQ 手机客户端
+ TIM: 1 // TIM 客户端
+ },
+ ssoLogin:function(successCallback, errorCallback, args){
+ if(args === undefined) {
+ args = {}
+ }
+ cordova.exec(successCallback, errorCallback, "QQSDK", "ssoLogin",[args]);
+ },
+ logout:function(successCallback, errorCallback){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "logout", []);
+ },
+ checkClientInstalled:function(successCallback, errorCallback, args){
+ if(args === undefined) {
+ args = {}
+ }
+ cordova.exec(successCallback, errorCallback, "QQSDK", "checkClientInstalled", [args]);
+ },
+ shareText:function(successCallback, errorCallback, args){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "shareText", [args]);
+ },
+ shareImage:function(successCallback, errorCallback, args){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "shareImage", [args]);
+ },
+ shareNews:function(successCallback, errorCallback, args){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "shareNews", [args]);
+ },
+ shareAudio:function(successCallback, errorCallback, args){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "shareAudio", [args]);
+ },
+};
+
+});
cordova.system.library.1=com.squareup.okhttp3:okhttp-urlconnection:3.10.0
cordova.gradle.include.1=cordova-plugin-qrscanner/dlapp-qrscanner.gradle
cordova.system.library.2=com.android.support:support-v4:24.1.1+
-cordova.gradle.include.2=cordova-plugin-fingerprint-aio/app-build.gradle
\ No newline at end of file
+cordova.gradle.include.2=cordova-plugin-fingerprint-aio/app-build.gradle
+cordova.system.library.3=com.android.support:support-v4:24.1.1+
\ No newline at end of file
},
"cordova-plugin-prevent-screenshot-coffice": {
"PACKAGE_NAME": "com.dalipolice.app"
+ },
+ "cordova-plugin-qqsdk": {
+ "QQ_APP_ID": "101885581",
+ "PACKAGE_NAME": "com.dalipolice.app"
}
},
"dependent_plugins": {},
"clobbers": [
"window.plugins.preventscreenshot"
]
+ },
+ {
+ "file": "plugins/cordova-plugin-qqsdk/www/qq.js",
+ "id": "cordova-plugin-qqsdk.QQSDK",
+ "pluginId": "cordova-plugin-qqsdk",
+ "clobbers": [
+ "QQSDK"
+ ]
}
],
"plugin_metadata": {
"cordova-plugin-wkwebview-engine": "1.2.1",
"cordova-plugin-brightness": "0.1.5",
"cordova-plugin-fingerprint-aio": "3.0.1",
- "cordova-plugin-prevent-screenshot-coffice": "1.0.1"
+ "cordova-plugin-prevent-screenshot-coffice": "1.0.1",
+ "cordova-plugin-qqsdk": "0.9.7"
}
}
"clobbers": [
"window.plugins.preventscreenshot"
]
+ },
+ {
+ "file": "plugins/cordova-plugin-qqsdk/www/qq.js",
+ "id": "cordova-plugin-qqsdk.QQSDK",
+ "pluginId": "cordova-plugin-qqsdk",
+ "clobbers": [
+ "QQSDK"
+ ]
}
];
module.exports.metadata =
"cordova-plugin-wkwebview-engine": "1.2.1",
"cordova-plugin-brightness": "0.1.5",
"cordova-plugin-fingerprint-aio": "3.0.1",
- "cordova-plugin-prevent-screenshot-coffice": "1.0.1"
+ "cordova-plugin-prevent-screenshot-coffice": "1.0.1",
+ "cordova-plugin-qqsdk": "0.9.7"
}
// BOTTOM OF METADATA
});
\ No newline at end of file
--- /dev/null
+cordova.define("cordova-plugin-qqsdk.QQSDK", function(require, exports, module) {
+var cordova = require('cordova');
+module.exports = {
+ Scene: {
+ QQ: 0, // QQ 好友
+ QQZone: 1, // QQ 空间
+ Favorite: 2 // 收藏
+ },
+ ClientType: {
+ QQ: 0, // QQ 手机客户端
+ TIM: 1 // TIM 客户端
+ },
+ ssoLogin:function(successCallback, errorCallback, args){
+ if(args === undefined) {
+ args = {}
+ }
+ cordova.exec(successCallback, errorCallback, "QQSDK", "ssoLogin",[args]);
+ },
+ logout:function(successCallback, errorCallback){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "logout", []);
+ },
+ checkClientInstalled:function(successCallback, errorCallback, args){
+ if(args === undefined) {
+ args = {}
+ }
+ cordova.exec(successCallback, errorCallback, "QQSDK", "checkClientInstalled", [args]);
+ },
+ shareText:function(successCallback, errorCallback, args){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "shareText", [args]);
+ },
+ shareImage:function(successCallback, errorCallback, args){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "shareImage", [args]);
+ },
+ shareNews:function(successCallback, errorCallback, args){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "shareNews", [args]);
+ },
+ shareAudio:function(successCallback, errorCallback, args){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "shareAudio", [args]);
+ },
+};
+
+});
81B8C05354704A02AE1560A0 /* Fingerprint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39BDB5993A0D495C9E97E995 /* Fingerprint.swift */; };
F70AC332CD71455D9E103429 /* ScreenshotBlocker.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BD5959A12D340C3AB8685C0 /* ScreenshotBlocker.m */; };
1ED02270B4D74F8BB970350D /* ScreenRecordingDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = E806644FDDDD4DB9B0A7D6E4 /* ScreenRecordingDetector.m */; };
+ EF44EC2E45A745DAA3A1FB50 /* CDVQQSDK.m in Sources */ = {isa = PBXBuildFile; fileRef = 29DE4F0A316B400B959056A3 /* CDVQQSDK.m */; };
+ ACA1B32B06DC41AF930E894E /* TencentOpenApi_IOS_Bundle.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 2EB7D53C82F7469F9B0712DC /* TencentOpenApi_IOS_Bundle.bundle */; };
+ F5F3E5C64CF0404D803BDCFB /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 5EF554FF7A544AD9932C524C /* libiconv.tbd */; };
+ EDCB3A04AD4D4B289E64F99E /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D29239646664D05B61A0517 /* libsqlite3.tbd */; };
+ 988F095294ED444C9ACB1281 /* libstdc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F5208F54124408BAA42D80E /* libstdc++.tbd */; };
+ 1CA6AE2CB7C4454E96B08442 /* TencentOpenAPI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B8DABF1D129444628738EB6A /* TencentOpenAPI.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
E806644FDDDD4DB9B0A7D6E4 /* ScreenRecordingDetector.m */ = {isa = PBXFileReference; name = "ScreenRecordingDetector.m"; path = "cordova-plugin-prevent-screenshot-coffice/ScreenRecordingDetector.m"; sourceTree = "<group>"; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; explicitFileType = undefined; includeInIndex = 0; };
5FA4467FDA284333A275FA08 /* ScreenshotBlocker.h */ = {isa = PBXFileReference; name = "ScreenshotBlocker.h"; path = "cordova-plugin-prevent-screenshot-coffice/ScreenshotBlocker.h"; sourceTree = "<group>"; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; explicitFileType = undefined; includeInIndex = 0; };
6C8C62629761432796084184 /* ScreenRecordingDetector.h */ = {isa = PBXFileReference; name = "ScreenRecordingDetector.h"; path = "cordova-plugin-prevent-screenshot-coffice/ScreenRecordingDetector.h"; sourceTree = "<group>"; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; explicitFileType = undefined; includeInIndex = 0; };
+ 29DE4F0A316B400B959056A3 /* CDVQQSDK.m */ = {isa = PBXFileReference; name = "CDVQQSDK.m"; path = "cordova-plugin-qqsdk/CDVQQSDK.m"; sourceTree = "<group>"; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; explicitFileType = undefined; includeInIndex = 0; };
+ E381D08A673C42D780B0EAA7 /* CDVQQSDK.h */ = {isa = PBXFileReference; name = "CDVQQSDK.h"; path = "cordova-plugin-qqsdk/CDVQQSDK.h"; sourceTree = "<group>"; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; explicitFileType = undefined; includeInIndex = 0; };
+ 2EB7D53C82F7469F9B0712DC /* TencentOpenApi_IOS_Bundle.bundle */ = {isa = PBXFileReference; name = "TencentOpenApi_IOS_Bundle.bundle"; path = "TencentOpenApi_IOS_Bundle.bundle"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.plug-in; explicitFileType = undefined; includeInIndex = 0; };
+ 5EF554FF7A544AD9932C524C /* libiconv.tbd */ = {isa = PBXFileReference; name = "libiconv.tbd"; path = "usr/lib/libiconv.tbd"; sourceTree = SDKROOT; fileEncoding = undefined; lastKnownFileType = sourcecode.text-based-dylib-definition; explicitFileType = undefined; includeInIndex = 0; };
+ 9D29239646664D05B61A0517 /* libsqlite3.tbd */ = {isa = PBXFileReference; name = "libsqlite3.tbd"; path = "usr/lib/libsqlite3.tbd"; sourceTree = SDKROOT; fileEncoding = undefined; lastKnownFileType = sourcecode.text-based-dylib-definition; explicitFileType = undefined; includeInIndex = 0; };
+ 1F5208F54124408BAA42D80E /* libstdc++.tbd */ = {isa = PBXFileReference; name = "libstdc++.tbd"; path = "usr/lib/libstdc++.tbd"; sourceTree = SDKROOT; fileEncoding = undefined; lastKnownFileType = sourcecode.text-based-dylib-definition; explicitFileType = undefined; includeInIndex = 0; };
+ B8DABF1D129444628738EB6A /* TencentOpenAPI.framework */ = {isa = PBXFileReference; name = "TencentOpenAPI.framework"; path = "dlapp/Plugins/cordova-plugin-qqsdk/TencentOpenAPI.framework"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.framework; explicitFileType = undefined; includeInIndex = 0; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
77CDF61132F44B81B0064744 /* UserNotifications.framework in Frameworks */,
3C00FC06B74E49CFBABD0CFF /* libresolv.tbd in Frameworks */,
8C09122A89C14C5FB0C28636 /* WebKit.framework in Frameworks */,
+ F5F3E5C64CF0404D803BDCFB /* libiconv.tbd in Frameworks */,
+ EDCB3A04AD4D4B289E64F99E /* libsqlite3.tbd in Frameworks */,
+ 988F095294ED444C9ACB1281 /* libstdc++.tbd in Frameworks */,
+ 1CA6AE2CB7C4454E96B08442 /* TencentOpenAPI.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
3047A50E1AB8057F00498E2A /* config */,
8D1107310486CEB800E47090 /* dlapp-Info.plist */,
E9D260B7FB6C49A3AE6CD0DB /* JPushConfig.plist */,
+ 2EB7D53C82F7469F9B0712DC /* TencentOpenApi_IOS_Bundle.bundle */,
);
name = Resources;
path = dlapp/Resources;
59D1F618C1ED464283B7B2E6 /* UserNotifications.framework */,
CBD6EA74C612474DA862E146 /* libresolv.tbd */,
FE0B455916A4481681D59FE0 /* WebKit.framework */,
+ 5EF554FF7A544AD9932C524C /* libiconv.tbd */,
+ 9D29239646664D05B61A0517 /* libsqlite3.tbd */,
+ 1F5208F54124408BAA42D80E /* libstdc++.tbd */,
+ B8DABF1D129444628738EB6A /* TencentOpenAPI.framework */,
);
name = Frameworks;
sourceTree = "<group>";
E806644FDDDD4DB9B0A7D6E4 /* ScreenRecordingDetector.m */,
5FA4467FDA284333A275FA08 /* ScreenshotBlocker.h */,
6C8C62629761432796084184 /* ScreenRecordingDetector.h */,
+ 29DE4F0A316B400B959056A3 /* CDVQQSDK.m */,
+ E381D08A673C42D780B0EAA7 /* CDVQQSDK.h */,
);
name = Plugins;
path = dlapp/Plugins;
302D95F214D2391D003F00A1 /* MainViewController.xib in Resources */,
0207DA581B56EA530066E2B4 /* Images.xcassets in Resources */,
3BE6767AAFDC4926A08E6690 /* JPushConfig.plist in Resources */,
+ ACA1B32B06DC41AF930E894E /* TencentOpenApi_IOS_Bundle.bundle in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
81B8C05354704A02AE1560A0 /* Fingerprint.swift in Sources */,
F70AC332CD71455D9E103429 /* ScreenshotBlocker.m in Sources */,
1ED02270B4D74F8BB970350D /* ScreenRecordingDetector.m in Sources */,
+ EF44EC2E45A745DAA3A1FB50 /* CDVQQSDK.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = 1;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"dlapp/Plugins/cordova-plugin-qqsdk\"",
+ );
};
name = Debug;
};
SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/$(PROJECT_NAME)/Bridging-Header.h";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = 1;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"dlapp/Plugins/cordova-plugin-qqsdk\"",
+ );
};
name = Release;
};
--- /dev/null
+//
+// CDVQQSDK.h
+// QQ
+//
+// Created by Van on 2016/12/16.
+//
+//
+#import <Cordova/CDVPlugin.h>
+#import <Cordova/CDVPluginResult.h>
+#import <TencentOpenAPI/TencentOAuth.h>
+#import <TencentOpenAPI/QQApiInterface.h>
+
+typedef NS_ENUM(NSInteger, QQShareScene) {
+ QQ,
+ QQZone,
+ Favorite,
+};
+
+typedef NS_ENUM(NSInteger, QQShareType) {
+ TextMessage,
+ ImageMesssage,
+ NewsMessageWithNetworkImage,
+ NewsMessageWithLocalImage,
+ AudioMessage,
+ VideoMessage,
+};
+
+@interface CDVQQSDK : CDVPlugin <TencentSessionDelegate, QQApiInterfaceDelegate>
+
+@property (nonatomic, copy) NSString *callback;
+
+- (void)checkClientInstalled:(CDVInvokedUrlCommand *)command;
+
+- (void)ssoLogin:(CDVInvokedUrlCommand *)command;
+
+- (void)logout:(CDVInvokedUrlCommand *)command;
+
+- (void)shareText:(CDVInvokedUrlCommand *)command;
+
+- (void)shareImage:(CDVInvokedUrlCommand *)command;
+
+- (void)shareNews:(CDVInvokedUrlCommand *)command;
+
+//- (void)shareAudio:(NSString *)previewUrl flashUrl:(NSString *)flashUrl
+// image:(NSString *)image
+// withTitle:(NSString *)title
+// description:(NSString *)description
+// shareScene:(QQShareScene)scene
+// command:(CDVInvokedUrlCommand
+// *)command;
+
+@end
--- /dev/null
+//
+// CDVQQSDK.m
+// QQ
+//
+// Created by Van on 2016/12/16.
+//
+//
+
+#import "CDVQQSDK.h"
+
+NSString *QQ_NOT_INSTALLED = @"QQ Client is not installed";
+NSString *QQ_PARAM_NOT_FOUND = @"param is not found";
+NSString *QQ_IMAGE_PARAM_INCORRECT = @"image param is incorrect";
+NSString *QQ_LOGIN_ERROR = @"QQ login error";
+NSString *QQ_LOGIN_CANCEL = @"QQ login cancelled";
+NSString *QQ_LOGIN_NETWORK_ERROR = @"QQ login network error";
+NSString *QQ_SHARE_CANCEL = @"QQ share cancelled by user";
+NSString *appId = @"";
+
+@implementation CDVQQSDK {
+ TencentOAuth *tencentOAuth;
+}
+/**
+ * 插件初始化,主要用户appkey注册
+ */
+- (void)pluginInitialize {
+ appId = [[self.commandDelegate settings] objectForKey:@"qq_app_id"];
+ if (nil == tencentOAuth) {
+ tencentOAuth = [[TencentOAuth alloc] initWithAppId:appId andDelegate:self];
+ }
+}
+/**
+ * 处理URL
+ *
+ * @param notification cordova 传递进来的消息
+ */
+- (void)handleOpenURL:(NSNotification *)notification {
+ NSURL *url = [notification object];
+ NSString *schemaPrefix = [@"tencent" stringByAppendingString:appId];
+ if ([url isKindOfClass:[NSURL class]] && [[url absoluteString] hasPrefix:[schemaPrefix stringByAppendingString:@"://response_from_qq"]]) {
+ [QQApiInterface handleOpenURL:url delegate:self];
+ } else {
+ [TencentOAuth HandleOpenURL:url];
+ }
+}
+
+/**
+ * 检查QQ官方客户端是否安装
+ *
+ * @param command CDVInvokedUrlCommand
+ */
+- (void)checkClientInstalled:(CDVInvokedUrlCommand *)command {
+ NSDictionary *args = [command.arguments objectAtIndex:0];
+ int type = [[args valueForKey:@"client"] intValue];
+ if(type == 0) {
+ [tencentOAuth setAuthShareType:AuthShareType_QQ];
+ [self checkQQInstalled:command];
+ } else if (type == 1) {
+ [self checkTIMInstalled:command];
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+/**
+ * 检查QQ官方客户端是否安装
+ *
+ * @param command CDVInvokedUrlCommand
+ */
+- (void)checkQQInstalled:(CDVInvokedUrlCommand *)command {
+ if ([TencentOAuth iphoneQQInstalled] && [TencentOAuth iphoneQQSupportSSOLogin]) {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+
+/**
+ * 检查TIM客户端是否安装
+ *
+ * @param command CDVInvokedUrlCommand
+ */
+- (void)checkTIMInstalled:(CDVInvokedUrlCommand *)command {
+ if ([TencentOAuth iphoneTIMInstalled] && [TencentOAuth iphoneTIMSupportSSOLogin]) {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+/**
+ * QQ 登出
+ *
+ * @param command CDVInvokedUrlCommand
+ */
+- (void)logout:(CDVInvokedUrlCommand *)command {
+ self.callback = command.callbackId;
+ [tencentOAuth logout:self];
+}
+
+/**
+ * QQ 登录
+ *
+ * @param command CDVInvokedUrlCommand
+ */
+- (void)ssoLogin:(CDVInvokedUrlCommand *)command {
+ if (nil == tencentOAuth) {
+ tencentOAuth = [[TencentOAuth alloc] initWithAppId:appId andDelegate:self];
+ }
+ NSDictionary *args = [command.arguments objectAtIndex:0];
+ self.callback = command.callbackId;
+ NSArray *permissions = [NSArray arrayWithObjects:
+ kOPEN_PERMISSION_GET_USER_INFO,
+ kOPEN_PERMISSION_GET_SIMPLE_USER_INFO,
+ kOPEN_PERMISSION_ADD_ALBUM,
+ kOPEN_PERMISSION_ADD_ONE_BLOG,
+ kOPEN_PERMISSION_ADD_SHARE,
+ kOPEN_PERMISSION_ADD_TOPIC,
+ kOPEN_PERMISSION_CHECK_PAGE_FANS,
+ kOPEN_PERMISSION_GET_INFO,
+ kOPEN_PERMISSION_GET_OTHER_INFO,
+ kOPEN_PERMISSION_LIST_ALBUM,
+ kOPEN_PERMISSION_UPLOAD_PIC,
+ kOPEN_PERMISSION_GET_VIP_INFO,
+ kOPEN_PERMISSION_GET_VIP_RICH_INFO,
+ nil];
+ int type = [[args valueForKey:@"client"] intValue];
+ if (type == 0) {
+ [tencentOAuth setAuthShareType:AuthShareType_QQ];
+ } else if (type == 1) {
+ [tencentOAuth setAuthShareType:AuthShareType_TIM];
+ }
+ [tencentOAuth authorize:permissions];
+
+}
+
+/**
+ 分享文本
+
+ @param command cordova参数
+ */
+- (void)shareText:(CDVInvokedUrlCommand *)command {
+ self.callback = command.callbackId;
+ NSDictionary *args = [command.arguments objectAtIndex:0];
+ if ([args objectForKey:@"text"]) {
+ NSString *text = [args objectForKey:@"text"];
+ int scene = [[args valueForKey:@"scene"] intValue];
+ int type = [[args valueForKey:@"client"] intValue];
+ [self shareObjectWithData:@{ @"text" : text } Type:TextMessage Scene:scene ClientType:type];
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_PARAM_NOT_FOUND];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+
+/**
+ 分享图片
+
+ @param command Cordova参数
+ */
+- (void)shareImage:(CDVInvokedUrlCommand *)command {
+ self.callback = command.callbackId;
+ NSDictionary *args = [command.arguments objectAtIndex:0];
+ if (args) {
+ NSString *title = [self check:@"title" in:args];
+ NSString *image = [self check:@"image" in:args];
+ NSString *description = [self check:@"description" in:args];
+ int scene = [[args valueForKey:@"scene"] intValue];
+ int type = [[args valueForKey:@"client"] intValue];
+ NSData *imageData = [self processImage:image];
+ if(!imageData) {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_IMAGE_PARAM_INCORRECT];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ } else {
+ [self shareObjectWithData:@{ @"image" : imageData,
+ @"title" : title,
+ @"description" : description }
+ Type:ImageMesssage
+ Scene:scene
+ ClientType:type];
+ }
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_PARAM_NOT_FOUND];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+
+/**
+ 分享新闻链接
+
+ @param command Cordova参数
+ */
+- (void)shareNews:(CDVInvokedUrlCommand *)command {
+ self.callback = command.callbackId;
+ NSDictionary *args = [command.arguments objectAtIndex:0];
+ if (args) {
+ NSString *title = [self check:@"title" in:args];
+ NSString *image = [self check:@"image" in:args];
+ NSString *description = [self check:@"description" in:args];
+ NSString *url = [self check:@"url" in:args];
+ int scene = [[args valueForKey:@"scene"] intValue];
+ int type = [[args valueForKey:@"client"] intValue];
+ NSData *imageData = [self processImage:image];
+ if(!imageData) {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_IMAGE_PARAM_INCORRECT];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ } else {
+ [self shareObjectWithData:@{ @"url" : url,
+ @"image" : imageData,
+ @"title" : title,
+ @"description" : description }
+ Type:NewsMessageWithLocalImage
+ Scene:scene
+ ClientType:type];
+
+ }
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_PARAM_NOT_FOUND];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+
+/**
+ 分享音乐链接
+
+ @param command Cordova参数
+ */
+- (void)shareAudio:(CDVInvokedUrlCommand *)command {
+ self.callback = command.callbackId;
+ NSDictionary *args = [command.arguments objectAtIndex:0];
+ if (args) {
+ NSString *title = [self check:@"title" in:args];
+ NSString *image = [self check:@"image" in:args];
+ NSString *description = [self check:@"description" in:args];
+ NSString *url = [self check:@"url" in:args];
+ NSString *flashUrl = [self check:@"flashUrl" in:args];
+ int scene = [[args valueForKey:@"scene"] intValue];
+ int type = [[args valueForKey:@"client"] intValue];
+ NSData *imageData = [self processImage:image];
+ if(!imageData) {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_IMAGE_PARAM_INCORRECT];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ } else {
+ [self shareObjectWithData:@{ @"url" : url,
+ @"image" : imageData,
+ @"flashUrl" : flashUrl,
+ @"title" : title,
+ @"description" : description }
+ Type:AudioMessage
+ Scene:scene
+ ClientType:type];
+ }
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_PARAM_NOT_FOUND];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+
+/**
+ 分享视频链接
+
+ @param command Cordova参数
+ */
+- (void)shareVideo:(CDVInvokedUrlCommand *)command {
+ self.callback = command.callbackId;
+ NSDictionary *args = [command.arguments objectAtIndex:0];
+ if (args) {
+ NSString *title = [self check:@"title" in:args];
+ NSString *image = [self check:@"image" in:args];
+ NSString *description = [self check:@"description" in:args];
+ NSString *url = [self check:@"url" in:args];
+ NSString *flashUrl = [self check:@"flashUrl" in:args];
+ int scene = [[args valueForKey:@"scene"] intValue];
+ int type = [[args valueForKey:@"client"] intValue];
+ NSData *imageData = [self processImage:image];
+ if(!imageData) {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_IMAGE_PARAM_INCORRECT];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ } else {
+ [self shareObjectWithData:@{ @"url" : url,
+ @"image" : imageData,
+ @"flashUrl" : flashUrl,
+ @"title" : title,
+ @"description" : description }
+ Type:VideoMessage
+ Scene:scene
+ ClientType:type];
+ }
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_PARAM_NOT_FOUND];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+
+/**
+ 分享文本到QQ空间
+
+ @param text 分享文本
+ */
+- (void)shareTextToQQZone:(NSString *)text Client:(int) client {
+ QQApiImageArrayForQZoneObject *txtObj = [QQApiImageArrayForQZoneObject objectWithimageDataArray:nil title:text extMap:nil]; if (client == 1) {
+ txtObj.shareDestType = AuthShareType_TIM;
+ } else {
+ txtObj.shareDestType = AuthShareType_QQ;
+ }
+ SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:txtObj];
+ QQApiSendResultCode sent = [QQApiInterface SendReqToQZone:req];
+ [self handleSendResult:sent];
+}
+
+/**
+ 分享方法
+
+ @param shareData 分享数据
+ @param type 分享的类型
+ @param scene 分享的场景
+ */
+- (void)shareObjectWithData:(NSDictionary *)shareData Type:(QQShareType)type Scene:(QQShareScene)scene ClientType:(int) client {
+ switch (type) {
+ case TextMessage: {
+ NSString *msg = [shareData objectForKey:@"text"];
+ QQApiTextObject *txtObj = [QQApiTextObject objectWithText:msg];
+ [txtObj setCflag:kQQAPICtrlFlagQZoneShareOnStart];
+ switch (scene) {
+ case QQZone:
+ [self shareTextToQQZone:msg Client:client];
+ return;
+ case Favorite:
+ [txtObj setCflag:kQQAPICtrlFlagQQShareFavorites];
+ break;
+ default:
+ [txtObj setCflag:kQQAPICtrlFlagQQShare];
+ break;
+ }
+ if (client == 1) {
+ txtObj.shareDestType = AuthShareType_TIM;
+ } else {
+ txtObj.shareDestType = AuthShareType_QQ;
+ }
+ SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:txtObj];
+ QQApiSendResultCode sent = [QQApiInterface sendReq:req];
+ [self handleSendResult:sent];
+ } break;
+ case ImageMesssage: {
+ NSData *data = [shareData objectForKey:@"image"];
+ NSString *title = [shareData objectForKey:@"title"];
+ NSString *description = [shareData objectForKey:@"description"];
+ QQApiImageObject *imgObj = [QQApiImageObject objectWithData:data
+ previewImageData:nil
+ title:title
+ description:description];
+ switch (scene) {
+ case QQZone:
+ [imgObj setCflag:kQQAPICtrlFlagQZoneShareOnStart];
+ break;
+ case Favorite:
+ [imgObj setCflag:kQQAPICtrlFlagQQShareFavorites];
+ break;
+ default:
+ [imgObj setCflag:kQQAPICtrlFlagQQShare];
+ break;
+ }
+ if (client == 1) {
+ imgObj.shareDestType = AuthShareType_TIM;
+ } else {
+ imgObj.shareDestType = AuthShareType_QQ;
+ }
+ SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:imgObj];
+ QQApiSendResultCode sent = [QQApiInterface sendReq:req];
+ [self handleSendResult:sent];
+ } break;
+ case NewsMessageWithLocalImage: {
+ NSData *data = [shareData objectForKey:@"image"];
+ NSURL *url = [NSURL URLWithString:[shareData objectForKey:@"url"]];
+ NSString *title = [shareData objectForKey:@"title"];
+ NSString *description = [shareData objectForKey:@"description"];
+ QQApiNewsObject *newsObj = [QQApiNewsObject objectWithURL:url
+ title:title
+ description:description
+ previewImageData:data];
+ switch (scene) {
+ case QQZone:
+ [newsObj setCflag:kQQAPICtrlFlagQZoneShareOnStart];
+ break;
+ case Favorite:
+ [newsObj setCflag:kQQAPICtrlFlagQQShareFavorites];
+ break;
+ default:
+ [newsObj setCflag:kQQAPICtrlFlagQQShare];
+ break;
+ }
+ if (client == 1) {
+ newsObj.shareDestType = AuthShareType_TIM;
+ } else {
+ newsObj.shareDestType = AuthShareType_QQ;
+ }
+ SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:newsObj];
+ QQApiSendResultCode sent = [QQApiInterface sendReq:req];
+ [self handleSendResult:sent];
+ } break;
+ case AudioMessage: {
+ NSData *data = [shareData objectForKey:@"image"];
+ NSURL *url = [NSURL URLWithString:[shareData objectForKey:@"url"]];
+ NSString *title = [shareData objectForKey:@"title"];
+ NSString *description = [shareData objectForKey:@"description"];
+ NSURL *flashUrl = [NSURL URLWithString:[shareData objectForKey:@"url"]];
+ QQApiAudioObject *audioObj = [QQApiAudioObject objectWithURL:url
+ title:title
+ description:description
+ previewImageData:data];
+ [audioObj setFlashURL:flashUrl];
+ switch (scene) {
+ case QQZone:
+ [audioObj setCflag:kQQAPICtrlFlagQZoneShareOnStart];
+ break;
+ case Favorite:
+ [audioObj setCflag:kQQAPICtrlFlagQQShareFavorites];
+ break;
+ default:
+ [audioObj setCflag:kQQAPICtrlFlagQQShare];
+ break;
+ }
+ if (client == 1) {
+ audioObj.shareDestType = AuthShareType_TIM;
+ } else {
+ audioObj.shareDestType = AuthShareType_QQ;
+ }
+ SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:audioObj];
+ QQApiSendResultCode sent = [QQApiInterface sendReq:req];
+ [self handleSendResult:sent];
+ } break;
+ case VideoMessage: {
+ NSData *data = [shareData objectForKey:@"image"];
+ NSURL *url = [NSURL URLWithString:[shareData objectForKey:@"url"]];
+ NSString *title = [shareData objectForKey:@"title"];
+ NSString *description = [shareData objectForKey:@"description"];
+ NSURL *flashUrl = [NSURL URLWithString:[shareData objectForKey:@"url"]];
+ QQApiVideoObject *videoObj = [QQApiVideoObject objectWithURL:url
+ title:title
+ description:description
+ previewImageData:data];
+ [videoObj setFlashURL:flashUrl];
+ switch (scene) {
+ case QQZone:
+ [videoObj setCflag:kQQAPICtrlFlagQZoneShareOnStart];
+ break;
+ case Favorite:
+ [videoObj setCflag:kQQAPICtrlFlagQQShareFavorites];
+ break;
+ default:
+ [videoObj setCflag:kQQAPICtrlFlagQQShare];
+ break;
+ }
+ if (client == 1) {
+ videoObj.shareDestType = AuthShareType_TIM;
+ } else {
+ videoObj.shareDestType = AuthShareType_QQ;
+ }
+ SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:videoObj];
+ QQApiSendResultCode sent = [QQApiInterface sendReq:req];
+ [self handleSendResult:sent];
+ }
+ default:
+ break;
+ }
+}
+
+/**
+ 分析那个结果处理
+
+ @param sendResult 分享结果
+ */
+- (void)handleSendResult:(QQApiSendResultCode)sendResult {
+ switch (sendResult) {
+ case EQQAPISENDSUCESS:
+ break;
+ case EQQAPIAPPSHAREASYNC:
+ break;
+ case EQQAPIAPPNOTREGISTED: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"App 未注册"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case EQQAPIMESSAGECONTENTINVALID:
+ case EQQAPIMESSAGECONTENTNULL:
+ case EQQAPIMESSAGETYPEINVALID: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"发送参数错误"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case EQQAPITIMNOTINSTALLED: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"没有安装 TIM"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case EQQAPIQQNOTINSTALLED: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"没有安装手机 QQ"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case EQQAPITIMNOTSUPPORTAPI:
+ case EQQAPIQQNOTSUPPORTAPI: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"API 接口不支持"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case EQQAPISENDFAILD: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"发送失败"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case EQQAPIVERSIONNEEDUPDATE: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"当前 QQ 版本太低"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case ETIMAPIVERSIONNEEDUPDATE: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"当前 TIM 版本太低"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case EQQAPIQZONENOTSUPPORTTEXT: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"QQZone 不支持 QQApiTextObject 分享"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case EQQAPIQZONENOTSUPPORTIMAGE: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"QQZone 不支持 QQApiImageObject 分享"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case EQQAPISHAREDESTUNKNOWN: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"未指定分享到 QQ 或 TIM"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ default: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"发生其他错误"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ }
+}
+
+#pragma mark - QQApiInterfaceDelegate
+- (void)onReq:(QQBaseReq *)req {
+}
+
+- (void)onResp:(QQBaseResp *)resp {
+ switch ([resp.result integerValue]) {
+ case 0: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case -4: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_SHARE_CANCEL];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ default: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ }
+}
+
+- (void)isOnlineResponse:(NSDictionary *)response {
+}
+
+#pragma mark - TencentSessionDelegate
+- (void)tencentDidLogin {
+ if (tencentOAuth.accessToken && 0 != [tencentOAuth.accessToken length]) {
+ NSMutableDictionary *Dic = [NSMutableDictionary dictionaryWithCapacity:2];
+ [Dic setObject:tencentOAuth.openId forKey:@"userid"];
+ [Dic setObject:tencentOAuth.accessToken forKey:@"access_token"];
+ [Dic setObject:[NSString stringWithFormat:@"%f", [tencentOAuth.expirationDate timeIntervalSince1970] * 1000] forKey:@"expires_time"];
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:Dic];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_LOGIN_ERROR];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ }
+}
+
+- (void)tencentDidLogout {
+ tencentOAuth = nil;
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+}
+
+- (void)tencentDidNotLogin:(BOOL)cancelled {
+ if (cancelled) {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_LOGIN_CANCEL];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_LOGIN_ERROR];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ }
+}
+
+- (void)tencentDidNotNetWork {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_LOGIN_NETWORK_ERROR];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+}
+
+/**
+ 图片处理
+
+ @param image 图片数据
+ @return 图片NSdata数据
+ */
+- (NSData *)processImage:(NSString *)image {
+ if ([self isBase64Data:image]) {
+ return [[NSData alloc] initWithBase64EncodedString:image options:0];
+ } else if ([image hasPrefix:@"http://"] || [image hasPrefix:@"https://"]) {
+ NSURL *url = [NSURL URLWithString:image];
+ return [NSData dataWithContentsOfURL:url];
+ } else {
+ return [NSData dataWithContentsOfFile:image];
+ }
+}
+
+/**
+ 检查图片是不是Base64
+
+ @param data 图片数据
+ @return 结果true or false
+ */
+- (BOOL)isBase64Data:(NSString *)data {
+ data = [[data componentsSeparatedByCharactersInSet:
+ [NSCharacterSet whitespaceAndNewlineCharacterSet]]
+ componentsJoinedByString:@""];
+ if ([data length] % 4 == 0) {
+ static NSCharacterSet *invertedBase64CharacterSet = nil;
+ if (invertedBase64CharacterSet == nil) {
+ invertedBase64CharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="] invertedSet];
+ }
+ return [data rangeOfCharacterFromSet:invertedBase64CharacterSet options:NSLiteralSearch].location == NSNotFound;
+ }
+ return NO;
+}
+
+/**
+ 检查参数是否存在
+
+ @param param 要检查的参数
+ @param args 参数字典
+ @return 参数
+ */
+- (NSString *)check:(NSString *)param in:(NSDictionary *)args {
+ NSString *data = [args objectForKey:param];
+ return data?data:@"";
+}
+
+@end
--- /dev/null
+///
+/// \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"
+
+/**
+ \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发起分享请求
+ \param req 分享内容的请求
+ \return 请求发送结果码
+ */
++ (QQApiSendResultCode)sendReq:(QQBaseReq *)req;
+
+/**
+ 向手Q QZone结合版发起分享请求
+ \note H5分享只支持单张网络图片的传递
+ \param req 分享内容的请求
+ \return 请求发送结果码
+ */
++ (QQApiSendResultCode)SendReqToQZone:(QQBaseReq *)req;
+
+/**
+ 向手Q 群部落发起分享请求
+ \note H5分享只支持单张网络图片的传递
+ \param req 分享内容的请求
+ \return 请求发送结果码
+ */
++ (QQApiSendResultCode)SendReqToQQGroupTribe:(QQBaseReq *)req;
+
+/**
+ 向手Q发送应答消息
+ \param resp 应答消息
+ \return 应答发送结果码
+ */
++ (QQApiSendResultCode)sendResp:(QQBaseResp *)resp;
+
+/**
+ 检测是否已安装QQ
+ \return 如果QQ已安装则返回YES,否则返回NO
+ */
++ (BOOL)isQQInstalled;
+
+/**
+ 检测是否已安装TIM
+ \return 如果TIM已安装则返回YES,否则返回NO
+ */
++ (BOOL)isTIMInstalled;
+
+/**
+ 批量检测QQ号码是否在线
+ */
++ (void)getQQUinOnlineStatues:(NSArray *)QQUins delegate:(id<QQApiInterfaceDelegate>)delegate;
+
+/**
+ 检测QQ是否支持API调用
+ \return 如果当前安装QQ版本支持API调用则返回YES,否则返回NO
+ */
++ (BOOL)isQQSupportApi;
+
+/**
+ 检测TIM是否支持API调用
+ \return 如果当前安装TIM版本支持API调用则返回YES,否则返回NO
+ */
++ (BOOL)isTIMSupportApi;
+
+/**
+ 启动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>和<code>QQApiInterface#isTIMSupportApi</code>检测发现TIM没安装或当前版本TIM不支持API调用,可引导用户通过打开此链接下载最新版TIM。
+ \return iPhoneTIM下载地址
+ */
++ (NSString *)getTIMInstallUrl;
+
+@end
--- /dev/null
+///
+/// \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 enum
+{
+ EQQAPISENDSUCESS = 0,
+ EQQAPIQQNOTINSTALLED = 1,
+ EQQAPIQQNOTSUPPORTAPI = 2,
+ EQQAPIMESSAGETYPEINVALID = 3,
+ EQQAPIMESSAGECONTENTNULL = 4,
+ EQQAPIMESSAGECONTENTINVALID = 5,
+ EQQAPIAPPNOTREGISTED = 6,
+ EQQAPIAPPSHAREASYNC = 7,
+ EQQAPIQQNOTSUPPORTAPI_WITH_ERRORSHOW = 8,
+ EQQAPISENDFAILD = -1,
+ EQQAPISHAREDESTUNKNOWN = -2, //未指定分享到QQ或TIM
+
+ EQQAPITIMNOTINSTALLED = 11, //TIM未安装
+ EQQAPITIMNOTSUPPORTAPI = 12, // TIM api不支持
+ //qzone分享不支持text类型分享
+ EQQAPIQZONENOTSUPPORTTEXT = 10000,
+ //qzone分享不支持image类型分享
+ EQQAPIQZONENOTSUPPORTIMAGE = 10001,
+ //当前QQ版本太低,需要更新至新版本才可以支持
+ EQQAPIVERSIONNEEDUPDATE = 10002,
+ ETIMAPIVERSIONNEEDUPDATE = 10004,
+} QQApiSendResultCode;
+
+#pragma mark - QQApiObject(分享对象类型)
+
+// QQApiObject control flags
+enum
+{
+ kQQAPICtrlFlagQZoneShareOnStart = 0x01,
+ kQQAPICtrlFlagQZoneShareForbid = 0x02,
+ kQQAPICtrlFlagQQShare = 0x04,
+ kQQAPICtrlFlagQQShareFavorites = 0x08, //收藏
+ kQQAPICtrlFlagQQShareDataline = 0x10, //数据线
+};
+
+// 分享到QQ或TIM
+typedef enum ShareDestType {
+ ShareDestTypeQQ,
+ ShareDestTypeTIM,
+}ShareDestType;
+
+// QQApiObject
+/** \brief 所有在QQ及插件间发送的数据对象的根类。
+ */
+__attribute__((visibility("default"))) @interface QQApiObject : NSObject
+@property(nonatomic,retain) NSString* title; ///< 标题,最长128个字符
+@property(nonatomic,retain) NSString* description; ///<简要描述,最长512个字符
+
+@property (nonatomic, assign) uint64_t cflag;
+@property (nonatomic, assign) ShareDestType shareDestType; //分享到QQ或TIM,必须指定
+@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 enum QQApiURLTargetType{
+ QQApiURLTargetTypeNotSpecified = 0x00,
+ QQApiURLTargetTypeAudio = 0x01,
+ QQApiURLTargetTypeVideo = 0x02,
+ QQApiURLTargetTypeNews = 0x03
+}QQApiURLTargetType;
+
+/** @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
+
+// 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可传ALAsset的ALAssetPropertyAssetURL,或者PHAsset的localIdentifier
+ @param extMap 扩展字段
+ */
+@interface QQApiVideoForQZoneObject : QQApiObject
+
+@property(nonatomic, retain) NSString *assetURL;
+@property(nonatomic,retain) NSDictionary* extMap; // 扩展字段
+
+- (id)initWithAssetURL:(NSString*)assetURL title:(NSString*)title extMap:(NSDictionary *)extMap;
+
++ (id)objectWithAssetURL:(NSString*)assetURL 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
+
+// QQApiGroupTribeImageObject
+/** @brief 群部落图片对象
+ 用于分享图片内容的对象,是一个指定为图片类型的 可以指定一些其他的附加数据<code>QQApiExtendObject</code>
+ */
+@interface QQApiGroupTribeImageObject : QQApiImageObject
+{
+ NSString *_bid;
+ NSString *_bname;
+}
+// 群部落id
+@property (nonatomic, retain)NSString* bid;
+
+// 群部落名称
+@property (nonatomic, retain)NSString* bname;
+
+@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
+
+// QQApiPayObject
+/** \brief 支付对象
+ */
+@interface QQApiPayObject : QQApiObject
+@property(nonatomic,retain)NSString* OrderNo; ///<支付订单号,必填
+@property(nonatomic,retain)NSString* AppInfo; ///<支付来源信息,必填
+
+-(id)initWithOrderNo:(NSString*)OrderNo AppInfo:(NSString*)AppInfo; ///<初始化方法
++(id)objectWithOrderNo:(NSString*)OrderNo AppInfo:(NSString*)AppInfo;///<工厂方法,获取一个QQApiPayObject对象.
+@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
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// 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
+
+// QQApiWPAObject
+/** \brief 发起WPA对象
+ */
+@interface QQApiWPAObject : QQApiObject
+@property(nonatomic,retain)NSString* uin; ///<想要对话的QQ号
+
+-(id)initWithUin:(NSString*)uin; ///<初始化方法
++(id)objectWithUin:(NSString*)uin;///<工厂方法,获取一个QQApiWPAObject对象.
+@end
+
+// QQApiAddFriendObject
+/** \brief 添加好友
+ */
+@interface QQApiAddFriendObject : QQApiObject
+@property (nonatomic,retain)NSString* openID;
+@property (nonatomic,retain)NSString* subID;
+@property (nonatomic,retain)NSString* remark;
+
+-(id)initWithOpenID:(NSString*)openID; ///<初始化方法
++(id)objecWithOpenID:(NSString*)openID; ///<工厂方法,获取一个QQApiAddFriendObject对象.
+
+@end
+
+// QQApiGameConsortiumBindingGroupObject
+/** \brief 游戏公会绑定群
+ */
+@interface QQApiGameConsortiumBindingGroupObject : QQApiObject
+@property (nonatomic,retain)NSString* signature;
+@property (nonatomic,retain)NSString* unionid;
+@property (nonatomic,retain)NSString* zoneID;
+@property (nonatomic,retain)NSString* appDisplayName;
+
+-(id)initWithGameConsortium:(NSString*)signature unionid:(NSString*)unionid zoneID:(NSString*)zoneID appDisplayName:(NSString*)appDisplayName; ///<初始化方法
++(id)objectWithGameConsortium:(NSString*)signature unionid:(NSString*)unionid zoneID:(NSString*)zoneID appDisplayName:(NSString*)appDisplayName; ///<工厂方法,获取一个QQApiAddFriendObject对象.
+
+@end
+
+// QQApiGameConsortiumBindingGroupObject
+/** \brief 加入群
+ */
+@interface QQApiJoinGroupObject : QQApiObject
+@property (nonatomic,retain)NSString* groupUin;
+@property (nonatomic,retain)NSString* groupKey;
+
+- (id)initWithGroupInfo:(NSString*)groupUin key:(NSString*)groupKey; ///<初始化方法
++ (id)objectWithGroupInfo:(NSString*)groupUin key:(NSString*)groupKey; ///<同时提供群号和群KEY 工厂方法,获取一个QQApiAddFriendObject对象.
++ (id)objectWithGroupKey:(NSString*)groupKey; ///<只需要群的KEY 工厂方法,获取一个QQApiAddFriendObject对象.
+
+@end
+
+// QQApiGroupChatObject
+/** \brief 发起群会话对象
+ */
+@interface QQApiGroupChatObject : QQApiObject
+@property(nonatomic,retain)NSString* groupID; ///<想要对话的群号
+
+-(id)initWithGroup:(NSString*)groupID; ///<初始化方法
++(id)objectWithGroup:(NSString*)groupID;///<工厂方法,获取一个QQApiGroupChatObject对象.
+@end
+
+#pragma mark - QQApi请求消息类型
+
+/**
+ QQApi请求消息类型
+ */
+enum QQApiInterfaceReqType
+{
+ EGETMESSAGEFROMQQREQTYPE = 0, ///< 手Q -> 第三方应用,请求第三方应用向手Q发送消息
+ ESENDMESSAGETOQQREQTYPE = 1, ///< 第三方应用 -> 手Q,第三方应用向手Q分享消息
+ ESHOWMESSAGEFROMQQREQTYPE = 2 ///< 手Q -> 第三方应用,请求第三方应用展现消息中的数据
+};
+
+/**
+ QQApi应答消息类型
+ */
+enum 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
+
+/**
+ GetMessageFromQQResp应答帮助类
+ */
+@interface GetMessageFromQQResp : QQBaseResp
+
+/**
+ 创建一个GetMessageFromQQResp应答实例
+ \param message 具体分享消息实例
+ \return 新创建的GetMessageFromQQResp应答实例
+ */
++ (GetMessageFromQQResp *)respWithContent:(QQApiObject *)message;
+
+/** 具体分享消息 */
+@property (nonatomic, retain) QQApiObject *message;
+
+@end
+
+/**
+ SendMessageToQQReq请求帮助类
+ */
+@interface SendMessageToQQReq : QQBaseReq
+
+/**
+ 创建一个SendMessageToQQReq请求实例
+ \param message 具体分享消息实例
+ \return 新创建的SendMessageToQQReq请求实例
+ */
++ (SendMessageToQQReq *)reqWithContent:(QQApiObject *)message;
+
+/** 具体分享消息 */
+@property (nonatomic, retain) QQApiObject *message;
+
+@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
+
+/**
+ ShowMessageFromQQResp应答帮助类
+ */
+@interface ShowMessageFromQQResp : QQBaseResp
+
+/**
+ 创建一个ShowMessageFromQQResp应答实例
+ \param result 展现消息结果
+ \param errDesp 具体错误描述信息
+ \return 新创建的ShowMessageFromQQResp应答实例
+ */
++ (ShowMessageFromQQResp *)respWithResult:(NSString *)result errorDescription:(NSString *)errDesp;
+
+@end
+
+#endif
--- /dev/null
+//
+// TencentMessage.h
+// TencentOpenApi_IOS
+//
+// Created by qqconnect on 13-5-29.
+// Copyright (c) 2013年 Tencent. All rights reserved.
+//
+
+#ifndef QQ_OPEN_SDK_LITE
+
+#import <Foundation/Foundation.h>
+#import "TencentMessageObject.h"
+
+typedef enum
+{
+ kIphoneQQ,
+ kIphoneQZONE,
+ kIphoneTIM,
+ kThirdApp,
+}
+TecnentPlatformType;
+
+typedef enum
+{
+ kTencentApiSuccess,
+ kTencentApiPlatformUninstall,
+ kTencentApiPlatformNotSupport,
+ kTencentApiParamsError,
+ kTencentApiFail,
+}
+TencentApiRetCode;
+
+@class TencentApiReq;
+@class TencentApiResp;
+
+/**
+ * \brief TencentApiInterface的回调
+ *
+ * TencentApiInterface的回调接口
+ * \note v1.0版本只支持腾讯业务拉起第三方请求内容
+ */
+@protocol TencentApiInterfaceDelegate <NSObject>
+
+@optional
+/**
+ * 请求获得内容 当前版本只支持第三方相应腾讯业务请求
+ */
+- (BOOL)onTencentReq:(TencentApiReq *)req;
+
+/**
+ * 响应请求答复 当前版本只支持腾讯业务相应第三方的请求答复
+ */
+- (BOOL)onTencentResp:(TencentApiResp *)resp;
+
+@end
+
+/**
+ * \brief TencentApiInterface的回调
+ *
+ * TencentApiInterface的调用接口
+ * \note v1.0版本只支持第三方答复内容
+ */
+@interface TencentApiInterface : NSObject
+
+/**
+ * 发送答复返回腾讯业务
+ * \param resp 答复内容
+ * \return 返回码
+ */
++ (TencentApiRetCode)sendRespMessageToTencentApp:(TencentApiResp *)resp;
+
+/**
+ * 是否可以处理拉起协议
+ * \param url
+ * \param delegate 指定的回调
+ * \return 是否是腾讯API认识的消息类型
+ */
++ (BOOL)canOpenURL:(NSURL *)url delegate:(id<TencentApiInterfaceDelegate>)delegate;
+
+/**
+ * 处理应用拉起协议
+ * \param url
+ * \param delegate 指定的回调
+ * \return 是否是腾讯API认识的消息类型
+ */
++ (BOOL)handleOpenURL:(NSURL *)url delegate:(id<TencentApiInterfaceDelegate>)delegate;
+
+/**
+ * 用户设备是否安装腾讯APP
+ * \param platform 指定的腾讯业务
+ * \return YES:安装 NO:未安装
+ */
++ (BOOL)isTencentAppInstall:(TecnentPlatformType)platform;
+
+/**
+ * 用户设备是否支持调用SDK
+ * \param platform 指定的腾讯业务
+ * \return YES:支持 NO:不支持
+ */
++ (BOOL)isTencentAppSupportTencentApi:(TecnentPlatformType)platform;
+
+@end
+
+#endif
--- /dev/null
+//
+// TencentMessageObject.h
+// TencentOpenApi_IOS
+//
+// Created by qqconnect on 13-5-27.
+// Copyright (c) 2013年 Tencent. All rights reserved.
+//
+
+#ifndef QQ_OPEN_SDK_LITE
+
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+#import "sdkdef.h"
+
+#define kTextLimit (1024 * 1024)
+#define kDataLimit (1024 * 1024 * 10)
+#define kPreviewDataLimit (1024 * 1024)
+
+@class TencentApiReq;
+@class TencentApiResp;
+
+/**
+ * 必填的NSArray型参数
+ */
+typedef NSArray *TCRequiredArray;
+
+/**
+ * 必填的NSDictionary型参数
+ */
+typedef NSDictionary *TCRequiredDictionary;
+
+/**
+ * 必填的TencentApiReq型参数
+ */
+typedef TencentApiReq *TCRequiredReq;
+
+/**
+ * 可选的UIImage类型参数
+ */
+typedef NSData *TCOptionalData;
+
+
+/**
+ * 可选的NSArray型参数
+ */
+typedef NSArray *TCOptionalArray;
+
+/**
+ * 可选的TencentApiReq型参数
+ */
+typedef TencentApiReq *TCOptionalReq;
+
+/**
+ * TencentReqMessageType 请求类型枚举参数
+ */
+typedef enum
+{
+ /** TX APP请求内容填充(需要第三方开发者填充完成内容后需要主动调用sendRespMessageToTencentApp)*/
+ ReqFromTencentAppQueryContent,
+ /** TX APP请求展现内容 (不用调用答复) */
+ ReqFromTencentAppShowContent,
+ /** 第三方 APP 请求内容 */
+ ReqFromThirdAppQueryContent,
+ /** 第三方 APP 请求展现内容(类似分享)*/
+ ReqFromThirdAppShowContent,
+}
+TencentReqMessageType;
+
+typedef enum
+{
+ RespFromTencentAppQueryContent,
+ RespFromTencentAppShowContent,
+ RespFromThirdAppQueryContent,
+ RespFromThirdAppShowContent,
+}
+TencentRespMessageType;
+
+/**
+ * TencentObjVersion 腾讯API消息类型枚举
+ */
+typedef enum
+{
+ /** 文本类型 */
+ TencentTextObj,
+ /** 图片类型 */
+ TencentImageObj,
+ /** 音频类型 */
+ TencentAudioObj,
+ /** 视频类型 */
+ TencentVideoObj,
+ /** 图片视频类 */
+ TencentImageAndVideoObj,
+}
+TencentObjVersion;
+
+/**
+ * \brief 请求包
+ *
+ * TencentApiReq用来向其他业务发送请求包
+ */
+@interface TencentApiReq : NSObject<NSCoding>
+
+/**
+ * 根据序列号生成一个请求包
+ * \param apiSeq 请求序列号
+ * \param type 请求类型
+ * \return tencentApiReq实例
+ */
++ (TencentApiReq *)reqFromSeq:(NSInteger)apiSeq type:(TencentReqMessageType)type;
+
+/** 请求类型 */
+@property (readonly, assign, nonatomic)TCRequiredInt nMessageType;
+
+/** 请求平台 */
+@property (readonly, assign, nonatomic)NSInteger nPlatform;
+
+/** 请求的SDK版本号 */
+@property (readonly, assign, nonatomic)NSInteger nSdkVersion;
+
+/** 请求序列号 */
+@property (readonly, assign, nonatomic)TCRequiredInt nSeq;
+
+/** 第三方的APPID */
+@property (nonatomic, retain)TCRequiredStr sAppID;
+
+/** 请求内容 TencentBaseMessageObj对象数组 */
+@property (nonatomic, retain)TCOptionalArray arrMessage;
+
+/** 请求的描述 可以用于告诉对方这个请求的特定场景 */
+@property (nonatomic, retain)TCOptionalStr sDescription;
+
+@end
+
+/**
+ * \brief 答复包
+ *
+ * TencentApiResp用来向其他业务发送答复包
+ */
+@interface TencentApiResp : NSObject<NSCoding>
+
+/**
+ * 根据序列号生成一个答复包
+ * \param req 答复对应的请求包(如果req不是TencentApiReq或者他的子类,会抛出异常)
+ * \return 答复包体
+ */
++ (TencentApiResp *)respFromReq:(TencentApiReq *)req;
+
+/** 返回码 */
+@property (nonatomic, assign)TCOptionalInt nRetCode;
+
+/** 返回消息 */
+@property (nonatomic, retain)TCOptionalStr sRetMsg;
+
+/** 答复对应的请求包 */
+@property (nonatomic, retain)TCOptionalReq objReq;
+
+@end
+
+/**
+ * \brief 消息体
+ *
+ * TencentBaseMessageObj 应用之间传递消息体
+ */
+@interface TencentBaseMessageObj : NSObject<NSCoding>
+
+/** 消息类型 */
+@property (nonatomic, assign)NSInteger nVersion;
+
+/** 消息描述 */
+@property (nonatomic, retain)NSString *sName;
+
+/** 消息的扩展信息 主要是可以用来进行一些请求消息体的描述 譬如图片要求的width height 文字的关键字什么的, 也可以不用填写*/
+@property (nonatomic, retain)NSDictionary *dictExpandInfo;
+
+/**
+ * 消息是否有效
+ */
+- (BOOL)isVaild;
+
+@end
+
+#pragma mark TencentTextMessage
+/**
+ * \brief 文本的消息体
+ *
+ * TencentTextMessageObjV1 应用之间传递的文本消息体
+ */
+@interface TencentTextMessageObjV1 : TencentBaseMessageObj
+
+/**
+ * 文本
+ * \note 文本长度不能超过4096个字
+ */
+@property (nonatomic, retain) NSString *sText;
+
+
+/**
+ * 初始化文本消息
+ * \param text 文本
+ * \return 初始化返回的文本消息
+ */
+- (id)initWithText:(NSString *)text;
+
+@end
+
+
+#pragma mark TecentImageMessage
+
+/**
+ * TencentApiImageSourceType 图片数据类型(请求方对数据类型可能会有限制)
+ */
+typedef enum
+{
+ /** 图片数据是url或二进制数据 */
+ AllImage,
+ /** 图片数据是url */
+ UrlImage,
+ /** 图片数据是二进制数据 */
+ DataImage,
+}TencentApiImageSourceType;
+
+/**
+ * \brief 图片的消息体
+ *
+ * TencentImageMessageObjV1 应用之间传递的图片消息体
+ */
+@interface TencentImageMessageObjV1 : TencentBaseMessageObj
+
+/**
+ * 图片数据
+ * \note 图片不能大于10M
+ */
+@property (nonatomic, retain) NSData *dataImage;
+
+/**
+ * 缩略图的数据
+ * \note 图片不能大于1M
+ */
+@property (nonatomic, retain) NSData *dataThumbImage;
+
+/** 图片URL */
+@property (nonatomic, retain) NSString *sUrl;
+
+/** 图片的描述 */
+@property (nonatomic, retain) NSString *sDescription;
+
+/** 图片的size */
+@property (nonatomic, assign) CGSize szImage;
+
+/**
+ * 图片来源
+ * \note TencentApiImageSourceType对应的类型
+ */
+@property (readonly, assign) NSInteger nType;
+
+/**
+ * 初始化图片消息
+ * \param dataImage 图片类型
+ * \return 初始化返回的图片消息
+ */
+- (id)initWithImageData:(NSData *)dataImage;
+
+/**
+ * 初始化图片消息
+ * \param url 图片url
+ * \return 初始化返回的图片消息
+ */
+- (id)initWithImageUrl:(NSString *)url;
+
+/**
+ * 初始化图片消息
+ * \param type 图片类型
+ * \return 初始化返回的图片消息
+ */
+- (id)initWithType:(TencentApiImageSourceType)type;
+@end
+
+
+#pragma mark TencentAudioMessage
+/**
+ * \brief 音频的消息体
+ *
+ * TencentAudioMessageObjV1 应用之间传递的音频消息体
+ */
+@interface TencentAudioMessageObjV1 : TencentBaseMessageObj
+
+/** 音频URL */
+@property (nonatomic, retain) NSString *sUrl;
+
+/**
+ * 音频的预览图
+ * \note图片不能大于1M
+ */
+@property (nonatomic, retain) NSData *dataImagePreview;
+
+/** 音频的预览图URL */
+@property (nonatomic, retain) NSString *sImagePreviewUrl;
+
+/** 音频的描述 */
+@property (nonatomic, retain) NSString *sDescription;
+
+/**
+ * 初始化图片消息
+ * \param url 音频URL
+ * \return 初始化返回的音频消息
+ */
+- (id)initWithAudioUrl:(NSString *)url;
+
+@end
+
+
+#pragma mark TencentVideoMessage
+
+/**
+ * TencentApiVideoSourceType 视频数据类型(请求方对数据类型可能会有限制)
+ */
+
+typedef enum
+{
+ /** 视频来源于本地或网络 */
+ AllVideo,
+ /** 视频来源于本地 */
+ LocalVideo,
+ /** 视频来源于网络 */
+ NetVideo,
+}TencentApiVideoSourceType;
+
+/**
+ * \brief 视频的消息体
+ *
+ * TencentVideoMessageV1 应用之间传递的视频消息体
+ */
+@interface TencentVideoMessageV1 : TencentBaseMessageObj
+
+/**
+ * 视频URL
+ * \note 不能超过1024
+ */
+@property (nonatomic, retain) NSString *sUrl;
+
+/**
+ * 视频来源 主要是用来让发起方指定视频的来源
+ * \note TencentApiVideoSourceType 对应的类型 只读参数
+ */
+@property (readonly, assign, nonatomic) NSInteger nType;
+
+/**
+ * 视频的预览图
+ * \note 图片不能大于1M
+ */
+@property (nonatomic, retain) NSData *dataImagePreview;
+
+/** 视频的预览图URL */
+@property (nonatomic, retain) NSString *sImagePreviewUrl;
+
+/** 视频的描述 */
+@property (nonatomic, retain) NSString *sDescription;
+
+/**
+ * 初始化视频消息
+ * \param url 视频URL
+ * \param type 视频来源类型
+ * \return 初始化返回的视频消息
+ */
+- (id)initWithVideoUrl:(NSString *)url type:(TencentApiVideoSourceType)type;
+
+
+/**
+ * 初始化视频消息
+ * \param type 视频来源类型
+ * \return 初始化返回的视频消息
+ */
+- (id)initWithType:(TencentApiVideoSourceType)type;
+@end
+
+#pragma mark TencentImageMessageObj
+/**
+ * \brief 视频图片消息体
+ *
+ * TencentVideoMessageV1 这是一个扩展的类 是一个图片视频类
+ * \note 图片视频可以任选一个内容填充 但是注意只能填一个 当有一种类型被填充后 另外一个种类型就无法填充了
+ */
+@interface TencentImageAndVideoMessageObjV1 : TencentBaseMessageObj
+
+/** 图片消息 */
+@property (nonatomic, retain) TencentImageMessageObjV1 *objImageMessage;
+
+/** 视频消息 */
+@property (nonatomic, retain) TencentVideoMessageV1 *objVideoMessage;
+
+/**
+ * 初始化图片消息
+ * \param dataImage 图片数据
+ * \param url 视频url
+ * \return 初始化返回的图片视频消息
+ */
+- (id)initWithMessage:(NSData *)dataImage videoUrl:(NSString *)url;
+
+/**
+ * 设置图片
+ * \param dataImage 图片数据
+ */
+- (void)setDataImage:(NSData *)dataImage;
+
+/**
+ * 设置视频
+ * \param videoUrl 视频URL
+ */
+- (void)setVideoUrl:(NSString *)videoUrl;
+@end
+
+#endif
--- /dev/null
+///
+/// \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"
+#import "TencentOAuthObject.h"
+#import "TencentApiInterface.h"
+
+@protocol TencentSessionDelegate;
+@protocol TencentLoginDelegate;
+@protocol TencentApiInterfaceDelegate;
+@protocol TencentWebViewDelegate;
+
+@class TencentApiReq;
+@class TencentApiResp;
+
+typedef enum
+{
+ kTencentNotAuthorizeState,
+ kTencentSSOAuthorizeState,
+ kTencentWebviewAuthorzieState,
+} TencentAuthorizeState;
+
+typedef enum
+{
+ kAuthModeClientSideToken,
+ kAuthModeServerSideCode,
+} TencentAuthMode;
+
+#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;
+
+/** 主要是互娱的游戏设置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;
+
+/**
+ * 用来获得当前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版本号
+ **/
++ (QQVersion)iphoneQQVersion;
+
+
+/**
+ * 用来获得当前手机TIM的版本号
+ * \return 返回手机qq版本号
+ **/
++ (QQVersion)iphoneTIMVersion;
+
+/**
+ * 初始化TencentOAuth对象
+ * \param appId 第三方应用在互联开放平台申请的唯一标识
+ * \param delegate 第三方应用用于接收请求返回结果的委托对象
+ * \return 初始化后的授权登录对象
+ */
+- (id)initWithAppId:(NSString *)appId
+ andDelegate:(id<TencentSessionDelegate>)delegate;
+
+
+/**
+ * 判断用户手机上是否安装手机QQ
+ * \return YES:安装 NO:没安装
+ */
++ (BOOL)iphoneQQInstalled;
+
+/**
+ * 判断用户手机上是否安装手机TIM
+ * \return YES:安装 NO:没安装
+ */
++ (BOOL)iphoneTIMInstalled;
+
+/**
+ * 判断用户手机上的手机QQ是否支持SSO登录
+ * \return YES:支持 NO:不支持
+ */
++ (BOOL)iphoneQQSupportSSOLogin;
+
+/**
+ * 判断用户手机上的手机TIM是否支持SSO登录
+ * \return YES:支持 NO:不支持
+ */
++ (BOOL)iphoneTIMSupportSSOLogin;
+
+/**
+ * 判断用户手机上是否安装手机QZone
+ * \return YES:安装 NO:没安装
+ */
++ (BOOL)iphoneQZoneInstalled;
+
+/**
+ * 判断用户手机上的手机QZone是否支持SSO登录
+ * \return YES:支持 NO:不支持
+ */
++ (BOOL)iphoneQZoneSupportSSOLogin;
+
+/**
+ * 登录授权
+ *
+ * \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;
+
+/**
+ * 增量授权,因用户没有授予相应接口调用的权限,需要用户确认是否授权
+ * \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;
+
+/**
+ * (静态方法)获取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;
+
+/**
+ * SDK内置webview实现定向分享时,第三方应用可以根据应用是否在白名单里来开启该配置开关,默认为关闭;
+ * 在白名单里的应用调用该接口后,即打开sdk内置webview的二级白名单开关(相对与sdk后台的白名单),
+ * 那么在sdk后台白名单校验请求失败的情况下,会继续先尝试采用内置webview进行分享。
+ */
+- (void)openSDKWebViewQQShareEnable;
+
+
+/**
+ * 获取用户QZone相册列表
+ * \attention 需\ref apply_perm
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)getListAlbum;
+
+/**
+ * 获取用户QZone相片列表
+ * \attention 需\ref apply_perm
+ * \param params 参数字典,字典的关键字参见TencentOAuthObject.h中的\ref TCListPhotoDic
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)getListPhotoWithParams:(NSMutableDictionary *)params;
+
+
+/**
+ * 分享到QZone
+ * \param params 参数字典,字典的关键字参见TencentOAuthObject.h中的\ref TCAddShareDic
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)addShareWithParams:(NSMutableDictionary *)params;
+
+
+/**
+ * 上传照片到QZone指定相册
+ * \attention 需\ref apply_perm
+ * \param params 参数字典,字典的关键字参见TencentOAuthObject.h中的\ref TCUploadPicDic
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)uploadPicWithParams:(NSMutableDictionary *)params;
+
+/**
+ * 在QZone相册中创建一个新的相册
+ * \attention 需\ref apply_perm
+ * \param params 参数字典,字典的关键字参见TencentOAuthObject.h中的\ref TCAddAlbumDic
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)addAlbumWithParams:(NSMutableDictionary *)params;
+
+/**
+ * 检查是否是QZone某个用户的粉丝
+ * \param params 参数字典,字典的关键字参见TencentOAuthObject.h中的\ref TCCheckPageFansDic
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)checkPageFansWithParams:(NSMutableDictionary *)params;
+
+/**
+ * 在QZone中发表一篇日志
+ * \attention 需\ref apply_perm
+ * \param params 参数字典,字典的关键字参见TencentOAuthObject.h中的\ref TCAddOneBlogDic
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)addOneBlogWithParams:(NSMutableDictionary *)params;
+
+/**
+ * 在QZone中发表一条说说
+ * \attention 需\ref apply_perm
+ * \param params 参数字典,字典的关键字参见TencentOAuthObject.h中的\ref TCAddTopicDic
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)addTopicWithParams:(NSMutableDictionary *)params;
+
+/**
+ * 设置QQ头像 使用默认的效果处理设置头像的界面
+ * \attention 需\ref apply_perm
+ * \param params 参数字典,字典的关键字参见TencentOAuthObject.h中的\ref TCSetUserHeadpic
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)setUserHeadpic:(NSMutableDictionary *)params;
+
+
+/**
+ * 设置QQ头像 会返回设置头像由第三方自己处理界面的弹出方式
+ * \attention 需\ref apply_perm
+ * \param params 参数字典,字典的关键字参见TencentOAuthObject.h中的\ref TCSetUserHeadpic
+ * \param viewController 设置头像的界面
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)setUserHeadpic:(NSMutableDictionary *)params andViewController:(UIViewController **)viewController;
+
+/**
+ * 获取QQ会员信息(仅包括是否为QQ会员,是否为年费QQ会员)
+ * \attention 需\ref apply_perm
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)getVipInfo;
+
+/**
+ * 获取QQ会员详细信息
+ * \attention 需\ref apply_perm
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)getVipRichInfo;
+
+/**
+ * QZone定向分享,可以@到具体好友,完成后将触发responseDidReceived:forMessage:回调,message:“SendStory”
+ * \param params 参数字典
+ * \param fopenIdArray 第三方应用预传人好友列表,好友以openid标识
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)sendStory:(NSMutableDictionary *)params friendList:(NSArray *)fopenIdArray;
+
+/**
+ * 发送应用邀请,完成后将触发responseDidReceived:forMessage:回调,message:“AppInvitation”
+ * \param desc 应用的描述文字,不超过35字符,如果为nil或@“”则显示默认描述
+ * \param imageUrl 应用的图标,如果为nil或者@“”则显示默认图标
+ * \param source 透传参数,由开发者自定义该参数内容
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)sendAppInvitationWithDescription:(NSString *)desc imageURL:(NSString *)imageUrl source:(NSString *)source;
+
+/**
+ * 发起PK或者发送炫耀,完成后将触发responseDidReceived:forMessage:回调,message:“AppChallenge”
+ * \param receiver 必须指定一位进行PK或者炫耀的好友,填写其OpenID,填写多个OpenID将截取第一个
+ * \param type 类型,"pk"或者“brag”
+ * \param imageUrl 炫耀/挑战场景图的URL
+ * \param message 炫耀/挑战中的内容描述,不超过50个字符,超过限制则自动截断
+ * \param source 透传参数,由开发者自定义该参数内容
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)sendChallenge:(NSString *)receiver type:(NSString *)type imageURL:(NSString *)imageUrl message:(NSString *)message source:(NSString *)source;
+
+/**
+ * 赠送或者请求礼物,完成后将触发responseDidReceived:forMessage:回调,message:“AppGiftRequest”
+ * \param receiver 赠送或者请求礼物的好友的OpenID,支持填写多个,OpenID之用","分隔,为nil时将由用户通过好友选择器选择好友
+ * \param exclude 用户通过好友选择器选择好友场景下,希望排除的好友(不显示在好友选择器)
+ * \param specified 用户通过好友选择器选择好友场景下,希望出现的指定好友
+ * \param only 是否只显示specified指定的好友
+ * \param type 类型,"request"或者“freegift”
+ * \param title 免费礼物或请求名称,不超过6个字符
+ * \param message 礼物或请求的默认赠言,控制在35个汉字以内,超过限制自动截断
+ * \param imageUrl 请求或礼物配图的URL,如果不传,则默认在弹框中显示应用的icon
+ * \param source 透传参数,由开发者自定义该参数内容
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)sendGiftRequest:(NSString *)receiver exclude:(NSString *)exclude specified:(NSString *)specified only:(BOOL)only type:(NSString *)type title:(NSString *)title message:(NSString *)message imageURL:(NSString *)imageUrl source:(NSString *)source;
+
+
+/**
+ * 退出指定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;
+
+@end
+
+#pragma mark - TencentSessionDelegate(开放接口回调协议)
+
+/**
+ * \brief TencentSessionDelegate iOS Open SDK 1.3 API回调协议
+ *
+ * 第三方应用需要实现每条需要调用的API的回调协议
+ */
+@protocol TencentSessionDelegate<NSObject, TencentLoginDelegate,
+ TencentApiInterfaceDelegate,
+ 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;
+
+
+/**
+ * 获取用户QZone相册列表回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/getListAlbumResponse.exp success
+ * 错误返回示例: \snippet example/getListAlbumResponse.exp fail
+ */
+- (void)getListAlbumResponse:(APIResponse*) response;
+
+/**
+ * 获取用户QZone相片列表
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/getListPhotoResponse.exp success
+ * 错误返回示例: \snippet example/getListPhotoResponse.exp fail
+ */
+- (void)getListPhotoResponse:(APIResponse*) response;
+
+/**
+ * 检查是否是QZone某个用户的粉丝回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/checkPageFansResponse.exp success
+ * 错误返回示例: \snippet example/checkPageFansResponse.exp fail
+ */
+- (void)checkPageFansResponse:(APIResponse*) response;
+
+/**
+ * 分享到QZone回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/addShareResponse.exp success
+ * 错误返回示例: \snippet example/addShareResponse.exp fail
+ */
+- (void)addShareResponse:(APIResponse*) response;
+
+/**
+ * 在QZone相册中创建一个新的相册回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/addAlbumResponse.exp success
+ * 错误返回示例: \snippet example/addAlbumResponse.exp fail
+ */
+- (void)addAlbumResponse:(APIResponse*) response;
+
+/**
+ * 上传照片到QZone指定相册回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/uploadPicResponse.exp success
+ * 错误返回示例: \snippet example/uploadPicResponse.exp fail
+ */
+- (void)uploadPicResponse:(APIResponse*) response;
+
+
+/**
+ * 在QZone中发表一篇日志回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/addOneBlogResponse.exp success
+ * 错误返回示例: \snippet example/addOneBlogResponse.exp fail
+ */
+- (void)addOneBlogResponse:(APIResponse*) response;
+
+/**
+ * 在QZone中发表一条说说回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/addTopicResponse.exp success
+ * 错误返回示例: \snippet example/addTopicResponse.exp fail
+ */
+- (void)addTopicResponse:(APIResponse*) response;
+
+/**
+ * 设置QQ头像回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/setUserHeadpicResponse.exp success
+ * 错误返回示例: \snippet example/setUserHeadpicResponse.exp fail
+ */
+- (void)setUserHeadpicResponse:(APIResponse*) response;
+
+/**
+ * 获取QQ会员信息回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/getVipInfoResponse.exp success
+ * 错误返回示例: \snippet example/getVipInfoResponse.exp fail
+ */
+- (void)getVipInfoResponse:(APIResponse*) response;
+
+/**
+ * 获取QQ会员详细信息回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ */
+- (void)getVipRichInfoResponse:(APIResponse*) response;
+
+/**
+ * sendStory分享的回调(已废弃,使用responseDidReceived:forMessage:)
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ */
+- (void)sendStoryResponse:(APIResponse*) response;
+
+
+/**
+ * 社交API统一回调接口
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \param message 响应的消息,目前支持‘SendStory’,‘AppInvitation’,‘AppChallenge’,‘AppGiftRequest’
+ */
+- (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
--- /dev/null
+///
+/// \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 = 1;GIF = 2;PNG = 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_nm,lbs_x,lbs_y通常一起使用,来明确标识一个地址。
+ */
+@property (nonatomic, retain) TCOptionalStr paramLbs_nm;
+
+/**
+ * 经度。-180.0到+180.0,+表示东经。lbs_nm,lbs_x,lbs_y通常一起使用,来明确标识一个地址。
+ */
+@property (nonatomic, retain) TCOptionalStr paramLbs_x;
+
+/**
+ * 纬度。-90.0到+90.0,+表示北纬。lbs_nm,lbs_x,lbs_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表示PC,1表示手机。用于当不传相册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
+ * \note(0:不发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
--- /dev/null
+///
+/// \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;
+
+/**
+ * \brief 手机qq的当前版本
+ */
+typedef enum QQVersion
+{
+ kQQUninstall,
+ kQQVersion3_0,
+ kQQVersion4_0, //支持sso登陆
+ kQQVersion4_2_1, //ios7兼容
+ kQQVersion4_5, //4.5版本,wpa会话
+ kQQVersion4_6, //4.6版本,sso登陆信令通道切换
+ kQQVersion4_7, //4.7版本 不确定新支持了什么样的属性
+} QQVersion;
+
+
+/**
+ * \breif TIM的当前版本
+ */
+typedef enum TIMVersion {
+ kTIMUinstall,
+ kTIMVersion1_1,
+}TIMVersion;
+
+/**
+ * \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_ONE_BLOG;
+
+/** 创建一个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;
+
+/** 同步分享到QQ空间、腾讯微博 */
+FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_ADD_SHARE;
+
+/** 验证是否认证空间粉丝 */
+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
+
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="X-UA-Compatible" content="IE=Edge">
+<meta charset="UTF-8">
+<title>社交渠道</title>
+<meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale = 1.0,user-scalable=no" />
+<meta name="format-detection" content="telephone=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<style>
+*{margin:0;padding:0}
+.header{text-align:center;height:44px;background:-webkit-gradient(linear,0 0,0 100%,from(#4c4c4c),to(#313131));border-top:#5b5b5b 1px solid;position:relative;line-height:44px}
+.header h1{color:#fff;font-weight:bold;font-size:20px}
+.header a{width:49px;height:29px;background-size:49px 29px;position:absolute;top:7px;display:block;text-indent:-999em;cursor:pointer}
+.header .back{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEkAAAAsCAYAAAApSpU1AAAFgElEQVR42u2bSWgsRRjH40XEg3rwIujBg6KCp4CH7AnZ933f9z0hK7kk8RCEhCwEMTmID81C8JIVQRJEfGQ5PEwOnpKDh+T0nomCGngolvUrpsaeYWbSnel5ODOv4Jfp/mrpqv9UffV1TyciwqYUGRn5keRjydeS7yWPgogfJOuSVsnrEXYn2ei7ku+Sk5NFZWWlaG1tFd3d3aK/vz9o6OnpES0tLaKoqEjIsfwu6bNToDzJbU1NjRgbGxPDw8NiYGAgqATSDA4OitHRUXXsEGvJDoEqJX8zcxCG2dPR0SHa2tqCkvb2dtHZ2Sl6e3vFyMiIKCwsRKgufwTKlTxFIKYqF2G6Njc3Bz2MA7EQTY7xRvLafQR6X/JHY2OjaoxGm5qaQgrEYlXk5OQgVJtVgV6W/FRRUaEEorFQE8goVFlZGSI9sCrS5wUFBaKrq0s1wmwKZZgMcsz7VgQqyszMVA4apRsaGkKe8vJyRHpoVqA3JL/U1dUpH4TKz0VyFegFybfEDuxmVK6vrw8LHD7JlEjdubm5aktEIGZTuFBaWnq3SLLAB0TUennV1taGFSUlJb5FkpkvcvNHQRw1lbj9CCfMiPQJy4ytngrV1dXPDEKMxcVFsbe390yv605xcbF3kWRGDPdlCMQMqqqq8gsCz5ubG7G7u+tiRwhscHJyIi4uLlQ5nW5vb8XU1JTXOlagntV+O250H3oS6BXJz3h2nBeFeQTiL4hA4lPb6DxCIA6Qh21jY0OJ46kd8km6jhm4BvWs9tlxk+tRpAcsMxw1BYk67eL4+Fh1Wp/TceO5GbRIVupwDepZ7a9HkaShOC0tTTlqBCKYshtCCX28s7Mjrq6uxMLCgld4bGGsTx2SlWsiEvWs9pVbMBeRHFH1NQqyxFhugUYP2FeijKc6+hwBPCXsxjLu7ZghPz//P5F0VJ2Xl6d2MgoQSNnF0NCQmJ+fd6LteiYZ8zQHBwdqsMbyug5Jn5+fn6tlbKzLOXZjGepZ7Td6GEXqycrKUo4agYgP7GR7e9vlW3a3M4i5uTmnnftDnC12b23pc8pgcy9jrOupjBmcIsk/bxFVs8RYh3YLdNcAr6+v1Sfp6OhICXR2dqZEYgb+X0RiqW2mpKSoDAKoQKEHqM8RCBvH6+vrShidODfThhbAvQx2X2XMwC5vXG6vSs5TU1NVABUo9AA5np2dVceTk5POfGaSTswmdllfbQACaBE02mYsg91qfx2Pb112tw8lf+KbiA8CwdbWlhogx3qpcYxQl5eXKm9tbU3BrMJGnrc2YH9/3ymKEey6DOfUs9rf7Oxsj3FSdVxcnIoPAoEeIMd0fHV11WlDsImJCWdZjhEKu7c2zKJFstpfJoy3iPvThIQEFSPYDd8uaXx83GnTQhHhu5fnh8Ll5WUXmxbJynW1SFb760skHpEcJSUlKe9uB319feL09FQNTn+ylDY3N50g1szMjEeor9ui7H0S9az2m2f6vp4CvCl5zI6Hh/eXpaUl1dGVlRV1Pj09LQ4PD112M1+J8rotLRI2s+gvxGq/MzIy7nyelMTjEtTEy/sLnfWV5wv3sgzYyrX5cnxd3xvp6emmHt+OxsbGKi8fjpgVSQWa7Hg4sXCDJyJmfy1RgWZiYqJyZOEEwbWVHydVoMmLWjizcIGNy7RIDqGqoqOjn4tkQqjPYmJilEMLB1g5ll6YcIj0kuRHHDlOLdTBD8vxfnGfl7jekfzGrUuoi8SqkWNtue/rgASaT1GaHSAU4bZMjvEJP7H5895kueSv+Ph45eBCjaioKERqsuMN3HTeeyYqDxVxmEEOgebtfJf7bcmu5B9CBJw6syvYoN8OcX7lPwMiApFkw+9JhiRfSb5h6wwyvpQ0evJB/wIFDhaTvqlwnwAAAABJRU5ErkJggg==);left:5px}
+</style>
+</head>
+<body>
+<div class="container" id="container">
+ <div class="header">
+ <h1 id="title"></h1>
+ <a href="javascript:void(0)" class="back" id="cancel">返回</a>
+ <a href="javascript:void(0)" style="display:none" id="confirm"></a>
+ </div>
+ <div id="main"></div>
+</div>
+<script>
+(function () {
+ try {
+ document.domain = "qq.com";
+ } catch (_) {
+ alert("invalid domain");
+ }
+ function getParam(name) {
+ var re = new RegExp("(?:\\?|#|&)" + name + "=([^&]*)(?:$|&|#)", "i"), m = re.exec(window.location.href);
+ var ret = m ? m[1] : "";
+ ret = ret.replace(/[+]/ig, "%20");
+ return ret;
+ }
+ var iface = getParam("iface");
+ switch (iface) {
+ case "AppChallenge":
+ case "AppInvitation":
+ case "AppGiftRequest":
+ case "SendStory": {
+ var appid = getParam("oauth_consumer_key"), type = getParam("type");
+ var url = "tencent" + appid + "://" + iface + "/cancel";
+ document.getElementById("cancel").addEventListener("click", function () {
+ setTimeout(function () {
+ window.open(url, "_self");
+ }, 0);
+ }, false);
+ document.getElementById("title").innerHTML = {
+ AppChallenge : type == "pk" ? "发送挑战" : "发送炫耀",
+ AppInvitation : "发送应用邀请",
+ AppGiftRequest : type == "request" ? "发送应用请求" : "发送免费礼物",
+ SendStory : "发送分享"
+ }[iface];
+ document.write('<script type="text/javascript" src="https://qzonestyle.gtimg.cn/open/mobile/' + {
+ AppChallenge : "brag_ios/js/sdk_brag.js",
+ AppInvitation : "invite_ios/js/sdk_invite.js",
+ AppGiftRequest : "request_ios/js/sdk_request.js",
+ SendStory : "story_ios/js/sdk_story.js"
+ }[iface] + '"><\/script>');
+ break;
+ }
+ default:
+ return;
+ }
+})();
+</script>
+</body>
+</html>
<param name="ios-package" value="ScreenshotBlocker" />
<param name="onload" value="true" />
</feature>
+ <feature name="QQSDK">
+ <param name="ios-package" value="CDVQQSDK" />
+ </feature>
<name short="大理智警">dlapp</name>
<description>
A sample Apache Cordova application that responds to the deviceready event.
<preference name="StatusBarOverlaysWebView" value="true" />
<preference name="StatusBarStyle" value="lightcontent" />
<preference name="CameraUsesGeolocation" value="false" />
+ <preference name="QQ_APP_ID" value="101885581" />
<preference name="AutoHideSplashScreen" value="true" />
<preference name="SplashScreenDelay" value="0" />
<preference name="SplashShowOnlyFirstTime" value="true" />
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
+ <key>CFBundleURLTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>CFBundleURLName</key>
+ <string>tencentopenapi</string>
+ <key>CFBundleURLSchemes</key>
+ <array>
+ <string>tencent101885581</string>
+ </array>
+ </dict>
+ </array>
+ <key>LSApplicationQueriesSchemes</key>
+ <array>
+ <string>mqqapi</string>
+ <string>mqq</string>
+ <string>mqqOpensdkSSoLogin</string>
+ <string>mqqconnect</string>
+ <string>mqqopensdkdataline</string>
+ <string>mqqopensdkgrouptribeshare</string>
+ <string>mqqopensdkfriend</string>
+ <string>mqqopensdkapi</string>
+ <string>mqqopensdkapiV2</string>
+ <string>mqqopensdkapiV3</string>
+ <string>mqqopensdkapiV4</string>
+ <string>mqzoneopensdk</string>
+ <string>wtloginmqq</string>
+ <string>wtloginmqq2</string>
+ <string>mqqwpa</string>
+ <string>mqzone</string>
+ <string>mqzonev2</string>
+ <string>mqzoneshare</string>
+ <string>wtloginqzone</string>
+ <string>mqzonewx</string>
+ <string>mqzoneopensdkapiV2</string>
+ <string>mqzoneopensdkapi19</string>
+ <string>mqzoneopensdkapi</string>
+ <string>mqqgamebindinggroup</string>
+ <string>tencentapi.qq.reqContent</string>
+ <string>tencentapi.qzone.reqContent</string>
+ <string>tim</string>
+ <string>timapi</string>
+ <string>timopensdkfriend</string>
+ <string>timwpa</string>
+ <string>timgamebindinggroup</string>
+ <string>timapiwallet</string>
+ <string>timOpensdkSSoLogin</string>
+ <string>wtlogintim</string>
+ <string>timopensdkgrouptribeshare</string>
+ <string>timopensdkapiV4</string>
+ <string>timopensdkdataline</string>
+ <string>wtlogintimV1</string>
+ <string>timapiV1</string>
+ </array>
<key>NSCameraUsageDescription</key>
<string>APP需要使用您的相机权限,没有该权限将无法完成扫一扫功能</string>
<key>NSPhotoLibraryUsageDescription</key>
{
- "Security.framework": 3,
- "SystemConfiguration.framework": 2,
+ "Security.framework": 4,
+ "SystemConfiguration.framework": 3,
"LocalAuthentication.framework": 1,
"ImageIO.framework": 1,
"CoreLocation.framework": 1,
"AVFoundation.framework": 1,
"CFNetwork.framework": 1,
"CoreFoundation.framework": 1,
- "CoreTelephony.framework": 1,
+ "CoreTelephony.framework": 2,
"Foundation.framework": 1,
"UIKit.framework": 2,
- "libz.tbd": 1,
+ "libz.tbd": 2,
"AdSupport.framework": 1,
"UserNotifications.framework": 1,
"libresolv.tbd": 1,
- "WebKit.framework": 1
+ "WebKit.framework": 1,
+ "libiconv.tbd": 1,
+ "libsqlite3.tbd": 1,
+ "libstdc++.tbd": 1
}
\ No newline at end of file
{
"xml": "<feature name=\"screenshotName\"><param name=\"ios-package\" value=\"ScreenshotBlocker\" /><param name=\"onload\" value=\"true\" /></feature>",
"count": 1
+ },
+ {
+ "xml": "<feature name=\"QQSDK\"><param name=\"ios-package\" value=\"CDVQQSDK\" /></feature>",
+ "count": 1
+ },
+ {
+ "xml": "<preference name=\"QQ_APP_ID\" value=\"101885581\" />",
+ "count": 1
}
]
}
"mode": "merge",
"id": "config.xml"
}
+ ],
+ "CFBundleURLTypes": [
+ {
+ "xml": "<array><dict><key>CFBundleTypeRole</key><string>Editor</string><key>CFBundleURLName</key><string>tencentopenapi</string><key>CFBundleURLSchemes</key><array><string>tencent101885581</string></array></dict></array>",
+ "count": 1
+ }
+ ],
+ "LSApplicationQueriesSchemes": [
+ {
+ "xml": "<array><string>mqqapi</string><string>mqq</string><string>mqqOpensdkSSoLogin</string><string>mqqconnect</string><string>mqqopensdkdataline</string><string>mqqopensdkgrouptribeshare</string><string>mqqopensdkfriend</string><string>mqqopensdkapi</string><string>mqqopensdkapiV2</string><string>mqqopensdkapiV3</string><string>mqqopensdkapiV4</string><string>mqzoneopensdk</string><string>wtloginmqq</string><string>wtloginmqq2</string><string>mqqwpa</string><string>mqzone</string><string>mqzonev2</string><string>mqzoneshare</string><string>wtloginqzone</string><string>mqzonewx</string><string>mqzoneopensdkapiV2</string><string>mqzoneopensdkapi19</string><string>mqzoneopensdkapi</string><string>mqzoneopensdk</string><string>mqqgamebindinggroup</string><string>tencentapi.qq.reqContent</string><string>tencentapi.qzone.reqContent</string><string>tim</string><string>timapi</string><string>timopensdkfriend</string><string>timwpa</string><string>timgamebindinggroup</string><string>timapiwallet</string><string>timOpensdkSSoLogin</string><string>wtlogintim</string><string>timopensdkgrouptribeshare</string><string>timopensdkapiV4</string><string>timgamebindinggroup</string><string>timopensdkdataline</string><string>wtlogintimV1</string><string>timapiV1</string></array>",
+ "count": 1
+ }
]
}
},
},
"cordova-plugin-prevent-screenshot-coffice": {
"PACKAGE_NAME": "$(PRODUCT_BUNDLE_IDENTIFIER)"
+ },
+ "cordova-plugin-qqsdk": {
+ "QQ_APP_ID": "101885581",
+ "PACKAGE_NAME": "$(PRODUCT_BUNDLE_IDENTIFIER)"
}
},
"dependent_plugins": {},
"clobbers": [
"window.plugins.preventscreenshot"
]
+ },
+ {
+ "id": "cordova-plugin-qqsdk.QQSDK",
+ "file": "plugins/cordova-plugin-qqsdk/www/qq.js",
+ "pluginId": "cordova-plugin-qqsdk",
+ "clobbers": [
+ "QQSDK"
+ ]
}
],
"plugin_metadata": {
"cordova-plugin-wkwebview-engine": "1.2.1",
"cordova-plugin-brightness": "0.1.5",
"cordova-plugin-fingerprint-aio": "3.0.1",
- "cordova-plugin-prevent-screenshot-coffice": "1.0.1"
+ "cordova-plugin-prevent-screenshot-coffice": "1.0.1",
+ "cordova-plugin-qqsdk": "0.9.7"
}
}
"clobbers": [
"window.plugins.preventscreenshot"
]
+ },
+ {
+ "id": "cordova-plugin-qqsdk.QQSDK",
+ "file": "plugins/cordova-plugin-qqsdk/www/qq.js",
+ "pluginId": "cordova-plugin-qqsdk",
+ "clobbers": [
+ "QQSDK"
+ ]
}
];
module.exports.metadata = {
"cordova-plugin-wkwebview-engine": "1.2.1",
"cordova-plugin-brightness": "0.1.5",
"cordova-plugin-fingerprint-aio": "3.0.1",
- "cordova-plugin-prevent-screenshot-coffice": "1.0.1"
+ "cordova-plugin-prevent-screenshot-coffice": "1.0.1",
+ "cordova-plugin-qqsdk": "0.9.7"
};
});
\ No newline at end of file
--- /dev/null
+cordova.define("cordova-plugin-qqsdk.QQSDK", function(require, exports, module) {
+
+var cordova = require('cordova');
+module.exports = {
+ Scene: {
+ QQ: 0, // QQ 好友
+ QQZone: 1, // QQ 空间
+ Favorite: 2 // 收藏
+ },
+ ClientType: {
+ QQ: 0, // QQ 手机客户端
+ TIM: 1 // TIM 客户端
+ },
+ ssoLogin:function(successCallback, errorCallback, args){
+ if(args === undefined) {
+ args = {}
+ }
+ cordova.exec(successCallback, errorCallback, "QQSDK", "ssoLogin",[args]);
+ },
+ logout:function(successCallback, errorCallback){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "logout", []);
+ },
+ checkClientInstalled:function(successCallback, errorCallback, args){
+ if(args === undefined) {
+ args = {}
+ }
+ cordova.exec(successCallback, errorCallback, "QQSDK", "checkClientInstalled", [args]);
+ },
+ shareText:function(successCallback, errorCallback, args){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "shareText", [args]);
+ },
+ shareImage:function(successCallback, errorCallback, args){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "shareImage", [args]);
+ },
+ shareNews:function(successCallback, errorCallback, args){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "shareNews", [args]);
+ },
+ shareAudio:function(successCallback, errorCallback, args){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "shareAudio", [args]);
+ },
+};
+
+});
},
"cordova-plugin-prevent-screenshot-coffice": {
"PACKAGE_NAME": "com.dalipolice.app"
+ },
+ "cordova-plugin-qqsdk": {
+ "QQ_APP_ID": "101885581",
+ "PACKAGE_NAME": "com.dalipolice.app"
}
},
"dependent_plugins": {
},
"cordova-plugin-prevent-screenshot-coffice": {
"PACKAGE_NAME": "com.dalipolice.app"
+ },
+ "cordova-plugin-qqsdk": {
+ "QQ_APP_ID": "101885581",
+ "PACKAGE_NAME": "com.dalipolice.app"
}
},
"dependent_plugins": {
--- /dev/null
+import { Plugin, Cordova, IonicNativePlugin } from '@ionic-native/core';
+import { Injectable } from '@angular/core';
+
+export interface QQShareOptions {
+
+ /**
+ * The clinet type, QQ or TIM
+ * Default is QQ
+ */
+ client?: number;
+
+ /**
+ * The Share Sence
+ * Default is QQ
+ */
+ scene?: number;
+
+ /**
+ * The text for shareText
+ */
+ text?: string;
+
+ /**
+ * The url for share news or audio
+ */
+ url?: string;
+
+ /**
+ * The title for share image,news or audio
+ */
+ title?: string;
+
+ /**
+ * The description for share image,news or audio
+ */
+ description?: string;
+
+ /**
+ * The image for share image,news or audio
+ * Image supports three types:
+ * 1. Network URL
+ * 2. Base64
+ * 3. Absolute file path
+ */
+ image?: string;
+
+ /**
+ * The URL for audio
+ */
+ flashUrl?: string;
+}
+
+/**
+ * @name QQSDK
+ * @description
+ * This Plugin is a wrapper around the Tencent QQ SDK for Android and iOS. Provides access to QQ ssoLogin, QQ Sharing, QQZone Sharing etc.
+ *
+ * Requires Cordova plugin: `cordova-plugin-qqsdk`. For more info, please see the [QQSDK plugin docs](https://github.com/iVanPan/Cordova_QQ).
+ *
+ * @usage
+ * ```typescript
+ * import { QQSDK, QQShareOptions } from '@ionic-native/qqsdk';
+ *
+ * constructor(private qq: QQSDK) { }
+ *
+ * ...
+ *
+ *
+ * const options: QQShareOptions = {
+ * client: this.qq.ClientType.QQ,
+ * scene: this.qq.Scene.QQ,
+ * title: 'This is a title for cordova-plugin-qqsdk',
+ * url: 'https://cordova.apache.org/',
+ * image: 'https://cordova.apache.org/static/img/cordova_bot.png',
+ * description: 'This is Cordova QQ share description',
+ * flashUrl: 'http://stream20.qqmusic.qq.com/30577158.mp3',
+ * };
+ *
+ * const clientOptions: QQShareOptions = {
+ * client: this.qq.ClientType.QQ,
+ * };
+ *
+ * const shareTextOptions: QQShareOptions = {
+ * client: this.qq.ClientType.QQ,
+ * text: 'This is Share Text',
+ * scene: this.qq.Scene.QQ,
+ * };
+ *
+ * this.qq.ssoLogin(clientOptions)
+ * .then(result => {
+ * // Success
+ * console.log('token is ' + result.access_token);
+ * console.log('userid is ' + result.userid);
+ * console.log('expires_time is ' + new Date(parseInt(result.expires_time)) + ' TimeStamp is ' + result.expires_time);
+ * })
+ * .catch(error => {
+ * console.log(error); // Failed
+ * });
+ *
+ * this.qq.logout()
+ * .then(() => {
+ * console.log('logout success');
+ * })
+ * .catch(error => {
+ * console.log(error);
+ * });
+ *
+ * this.qq.checkClientInstalled(clientOptions)
+ * .then(() => {
+ * console.log('Installed');
+ * })
+ * .catch(() => {
+ * console.log('Not Installed');
+ * });
+ *
+ * this.qq.shareText(shareTextOptions)
+ * .then(() => {
+ * console.log('shareText success');
+ * })
+ * .catch(error => {
+ * console.log(error);
+ * });
+ *
+ * this.qq.shareImage(options)
+ * .then(() => {
+ * console.log('shareImage success');
+ * })
+ * .catch(error => {
+ * console.log(error);
+ * });
+ * }
+ *
+ * this.qq.shareNews(options)
+ * .then(() => {
+ * console.log('shareNews success');
+ * })
+ * .catch(error => {
+ * console.log(error);
+ * });
+ * }
+ *
+ * this.qq.shareAudio(options)
+ * .then(() => {
+ * console.log('shareAudio success');
+ * })
+ * .catch(error => {
+ * console.log(error);
+ * });
+ *
+ * ```
+ *
+ * @interfaces
+ * QQShareOptions
+ */
+@Plugin({
+ pluginName: 'QQSDK',
+ plugin: 'cordova-plugin-qqsdk',
+ pluginRef: 'QQSDK',
+ repo: 'https://github.com/iVanPan/Cordova_QQ',
+ platforms: ['Android', 'iOS'],
+ install: 'ionic cordova plugin add cordova-plugin-qqsdk --variable QQ_APP_ID=YOUR_QQ_APPID',
+ installVariables: ['QQ_APP_ID'],
+})
+@Injectable()
+export class QQSDK extends IonicNativePlugin {
+
+ /**
+ * QQ Share Scene
+ * @type {{QQ: number; QQZone: number; Favorite: number}}
+ */
+ Scene = {
+ QQ: 0,
+ QQZone: 1,
+ Favorite: 2
+ };
+ /**
+ * client type: QQ application or TIM application
+ * @type {{QQ: number; TIM: number}}
+ */
+ ClientType = {
+ QQ: 0,
+ TIM: 1
+ };
+
+ /**
+ * open QQ or TIM client perform ssoLogin
+ * @param options
+ * @returns {Promise<any>} Returns a Promise that resolves with the success return, or rejects with an error.
+ */
+ @Cordova({
+ callbackOrder: 'reverse'
+ })
+ ssoLogin(options: QQShareOptions): Promise<any> {
+ return;
+ }
+
+ @Cordova({
+ callbackOrder: 'reverse'
+ })
+ logout(): Promise<any> {
+ return;
+ }
+
+ /**
+ * Detect if the QQ application or TIM application is installed on the device.
+ *
+ * @returns {Promise<any>} Returns a Promise that resolves with the success return, or rejects with an error.
+ */
+ @Cordova({
+ callbackOrder: 'reverse'
+ })
+ checkClientInstalled(options: QQShareOptions): Promise<any> {
+ return;
+ }
+
+ /**
+ * shareText
+ * @param options
+ * @returns {Promise<any>} Returns a Promise that resolves with the success return, or rejects with an error.
+ */
+ @Cordova({
+ callbackOrder: 'reverse'
+ })
+ shareText(options: QQShareOptions): Promise<any> {
+ return;
+ }
+
+ /**
+ * shareImage
+ * @param options
+ * @returns {Promise<any>} Returns a Promise that resolves with the success return, or rejects with an error.
+ */
+ @Cordova({
+ callbackOrder: 'reverse'
+ })
+ shareImage(options: QQShareOptions): Promise<any> {
+ return;
+ }
+
+ /**
+ * shareNews
+ * @param options
+ * @returns {Promise<any>} Returns a Promise that resolves with the success return, or rejects with an error.
+ */
+ @Cordova({
+ callbackOrder: 'reverse'
+ })
+ shareNews(options: QQShareOptions): Promise<any> {
+ return;
+ }
+
+ /**
+ * shareAudio
+ * @param options
+ * @returns {Promise<any>} Returns a Promise that resolves with the success return, or rejects with an error.
+ */
+ @Cordova({
+ callbackOrder: 'reverse'
+ })
+ shareAudio(options: QQShareOptions): Promise<any> {
+ return;
+ }
+}
--- /dev/null
+The MIT License (MIT)
+
+Copyright (c) 2015 Van
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
--- /dev/null
+/*!
+ * Bootstrap v3.3.7 (http://getbootstrap.com)
+ * Copyright 2011-2017 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+/*!
+ * Generated using the Bootstrap Customizer (<none>)
+ * Config saved to config.json and <none>
+ */
+/*!
+ * Bootstrap v3.3.7 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
+html {
+ font-family: sans-serif;
+ -ms-text-size-adjust: 100%;
+ -webkit-text-size-adjust: 100%;
+}
+body {
+ margin: 0;
+}
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+ display: block;
+}
+audio,
+canvas,
+progress,
+video {
+ display: inline-block;
+ vertical-align: baseline;
+}
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+[hidden],
+template {
+ display: none;
+}
+a {
+ background-color: transparent;
+}
+a:active,
+a:hover {
+ outline: 0;
+}
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+b,
+strong {
+ font-weight: bold;
+}
+dfn {
+ font-style: italic;
+}
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+mark {
+ background: #ff0;
+ color: #000;
+}
+small {
+ font-size: 80%;
+}
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+sup {
+ top: -0.5em;
+}
+sub {
+ bottom: -0.25em;
+}
+img {
+ border: 0;
+}
+svg:not(:root) {
+ overflow: hidden;
+}
+figure {
+ margin: 1em 40px;
+}
+hr {
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ height: 0;
+}
+pre {
+ overflow: auto;
+}
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace, monospace;
+ font-size: 1em;
+}
+button,
+input,
+optgroup,
+select,
+textarea {
+ color: inherit;
+ font: inherit;
+ margin: 0;
+}
+button {
+ overflow: visible;
+}
+button,
+select {
+ text-transform: none;
+}
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ -webkit-appearance: button;
+ cursor: pointer;
+}
+button[disabled],
+html input[disabled] {
+ cursor: default;
+}
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+input {
+ line-height: normal;
+}
+input[type="checkbox"],
+input[type="radio"] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ padding: 0;
+}
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+input[type="search"] {
+ -webkit-appearance: textfield;
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+}
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+fieldset {
+ border: 1px solid #c0c0c0;
+ margin: 0 2px;
+ padding: 0.35em 0.625em 0.75em;
+}
+legend {
+ border: 0;
+ padding: 0;
+}
+textarea {
+ overflow: auto;
+}
+optgroup {
+ font-weight: bold;
+}
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+td,
+th {
+ padding: 0;
+}
+* {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+*:before,
+*:after {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+html {
+ font-size: 10px;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+body {
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #333333;
+ background-color: #ffffff;
+}
+input,
+button,
+select,
+textarea {
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+}
+a {
+ color: #337ab7;
+ text-decoration: none;
+}
+a:hover,
+a:focus {
+ color: #23527c;
+ text-decoration: underline;
+}
+a:focus {
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+figure {
+ margin: 0;
+}
+img {
+ vertical-align: middle;
+}
+.img-responsive {
+ display: block;
+ max-width: 100%;
+ height: auto;
+}
+.img-rounded {
+ border-radius: 6px;
+}
+.img-thumbnail {
+ padding: 4px;
+ line-height: 1.42857143;
+ background-color: #ffffff;
+ border: 1px solid #dddddd;
+ border-radius: 4px;
+ -webkit-transition: all 0.2s ease-in-out;
+ -o-transition: all 0.2s ease-in-out;
+ transition: all 0.2s ease-in-out;
+ display: inline-block;
+ max-width: 100%;
+ height: auto;
+}
+.img-circle {
+ border-radius: 50%;
+}
+hr {
+ margin-top: 20px;
+ margin-bottom: 20px;
+ border: 0;
+ border-top: 1px solid #eeeeee;
+}
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ margin: -1px;
+ padding: 0;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0;
+}
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+}
+[role="button"] {
+ cursor: pointer;
+}
+.btn {
+ display: inline-block;
+ margin-bottom: 0;
+ font-weight: normal;
+ text-align: center;
+ vertical-align: middle;
+ -ms-touch-action: manipulation;
+ touch-action: manipulation;
+ cursor: pointer;
+ background-image: none;
+ border: 1px solid transparent;
+ white-space: nowrap;
+ padding: 6px 12px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ border-radius: 4px;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+.btn:focus,
+.btn:active:focus,
+.btn.active:focus,
+.btn.focus,
+.btn:active.focus,
+.btn.active.focus {
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+.btn:hover,
+.btn:focus,
+.btn.focus {
+ color: #333333;
+ text-decoration: none;
+}
+.btn:active,
+.btn.active {
+ outline: 0;
+ background-image: none;
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+}
+.btn.disabled,
+.btn[disabled],
+fieldset[disabled] .btn {
+ cursor: not-allowed;
+ opacity: 0.65;
+ filter: alpha(opacity=65);
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+a.btn.disabled,
+fieldset[disabled] a.btn {
+ pointer-events: none;
+}
+.btn-default {
+ color: #333333;
+ background-color: #ffffff;
+ border-color: #cccccc;
+}
+.btn-default:focus,
+.btn-default.focus {
+ color: #333333;
+ background-color: #e6e6e6;
+ border-color: #8c8c8c;
+}
+.btn-default:hover {
+ color: #333333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ color: #333333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+.btn-default:active:hover,
+.btn-default.active:hover,
+.open > .dropdown-toggle.btn-default:hover,
+.btn-default:active:focus,
+.btn-default.active:focus,
+.open > .dropdown-toggle.btn-default:focus,
+.btn-default:active.focus,
+.btn-default.active.focus,
+.open > .dropdown-toggle.btn-default.focus {
+ color: #333333;
+ background-color: #d4d4d4;
+ border-color: #8c8c8c;
+}
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ background-image: none;
+}
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled.focus,
+.btn-default[disabled].focus,
+fieldset[disabled] .btn-default.focus {
+ background-color: #ffffff;
+ border-color: #cccccc;
+}
+.btn-default .badge {
+ color: #ffffff;
+ background-color: #333333;
+}
+.btn-primary {
+ color: #ffffff;
+ background-color: #337ab7;
+ border-color: #2e6da4;
+}
+.btn-primary:focus,
+.btn-primary.focus {
+ color: #ffffff;
+ background-color: #286090;
+ border-color: #122b40;
+}
+.btn-primary:hover {
+ color: #ffffff;
+ background-color: #286090;
+ border-color: #204d74;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ color: #ffffff;
+ background-color: #286090;
+ border-color: #204d74;
+}
+.btn-primary:active:hover,
+.btn-primary.active:hover,
+.open > .dropdown-toggle.btn-primary:hover,
+.btn-primary:active:focus,
+.btn-primary.active:focus,
+.open > .dropdown-toggle.btn-primary:focus,
+.btn-primary:active.focus,
+.btn-primary.active.focus,
+.open > .dropdown-toggle.btn-primary.focus {
+ color: #ffffff;
+ background-color: #204d74;
+ border-color: #122b40;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ background-image: none;
+}
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled.focus,
+.btn-primary[disabled].focus,
+fieldset[disabled] .btn-primary.focus {
+ background-color: #337ab7;
+ border-color: #2e6da4;
+}
+.btn-primary .badge {
+ color: #337ab7;
+ background-color: #ffffff;
+}
+.btn-success {
+ color: #ffffff;
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+.btn-success:focus,
+.btn-success.focus {
+ color: #ffffff;
+ background-color: #449d44;
+ border-color: #255625;
+}
+.btn-success:hover {
+ color: #ffffff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ color: #ffffff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+.btn-success:active:hover,
+.btn-success.active:hover,
+.open > .dropdown-toggle.btn-success:hover,
+.btn-success:active:focus,
+.btn-success.active:focus,
+.open > .dropdown-toggle.btn-success:focus,
+.btn-success:active.focus,
+.btn-success.active.focus,
+.open > .dropdown-toggle.btn-success.focus {
+ color: #ffffff;
+ background-color: #398439;
+ border-color: #255625;
+}
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ background-image: none;
+}
+.btn-success.disabled:hover,
+.btn-success[disabled]:hover,
+fieldset[disabled] .btn-success:hover,
+.btn-success.disabled:focus,
+.btn-success[disabled]:focus,
+fieldset[disabled] .btn-success:focus,
+.btn-success.disabled.focus,
+.btn-success[disabled].focus,
+fieldset[disabled] .btn-success.focus {
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+.btn-success .badge {
+ color: #5cb85c;
+ background-color: #ffffff;
+}
+.btn-info {
+ color: #ffffff;
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+.btn-info:focus,
+.btn-info.focus {
+ color: #ffffff;
+ background-color: #31b0d5;
+ border-color: #1b6d85;
+}
+.btn-info:hover {
+ color: #ffffff;
+ background-color: #31b0d5;
+ border-color: #269abc;
+}
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ color: #ffffff;
+ background-color: #31b0d5;
+ border-color: #269abc;
+}
+.btn-info:active:hover,
+.btn-info.active:hover,
+.open > .dropdown-toggle.btn-info:hover,
+.btn-info:active:focus,
+.btn-info.active:focus,
+.open > .dropdown-toggle.btn-info:focus,
+.btn-info:active.focus,
+.btn-info.active.focus,
+.open > .dropdown-toggle.btn-info.focus {
+ color: #ffffff;
+ background-color: #269abc;
+ border-color: #1b6d85;
+}
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ background-image: none;
+}
+.btn-info.disabled:hover,
+.btn-info[disabled]:hover,
+fieldset[disabled] .btn-info:hover,
+.btn-info.disabled:focus,
+.btn-info[disabled]:focus,
+fieldset[disabled] .btn-info:focus,
+.btn-info.disabled.focus,
+.btn-info[disabled].focus,
+fieldset[disabled] .btn-info.focus {
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+.btn-info .badge {
+ color: #5bc0de;
+ background-color: #ffffff;
+}
+.btn-warning {
+ color: #ffffff;
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+.btn-warning:focus,
+.btn-warning.focus {
+ color: #ffffff;
+ background-color: #ec971f;
+ border-color: #985f0d;
+}
+.btn-warning:hover {
+ color: #ffffff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ color: #ffffff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+.btn-warning:active:hover,
+.btn-warning.active:hover,
+.open > .dropdown-toggle.btn-warning:hover,
+.btn-warning:active:focus,
+.btn-warning.active:focus,
+.open > .dropdown-toggle.btn-warning:focus,
+.btn-warning:active.focus,
+.btn-warning.active.focus,
+.open > .dropdown-toggle.btn-warning.focus {
+ color: #ffffff;
+ background-color: #d58512;
+ border-color: #985f0d;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ background-image: none;
+}
+.btn-warning.disabled:hover,
+.btn-warning[disabled]:hover,
+fieldset[disabled] .btn-warning:hover,
+.btn-warning.disabled:focus,
+.btn-warning[disabled]:focus,
+fieldset[disabled] .btn-warning:focus,
+.btn-warning.disabled.focus,
+.btn-warning[disabled].focus,
+fieldset[disabled] .btn-warning.focus {
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+.btn-warning .badge {
+ color: #f0ad4e;
+ background-color: #ffffff;
+}
+.btn-danger {
+ color: #ffffff;
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+.btn-danger:focus,
+.btn-danger.focus {
+ color: #ffffff;
+ background-color: #c9302c;
+ border-color: #761c19;
+}
+.btn-danger:hover {
+ color: #ffffff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ color: #ffffff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+.btn-danger:active:hover,
+.btn-danger.active:hover,
+.open > .dropdown-toggle.btn-danger:hover,
+.btn-danger:active:focus,
+.btn-danger.active:focus,
+.open > .dropdown-toggle.btn-danger:focus,
+.btn-danger:active.focus,
+.btn-danger.active.focus,
+.open > .dropdown-toggle.btn-danger.focus {
+ color: #ffffff;
+ background-color: #ac2925;
+ border-color: #761c19;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ background-image: none;
+}
+.btn-danger.disabled:hover,
+.btn-danger[disabled]:hover,
+fieldset[disabled] .btn-danger:hover,
+.btn-danger.disabled:focus,
+.btn-danger[disabled]:focus,
+fieldset[disabled] .btn-danger:focus,
+.btn-danger.disabled.focus,
+.btn-danger[disabled].focus,
+fieldset[disabled] .btn-danger.focus {
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+.btn-danger .badge {
+ color: #d9534f;
+ background-color: #ffffff;
+}
+.btn-link {
+ color: #337ab7;
+ font-weight: normal;
+ border-radius: 0;
+}
+.btn-link,
+.btn-link:active,
+.btn-link.active,
+.btn-link[disabled],
+fieldset[disabled] .btn-link {
+ background-color: transparent;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.btn-link,
+.btn-link:hover,
+.btn-link:focus,
+.btn-link:active {
+ border-color: transparent;
+}
+.btn-link:hover,
+.btn-link:focus {
+ color: #23527c;
+ text-decoration: underline;
+ background-color: transparent;
+}
+.btn-link[disabled]:hover,
+fieldset[disabled] .btn-link:hover,
+.btn-link[disabled]:focus,
+fieldset[disabled] .btn-link:focus {
+ color: #777777;
+ text-decoration: none;
+}
+.btn-lg {
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px;
+}
+.btn-sm {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+.btn-xs {
+ padding: 1px 5px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+.btn-block {
+ display: block;
+ width: 100%;
+}
+.btn-block + .btn-block {
+ margin-top: 5px;
+}
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+ width: 100%;
+}
+.clearfix:before,
+.clearfix:after {
+ content: " ";
+ display: table;
+}
+.clearfix:after {
+ clear: both;
+}
+.center-block {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+.pull-right {
+ float: right !important;
+}
+.pull-left {
+ float: left !important;
+}
+.hide {
+ display: none !important;
+}
+.show {
+ display: block !important;
+}
+.invisible {
+ visibility: hidden;
+}
+.text-hide {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
+.hidden {
+ display: none !important;
+}
+.affix {
+ position: fixed;
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+* {
+ -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
+}
+
+body {
+ -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
+ -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
+ -webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
+ background-color:#E4E4E4;
+ background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+ background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+ background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+ background-image:-webkit-gradient(
+ linear,
+ left top,
+ left bottom,
+ color-stop(0, #A7A7A7),
+ color-stop(0.51, #E4E4E4)
+ );
+ background-attachment:fixed;
+ font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
+ font-size:12px;
+ height:100%;
+ margin:0px;
+ padding:0px;
+ text-transform:uppercase;
+ width:100%;
+}
+
+/* Portrait layout (default) */
+.app {
+ background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
+ position:absolute; /* position in the center of the screen */
+ left:50%;
+ top:25%;
+ height:50px; /* text area height */
+ width:225px; /* text area width */
+ text-align:center;
+ padding:180px 0px 0px 0px; /* image height is 200px (bottom 20px are overlapped with text) */
+ margin:-115px 0px 0px -112px; /* offset vertical: half of image height and text area height */
+ /* offset horizontal: half of text area width */
+}
+
+/* Landscape layout (with min-width) */
+@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
+ .app {
+ background-position:left center;
+ padding:75px 0px 75px 170px; /* padding-top + padding-bottom + text area = image height */
+ margin:-90px 0px 0px -198px; /* offset vertical: half of image height */
+ /* offset horizontal: half of image width and text area width */
+ }
+}
+
+h1 {
+ font-size:24px;
+ font-weight:normal;
+ margin:0px;
+ overflow:visible;
+ padding:0px;
+ text-align:center;
+}
+
+.event {
+ border-radius:4px;
+ -webkit-border-radius:4px;
+ color:#FFFFFF;
+ font-size:12px;
+ margin:0px 30px;
+ padding:2px 0px;
+}
+
+.event.listening {
+ background-color:#333333;
+ display:block;
+}
+
+.event.received {
+ background-color:#4B946A;
+ display:none;
+}
+
+@keyframes fade {
+ from { opacity: 1.0; }
+ 50% { opacity: 0.4; }
+ to { opacity: 1.0; }
+}
+
+@-webkit-keyframes fade {
+ from { opacity: 1.0; }
+ 50% { opacity: 0.4; }
+ to { opacity: 1.0; }
+}
+
+.blink {
+ animation:fade 3000ms infinite;
+ -webkit-animation:fade 3000ms infinite;
+}
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8"/>
+ <meta name="format-detection" content="telephone=no"/>
+ <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=3, minimum-scale=1, width=device-width"/>
+ <link rel="stylesheet" type="text/css" href="css/index.css"/>
+ <link rel="stylesheet" type="text/css" href="css/bootstrap.css"/>
+ <script type="text/javascript" src="cordova.js"></script>
+ <script type="text/javascript" src="js/index.js"></script>
+ <script type="text/javascript">
+ document.addEventListener("deviceready", function() {
+ appintance = new app();
+ alert('deviceready');
+ console.log(navigator.camera);
+ }, true);
+</script>
+<title>Corodva QQ Plugin Exmaple</title>
+</head>
+<body>
+ <div class="app">
+ <div id="deviceready">
+ <button type="button" class="btn btn-primary btn-block" onclick="appintance.checkClientInstalled()">检查客户端是否安装</button>
+ <button type="button" class="btn btn-primary btn-block" onclick="appintance.ssoLogin()">QQ登录</button>
+ <button type="button" class="btn btn-primary btn-block" onclick="appintance.logout()">QQ登出</button>
+ <button type="button" class="btn btn-primary btn-block" onclick="appintance.shareText()">文本分享</button>
+ <button type="button" class="btn btn-primary btn-block" onclick="appintance.shareImage()">网络图片分享</button>
+ <button type="button" class="btn btn-primary btn-block" onclick="appintance.shareLocalImage()">拍照分享图片</button>
+ <button type="button" class="btn btn-primary btn-block" onclick="appintance.shareBase64Image()">Base64图片分享</button>
+ <button type="button" class="btn btn-primary btn-block" onclick="appintance.shareNews()">新闻分享</button>
+ <button type="button" class="btn btn-primary btn-block" onclick="appintance.shareAudio()">音乐分享</button>
+ </div>
+ </div>
+ </body>
+ </html>
--- /dev/null
+var app = function () {
+
+ this.checkClientInstalled = function () {
+ var args = {};
+ args.client = QQSDK.ClientType.QQ;//QQSDK.ClientType.QQ,QQSDK.ClientType.TIM;
+ QQSDK.checkClientInstalled(function () {
+ alert('client is installed');
+ }, function () {
+ // if installed QQ Client version is not supported sso,also will get this error
+ alert('client is not installed');
+ }, args);
+ };
+
+ this.ssoLogin = function () {
+ var args = {};
+ args.client = QQSDK.ClientType.QQ;//QQSDK.ClientType.QQ,QQSDK.ClientType.TIM;
+ QQSDK.ssoLogin(function (result) {
+ alert('token is ' + result.access_token);
+ alert('userid is ' + result.userid);
+ alert('expires_time is ' + new Date(parseInt(result.expires_time)) + ' TimeStamp is ' + result.expires_time);
+ }, function (failReason) {
+ alert(failReason);
+ }, args);
+ };
+
+ this.logout = function () {
+ QQSDK.logout(function () {
+ alert('logout success');
+ }, function (failReason) {
+ alert(failReason);
+ });
+ };
+
+ this.shareText = function () {
+ var args = {};
+ args.client = QQSDK.ClientType.QQ;//QQSDK.ClientType.QQ,QQSDK.ClientType.TIM;
+ args.scene = QQSDK.Scene.QQ;//QQSDK.Scene.QQZone,QQSDK.Scene.Favorite
+ args.text = '这个是 Cordova QQ 分享文字';
+ QQSDK.shareText(function () {
+ alert('shareText success');
+ }, function (failReason) {
+ alert(failReason);
+ }, args);
+ };
+
+ this.shareImage = function () {
+ var args = {};
+ args.client = QQSDK.ClientType.QQ;//QQSDK.ClientType.QQ,QQSDK.ClientType.TIM;
+ args.scene = QQSDK.Scene.QQ;//QQSDK.Scene.QQZone,QQSDK.Scene.Favorite
+ args.title = '这个是 Cordova QQ 图片分享的标题';
+ args.description = '这个是 Cordova QQ 图片分享的描述';
+ args.image = 'https://cordova.apache.org/static/img/cordova_bot.png';
+ QQSDK.shareImage(function () {
+ alert('shareImage success');
+ }, function (failReason) {
+ alert(failReason);
+ }, args);
+ };
+
+ this.shareBase64Image = function () {
+ var base64 = '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';
+ var args = {};
+ args.client = QQSDK.ClientType.QQ;//QQSDK.ClientType.QQ,QQSDK.ClientType.TIM;
+ args.scene = QQSDK.Scene.QQ;//QQSDK.Scene.QQZone,QQSDK.Scene.Favorite
+ args.title = '这个是 Cordova QQ 图片分享的标题';
+ args.description = '这个是 Cordova QQ 图片分享的描述';
+ args.image = base64;
+ QQSDK.shareImage(function () {
+ alert('shareImage success');
+ }, function (failReason) {
+ alert(failReason);
+ }, args);
+ };
+
+ this.shareLocalImage = function () {
+ var args = {};
+ args.client = QQSDK.ClientType.QQ;//QQSDK.ClientType.QQ,QQSDK.ClientType.TIM;
+ args.scene = QQSDK.Scene.QQ;//QQSDK.Scene.QQZone,QQSDK.Scene.Favorite
+ args.title = '这个是 Cordova QQ 图片分享的标题';
+ args.description = '这个是 Cordova QQ 图片分享的描述';
+ args.image = 'https://cordova.apache.org/static/img/cordova_bot.png';
+ navigator.camera.getPicture(function (pic) {
+ args.image = pic.split("://")[1];
+ console.log('pic is ', pic);
+ QQSDK.shareImage(function () {
+ alert('shareImage success');
+ }, function (failReason) {
+ alert(failReason);
+ }, args);
+ }, null, {targetWidth: 60, targetHeight: 60}
+ );
+ };
+
+ this.shareNews = function () {
+ var args = {};
+ args.client = QQSDK.ClientType.QQ;//QQSDK.ClientType.QQ,QQSDK.ClientType.TIM;
+ args.scene = QQSDK.Scene.QQ;//QQSDK.Scene.QQZone,QQSDK.Scene.Favorite
+ args.url = 'https://cordova.apache.org/';
+ args.title = '这个是 Cordova QQ 新闻分享的标题';
+ args.description = '这个是 Cordova QQ 新闻分享的描述';
+ args.image = 'https://cordova.apache.org/static/img/cordova_bot.png';
+ QQSDK.shareNews(function () {
+ alert('shareNews success');
+ }, function (failReason) {
+ alert(failReason);
+ }, args);
+ };
+
+ this.shareAudio = function () {
+ var args = {};
+ args.client = QQSDK.ClientType.QQ;//QQSDK.ClientType.QQ,QQSDK.ClientType.TIM;
+ args.scene = QQSDK.Scene.QQ;//QQSDK.Scene.QQZone,QQSDK.Scene.Favorite
+ args.url = 'https://y.qq.com/portal/song/001OyHbk2MSIi4.html';
+ args.title = '十年';
+ args.description = '陈奕迅';
+ args.image = 'https://y.gtimg.cn/music/photo_new/T001R300x300M000003Nz2So3XXYek.jpg';
+ args.flashUrl = 'http://stream20.qqmusic.qq.com/30577158.mp3';
+ QQSDK.shareAudio(function () {
+ alert('shareAudio success');
+ }, function (failReason) {
+ alert(failReason);
+ }, args);
+ };
+}
--- /dev/null
+{
+ "_from": "cordova-plugin-qqsdk",
+ "_id": "cordova-plugin-qqsdk@0.9.7",
+ "_inBundle": false,
+ "_integrity": "sha512-WpWbn4jenU3LC9FJJQxTxqpChw2/CWJWuKwGpFQgTuEdaWNAU5VQSoAnBtYX3zQZA8nIsXJ4J+GXlixxXswAcw==",
+ "_location": "/cordova-plugin-qqsdk",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "tag",
+ "registry": true,
+ "raw": "cordova-plugin-qqsdk",
+ "name": "cordova-plugin-qqsdk",
+ "escapedName": "cordova-plugin-qqsdk",
+ "rawSpec": "",
+ "saveSpec": null,
+ "fetchSpec": "latest"
+ },
+ "_requiredBy": [
+ "#USER",
+ "/"
+ ],
+ "_resolved": "https://registry.npmjs.org/cordova-plugin-qqsdk/-/cordova-plugin-qqsdk-0.9.7.tgz",
+ "_shasum": "ac38bc7480a7e0a1c5c4b6e8807ff1954979f9b7",
+ "_spec": "cordova-plugin-qqsdk",
+ "_where": "E:\\alipay\\mobile",
+ "author": {
+ "name": "https://github.com/iVanPan"
+ },
+ "bugs": {
+ "url": "https://github.com/iVanPan/Cordova_QQ/issues"
+ },
+ "bundleDependencies": false,
+ "cordova": {
+ "id": "cordova-plugin-qqsdk",
+ "platforms": [
+ "android",
+ "ios"
+ ]
+ },
+ "deprecated": false,
+ "description": "codrova/phonegap wrapper for qq sdk",
+ "engines": [
+ {
+ "name": "cordova-android",
+ "version": ">=7.0.0"
+ }
+ ],
+ "homepage": "https://github.com/iVanPan/Cordova_QQ",
+ "keywords": [
+ "ecosystem:cordova",
+ "cordova-android",
+ "cordova-ios",
+ "cordova",
+ "phonegap",
+ "plugin",
+ "qqsdk",
+ "qq",
+ "TIM",
+ "Tencent",
+ "login",
+ "share",
+ "favorites"
+ ],
+ "license": "MIT",
+ "main": "index.js",
+ "name": "cordova-plugin-qqsdk",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/iVanPan/Cordova_QQ.git"
+ },
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "version": "0.9.7"
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ id="cordova-plugin-qqsdk"
+ version="0.9.7">
+
+ <name>QQSDK</name>
+ <description>Cordova Plugin QQSDK</description>
+ <license>MIT</license>
+ <keywords>cordova,qq</keywords>
+ <repo>https://github.com/iVanPan/Cordova_QQ</repo>
+ <issue>https://github.com/iVanPan/Cordova_QQ/issues</issue>
+
+ <preference name="QQ_APP_ID" />
+
+ <!--require cordova version -->
+ <engines>
+ <engine name="cordova" version=">=4.0.0" />
+ <engine name="cordova-android" version=">=7.0.0" />
+ </engines>
+
+ <!-- js module-->
+ <js-module src="www/qq.js" name="QQSDK">
+ <clobbers target="QQSDK" />
+ </js-module>
+
+ <!-- ios -->
+ <platform name="ios">
+ <config-file target="config.xml" parent="/*">
+ <feature name="QQSDK">
+ <param name="ios-package" value="CDVQQSDK"/>
+ </feature>
+ <preference name="QQ_APP_ID" value="$QQ_APP_ID" />
+ </config-file>
+
+ <!--set ios URLTypes for QQ SDK -->
+ <config-file target="*-Info.plist" parent="CFBundleURLTypes">
+ <array>
+ <dict>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>CFBundleURLName</key>
+ <string>tencentopenapi</string>
+ <key>CFBundleURLSchemes</key>
+ <array>
+ <string>tencent$QQ_APP_ID</string>
+ </array>
+ </dict>
+ </array>
+ </config-file>
+
+ <!--scheme query whitlist-->
+ <config-file platform="ios" target="*-Info.plist" parent="LSApplicationQueriesSchemes">
+ <array>
+ <string>mqqapi</string>
+ <string>mqq</string>
+ <string>mqqOpensdkSSoLogin</string>
+ <string>mqqconnect</string>
+ <string>mqqopensdkdataline</string>
+ <string>mqqopensdkgrouptribeshare</string>
+ <string>mqqopensdkfriend</string>
+ <string>mqqopensdkapi</string>
+ <string>mqqopensdkapiV2</string>
+ <string>mqqopensdkapiV3</string>
+ <string>mqqopensdkapiV4</string>
+ <string>mqzoneopensdk</string>
+ <string>wtloginmqq</string>
+ <string>wtloginmqq2</string>
+ <string>mqqwpa</string>
+ <string>mqzone</string>
+ <string>mqzonev2</string>
+ <string>mqzoneshare</string>
+ <string>wtloginqzone</string>
+ <string>mqzonewx</string>
+ <string>mqzoneopensdkapiV2</string>
+ <string>mqzoneopensdkapi19</string>
+ <string>mqzoneopensdkapi</string>
+ <string>mqzoneopensdk</string>
+ <string>mqqgamebindinggroup</string>
+ <string>tencentapi.qq.reqContent</string>
+ <string>tencentapi.qzone.reqContent</string>
+ <string>tim</string>
+ <string>timapi</string>
+ <string>timopensdkfriend</string>
+ <string>timwpa</string>
+ <string>timgamebindinggroup</string>
+ <string>timapiwallet</string>
+ <string>timOpensdkSSoLogin</string>
+ <string>wtlogintim</string>
+ <string>timopensdkgrouptribeshare</string>
+ <string>timopensdkapiV4</string>
+ <string>timgamebindinggroup</string>
+ <string>timopensdkdataline</string>
+ <string>wtlogintimV1</string>
+ <string>timapiV1</string>
+ </array>
+ </config-file>
+ <header-file src="src/ios/CDVQQSDK.h"/>
+ <source-file src="src/ios/CDVQQSDK.m"/>
+ <!--required frameworks for qq sdk-->
+ <framework src="CoreGraphics.framework" />
+ <framework src="CoreTelephony.framework" />
+ <framework src="SystemConfiguration.framework" />
+ <framework src="Security.framework" />
+ <framework src="libiconv.tbd" />
+ <framework src="libsqlite3.tbd" />
+ <framework src="libstdc++.tbd" />
+ <framework src="libz.tbd" />
+ <!--QQ SDK version 3.2.3-->
+ <framework src="src/ios/TencentOpenAPI.framework" custom="true" framework="true"/>
+ <resource-file src="src/ios/TencentOpenApi_IOS_Bundle.bundle" />
+
+ <info>
+ 1.安装完这个插件,请用 Xcode 打开工程,查看 URL Types 里面 QQ 的 URL Type 有没有,如果没有请手动添加。
+ 1.after installing this plugin,check the URL Types in your Xcode project.If you don't find URL Types for QQ SDK,manually add it.
+ </info>
+ </platform>
+
+ <!-- android -->
+ <platform name="android">
+ <config-file target="res/xml/config.xml" parent="/*">
+ <feature name="QQSDK" >
+ <param name="android-package" value="me.vanpan.qqsdk.QQSDKPlugin"/>
+ </feature>
+ <!--whitelist for QQ SDK-->
+ <access origin = "https://openmobile.qq.com/*"/>
+ <access origin = "http://qzonestyle.gtimg.cn/*"/>
+ <access origin = "http://pub.idqqimg.com/*"/>
+ <access origin = "http://qzs.qq.com/*"/>
+ <access origin = "http://m.qzone.com/*"/>
+ <access origin = "http://*.ptlogin2.qq.com/*"/>
+ <access origin = "http://*.qq.com/*"/>
+ <access origin = "http://q2.qlogo.cn/*" />
+
+ <preference name="QQ_APP_ID" value="$QQ_APP_ID" />
+ </config-file>
+ <!--permission for QQ SDK -->
+ <config-file target="app/src/main/AndroidManifest.xml" parent="/manifest">
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ </config-file>
+ <!--QQ webview Auth Activity -->
+ <config-file target="app/src/main/AndroidManifest.xml" parent="/manifest/application">
+ <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_APP_ID"/>
+ </intent-filter>
+ </activity>
+ <activity
+ android:name="com.tencent.connect.common.AssistActivity"
+ android:configChanges="orientation|keyboardHidden"
+ android:screenOrientation="portrait"
+ android:theme="@android:style/Theme.Translucent.NoTitleBar" >
+ </activity>
+ </config-file>
+ <source-file src="src/android/QQSDKPlugin.java" target-dir="src/me/vanpan/qqsdk" />
+ <!--QQ SDK version 3.2.1-->
+ <source-file src="src/android/open_sdk_r5793.jar" target-dir="app/libs/" />
+ <source-file src="src/android/mta-sdk-1.6.2.jar" target-dir="app/libs/" />
+ <framework src="com.android.support:support-v4:24.1.1+" />
+ </platform>
+</plugin>
--- /dev/null
+package me.vanpan.qqsdk;
+
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Base64;
+import android.util.Log;
+import android.webkit.URLUtil;
+import com.tencent.connect.common.Constants;
+import com.tencent.connect.share.QQShare;
+import com.tencent.connect.share.QzonePublish;
+import com.tencent.connect.share.QzoneShare;
+import com.tencent.open.GameAppOperation;
+import com.tencent.tauth.IUiListener;
+import com.tencent.tauth.Tencent;
+import com.tencent.tauth.UiError;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import org.apache.cordova.CallbackContext;
+import org.apache.cordova.CordovaArgs;
+import org.apache.cordova.CordovaPlugin;
+import org.apache.cordova.PluginResult;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import static org.apache.cordova.CordovaActivity.TAG;
+
+/**
+ * Project: QQSDKPlugin
+ * Created by Van on 2016/12/16.
+ */
+
+class ShareScene {
+ public static final int QQ = 0;
+ public static final int QQZone = 1;
+ public static final int Favorite = 2;
+}
+
+public class QQSDKPlugin extends CordovaPlugin {
+ private static Tencent mTencent;
+ private CallbackContext currentCallbackContext;
+ private String APP_ID;
+ private static final String QQ_APP_ID = "qq_app_id";
+ private static final String QQ_CANCEL_BY_USER = "cancelled by user";
+ private static final String QQ_RESPONSE_ERROR = "QQ response is error";
+ private static final String QZONE_SHARE_CANCEL = "QZone share is cancelled";
+ private static final String QQFAVORITES_CANCEL = "QQ Favorites is cancelled";
+ private static final String QQ_Client_NOT_INSYALLED_ERROR = "QQ client is not installed";
+ private static final String QQ_PARAM_ERROR = "param incorrect";
+
+ @Override protected void pluginInitialize() {
+ super.pluginInitialize();
+ APP_ID = webView.getPreferences().getString(QQ_APP_ID, "");
+ mTencent = Tencent.createInstance(APP_ID, this.cordova.getActivity().getApplicationContext());
+ }
+
+ @Override
+ public boolean execute(String action, final CordovaArgs args, final CallbackContext callbackContext)
+ throws JSONException {
+ if (action.equalsIgnoreCase("checkClientInstalled")) {
+ return checkClientInstalled(callbackContext);
+ }
+ if (action.equals("ssoLogin")) {
+ return ssoLogin(callbackContext);
+ }
+ if (action.equals("logout")) {
+ return logout(callbackContext);
+ }
+ if (action.equals("shareText")) {
+ return shareText(args,callbackContext);
+ }
+ if (action.equals("shareImage")) {
+ return shareImage(args,callbackContext);
+ }
+ if (action.equals("shareNews")) {
+ return shareNews(args,callbackContext);
+ }
+ if (action.equals("shareAudio")) {
+ return shareAudio(args,callbackContext);
+ }
+ return super.execute(action, args, callbackContext);
+ }
+
+ /**
+ * 检查手机QQ客户端是否安装
+ */
+ private boolean checkClientInstalled(CallbackContext callbackContext) {
+ Boolean installed = mTencent.isSupportSSOLogin(QQSDKPlugin.this.cordova.getActivity());
+ if (installed) {
+ callbackContext.success();
+ } else {
+ callbackContext.error(QQ_Client_NOT_INSYALLED_ERROR);
+ }
+ return true;
+ }
+
+ /**
+ * QQ 单点登录
+ */
+ private boolean ssoLogin(CallbackContext callbackContext) {
+ currentCallbackContext = callbackContext;
+ Runnable runnable = new Runnable() {
+ @Override public void run() {
+ mTencent.login(QQSDKPlugin.this.cordova.getActivity(), "all", loginListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(runnable);
+ this.cordova.setActivityResultCallback(this);
+ return true;
+ }
+
+ /**
+ * QQ 登出
+ */
+ private boolean logout(CallbackContext callbackContext) {
+ mTencent.logout(this.cordova.getActivity());
+ callbackContext.success();
+ return true;
+ }
+
+ public boolean shareText(CordovaArgs args, CallbackContext callbackContext) {
+ final Bundle params = new Bundle();
+ currentCallbackContext = callbackContext;
+ final JSONObject data;
+ try {
+ data = args.getJSONObject(0);
+ String text = data.has("text")? data.getString("text"): "";
+ int shareScene = data.has("scene")? data.getInt("scene"): 0;
+ switch (shareScene) {
+ case ShareScene.QQ:
+ callbackContext.error("Android 不支持分享文字到 QQ");
+ break;
+ case ShareScene.Favorite:
+ params.putInt(GameAppOperation.QQFAV_DATALINE_REQTYPE,
+ GameAppOperation.QQFAV_DATALINE_TYPE_TEXT);
+ params.putString(GameAppOperation.QQFAV_DATALINE_TITLE, getAppName());
+ params.putString(GameAppOperation.QQFAV_DATALINE_DESCRIPTION, text);
+ params.putString(GameAppOperation.QQFAV_DATALINE_APPNAME, getAppName());
+ Runnable favoritesRunnable = new Runnable() {
+ @Override public void run() {
+ mTencent.addToQQFavorites(QQSDKPlugin.this.cordova.getActivity(), params,
+ addToQQFavoritesListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(favoritesRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ case ShareScene.QQZone:
+ params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE,
+ QzonePublish.PUBLISH_TO_QZONE_TYPE_PUBLISHMOOD);
+ params.putString(QzoneShare.SHARE_TO_QQ_TITLE, text);
+ Runnable zoneRunnable = new Runnable() {
+
+ @Override public void run() {
+ mTencent.publishToQzone(QQSDKPlugin.this.cordova.getActivity(), params,
+ qZoneShareListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(zoneRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ default:
+ break;
+ }
+ } catch (JSONException e) {
+ callbackContext.error(QQ_PARAM_ERROR);
+ return true;
+ }
+ return true;
+ }
+
+ public boolean shareImage(CordovaArgs args, CallbackContext callbackContext) {
+ currentCallbackContext = callbackContext;
+ final JSONObject data;
+ try {
+ data = args.getJSONObject(0);
+ String title = data.has("title")? data.getString("title"): "";
+ String description = data.has("description")? data.getString("description"): "";
+ String image = data.has("image")? data.getString("image"): "";
+ int shareScene = data.has("scene")? data.getInt("scene"): 0;
+ image = processImage(image);
+ final Bundle params = new Bundle();
+ switch (shareScene) {
+ case ShareScene.QQ:
+ params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_IMAGE);
+ params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, image);
+ params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
+ params.putString(QQShare.SHARE_TO_QQ_SUMMARY, description);
+ Runnable qqRunnable = new Runnable() {
+
+ @Override public void run() {
+ mTencent.shareToQQ(QQSDKPlugin.this.cordova.getActivity(), params, qqShareListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(qqRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ case ShareScene.Favorite:
+ ArrayList<String> imageUrls = new ArrayList<String>();
+ imageUrls.add(image);
+ params.putInt(GameAppOperation.QQFAV_DATALINE_REQTYPE,
+ GameAppOperation.QQFAV_DATALINE_TYPE_IMAGE_TEXT);
+ params.putString(GameAppOperation.QQFAV_DATALINE_TITLE, title);
+ params.putString(GameAppOperation.QQFAV_DATALINE_DESCRIPTION, description);
+ params.putString(GameAppOperation.QQFAV_DATALINE_IMAGEURL, image);
+ params.putString(GameAppOperation.QQFAV_DATALINE_APPNAME, getAppName());
+ params.putStringArrayList(GameAppOperation.QQFAV_DATALINE_FILEDATA, imageUrls);
+ Runnable favoritesRunnable = new Runnable() {
+ @Override public void run() {
+ mTencent.addToQQFavorites(QQSDKPlugin.this.cordova.getActivity(), params,
+ addToQQFavoritesListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(favoritesRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ case ShareScene.QQZone:
+ params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_IMAGE);
+ params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, image);
+ params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
+ params.putString(QQShare.SHARE_TO_QQ_SUMMARY, description);
+ params.putInt(QQShare.SHARE_TO_QQ_EXT_INT, QQShare.SHARE_TO_QQ_FLAG_QZONE_AUTO_OPEN);
+ Runnable zoneRunnable = new Runnable() {
+
+ @Override public void run() {
+ mTencent.shareToQQ(QQSDKPlugin.this.cordova.getActivity(), params, qqShareListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(zoneRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ default:
+ break;
+ }
+ } catch (JSONException e) {
+ callbackContext.error(QQ_PARAM_ERROR);
+ return true;
+ }
+ return true;
+ }
+
+ public boolean shareNews(CordovaArgs args, CallbackContext callbackContext) {
+ currentCallbackContext = callbackContext;
+ final JSONObject data;
+ try {
+ data = args.getJSONObject(0);
+ String title = data.has("title")? data.getString("title"): "";
+ String description = data.has("description")? data.getString("description"): "";
+ String image = data.has("image")? data.getString("image"): "";
+ String url = data.has("url")? data.getString("url"): "";
+ int shareScene = data.has("scene")? data.getInt("scene"): 0;
+ final Bundle params = new Bundle();
+ switch (shareScene) {
+ case ShareScene.QQ:
+ params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT);
+ if(URLUtil.isHttpUrl(image) || URLUtil.isHttpsUrl(image)) {
+ params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL,image);
+ } else {
+ params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL,processImage(image));
+ }
+ params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
+ params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, url);
+ params.putString(QQShare.SHARE_TO_QQ_SUMMARY, description);
+ Runnable qqRunnable = new Runnable() {
+
+ @Override public void run() {
+ mTencent.shareToQQ(QQSDKPlugin.this.cordova.getActivity(), params, qqShareListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(qqRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ case ShareScene.Favorite:
+ image = processImage(image);
+ params.putInt(GameAppOperation.QQFAV_DATALINE_REQTYPE,
+ GameAppOperation.QQFAV_DATALINE_TYPE_DEFAULT);
+ params.putString(GameAppOperation.QQFAV_DATALINE_TITLE, title);
+ params.putString(GameAppOperation.QQFAV_DATALINE_DESCRIPTION, description);
+ params.putString(GameAppOperation.QQFAV_DATALINE_IMAGEURL, image);
+ params.putString(GameAppOperation.QQFAV_DATALINE_URL, url);
+ params.putString(GameAppOperation.QQFAV_DATALINE_APPNAME, getAppName());
+ Runnable favoritesRunnable = new Runnable() {
+ @Override public void run() {
+ mTencent.addToQQFavorites(QQSDKPlugin.this.cordova.getActivity(), params,
+ addToQQFavoritesListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(favoritesRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ case ShareScene.QQZone:
+ image = processImage(image);
+ ArrayList<String> imageUrls = new ArrayList<String>();
+ imageUrls.add(image);
+ params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE,
+ QzoneShare.SHARE_TO_QZONE_TYPE_IMAGE_TEXT);
+ params.putString(QzoneShare.SHARE_TO_QQ_TITLE, title);
+ params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, description);
+ params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL, url);
+ params.putStringArrayList(QzoneShare.SHARE_TO_QQ_IMAGE_URL, imageUrls);
+ Runnable zoneRunnable = new Runnable() {
+
+ @Override public void run() {
+ mTencent.shareToQzone(QQSDKPlugin.this.cordova.getActivity(), params,
+ qZoneShareListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(zoneRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ default:
+ break;
+ }
+ } catch (JSONException e) {
+ callbackContext.error(QQ_PARAM_ERROR);
+ return true;
+ }
+ return true;
+ }
+
+ public boolean shareAudio(CordovaArgs args, CallbackContext callbackContext) {
+ currentCallbackContext = callbackContext;
+ final JSONObject data;
+ try {
+ data = args.getJSONObject(0);
+ String title = data.has("title")? data.getString("title"): "";
+ String description = data.has("description")? data.getString("description"): "";
+ String image = data.has("image")? data.getString("image"): "";
+ String url = data.has("url")? data.getString("url"): "";
+ String flashUrl = data.has("flashUrl")? data.getString("flashUrl"): "";
+ int shareScene = data.has("scene")? data.getInt("scene"): 0;
+ final Bundle params = new Bundle();
+ switch (shareScene) {
+ case ShareScene.QQ:
+ params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT);
+ if(URLUtil.isHttpUrl(image) || URLUtil.isHttpsUrl(image)) {
+ params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL,image);
+ } else {
+ params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL,processImage(image));
+ }
+ params.putString(QQShare.SHARE_TO_QQ_AUDIO_URL, flashUrl);
+ params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
+ params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, url);
+ params.putString(QQShare.SHARE_TO_QQ_SUMMARY, description);
+ Runnable qqRunnable = new Runnable() {
+
+ @Override public void run() {
+ mTencent.shareToQQ(QQSDKPlugin.this.cordova.getActivity(), params, qqShareListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(qqRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ case ShareScene.Favorite:
+ image = processImage(image);
+ params.putInt(GameAppOperation.QQFAV_DATALINE_REQTYPE,
+ GameAppOperation.QQFAV_DATALINE_TYPE_DEFAULT);
+ params.putString(GameAppOperation.QQFAV_DATALINE_TITLE, title);
+ params.putString(GameAppOperation.QQFAV_DATALINE_DESCRIPTION, description);
+ params.putString(GameAppOperation.QQFAV_DATALINE_IMAGEURL, image);
+ params.putString(GameAppOperation.QQFAV_DATALINE_URL, url);
+ params.putString(GameAppOperation.QQFAV_DATALINE_APPNAME, getAppName());
+ params.putString(GameAppOperation.QQFAV_DATALINE_AUDIOURL, flashUrl);
+ Runnable favoritesRunnable = new Runnable() {
+ @Override public void run() {
+ mTencent.addToQQFavorites(QQSDKPlugin.this.cordova.getActivity(), params,
+ addToQQFavoritesListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(favoritesRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ case ShareScene.QQZone:
+ image = processImage(image);
+ ArrayList<String> imageUrls = new ArrayList<String>();
+ imageUrls.add(image);
+ params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE,
+ QzoneShare.SHARE_TO_QZONE_TYPE_IMAGE_TEXT);
+ params.putString(QzoneShare.SHARE_TO_QQ_TITLE, title);
+ params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, description);
+ params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL, url);
+ params.putString(QzoneShare.SHARE_TO_QQ_AUDIO_URL, flashUrl);
+ params.putStringArrayList(QzoneShare.SHARE_TO_QQ_IMAGE_URL, imageUrls);
+ Runnable zoneRunnable = new Runnable() {
+
+ @Override public void run() {
+ mTencent.shareToQzone(QQSDKPlugin.this.cordova.getActivity(), params,
+ qZoneShareListener);
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(zoneRunnable);
+ this.cordova.setActivityResultCallback(this);
+ break;
+ default:
+ break;
+ }
+ } catch (JSONException e) {
+ callbackContext.error(QQ_PARAM_ERROR);
+ return true;
+ }
+ return true;
+ }
+
+ /**
+ * 保存token 和 openid
+ */
+ public static void initOpenidAndToken(JSONObject jsonObject) {
+ try {
+ String token = jsonObject.getString(Constants.PARAM_ACCESS_TOKEN);
+ String expires = jsonObject.getString(Constants.PARAM_EXPIRES_IN);
+ String openId = jsonObject.getString(Constants.PARAM_OPEN_ID);
+ if (!TextUtils.isEmpty(token) && !TextUtils.isEmpty(expires) && !TextUtils.isEmpty(openId)) {
+ mTencent.setAccessToken(token, expires);
+ mTencent.setOpenId(openId);
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ /**
+ * 获取应用的名称
+ */
+ private String getAppName() {
+ PackageManager packageManager = this.cordova.getActivity().getPackageManager();
+ ApplicationInfo applicationInfo = null;
+ try {
+ applicationInfo =
+ packageManager.getApplicationInfo(this.cordova.getActivity().getPackageName(), 0);
+ } catch (final PackageManager.NameNotFoundException e) {
+ }
+ final String AppName =
+ (String) ((applicationInfo != null) ? packageManager.getApplicationLabel(applicationInfo)
+ : "AppName");
+ return AppName;
+ }
+
+ /**
+ * 处理图片
+ * @param image
+ * @return
+ */
+ private String processImage(String image) {
+ if(URLUtil.isHttpUrl(image) || URLUtil.isHttpsUrl(image)) {
+ return saveBitmapToFile(getBitmapFromURL(image));
+ } else if (isBase64(image)) {
+ return saveBitmapToFile(decodeBase64ToBitmap(image));
+ } else if (image.startsWith("/") ){
+ File file = new File(image);
+ return file.getAbsolutePath();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * 检查图片字符串是不是Base64
+ * @param image
+ * @return
+ */
+ private boolean isBase64(String image) {
+ try {
+ byte[] decodedString = Base64.decode(image, Base64.DEFAULT);
+ Bitmap bitmap = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
+ if (bitmap == null) {
+ return false;
+ }
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+
+ public static Bitmap getBitmapFromURL(String src) {
+ try {
+ URL url = new URL(src);
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setDoInput(true);
+ connection.connect();
+ InputStream input = connection.getInputStream();
+ Bitmap bitmap = BitmapFactory.decodeStream(input);
+ return bitmap;
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ /**
+ * 将Base64解码成Bitmap
+ */
+
+ private Bitmap decodeBase64ToBitmap(String Base64String) {
+ byte[] decode = Base64.decode(Base64String, Base64.DEFAULT);
+ Bitmap bitmap = BitmapFactory.decodeByteArray(decode, 0, decode.length);
+ return bitmap;
+ }
+
+ /**
+ * 将bitmap 保存成文件
+ */
+ private String saveBitmapToFile(Bitmap bitmap) {
+ File pictureFile = getOutputMediaFile();
+ if (pictureFile == null) {
+ return null;
+ }
+ try {
+ FileOutputStream fos = new FileOutputStream(pictureFile);
+ bitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
+ fos.close();
+ } catch (FileNotFoundException e) {
+ Log.d(TAG, "File not found: " + e.getMessage());
+ } catch (IOException e) {
+ Log.d(TAG, "Error accessing file: " + e.getMessage());
+ }
+ return pictureFile.getAbsolutePath();
+ }
+
+ /**
+ * 生成文件用来存储图片
+ */
+ private File getOutputMediaFile() {
+ File mediaStorageDir = this.cordova.getActivity().getExternalCacheDir();
+ if (!mediaStorageDir.exists()) {
+ if (!mediaStorageDir.mkdirs()) {
+ return null;
+ }
+ }
+ String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date());
+ File mediaFile;
+ String mImageName = "Cordova_" + timeStamp + ".jpg";
+ mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
+ return mediaFile;
+ }
+
+ /**
+ * 登录监听
+ */
+ IUiListener loginListener = new IUiListener() {
+ @Override public void onComplete(Object response) {
+ if (null == response) {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, QQ_RESPONSE_ERROR),
+ currentCallbackContext.getCallbackId());
+ return;
+ }
+ JSONObject jsonResponse = (JSONObject) response;
+ if (null != jsonResponse && jsonResponse.length() == 0) {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, QQ_RESPONSE_ERROR),
+ currentCallbackContext.getCallbackId());
+ return;
+ }
+ initOpenidAndToken(jsonResponse);
+ JSONObject jo =
+ makeJson(mTencent.getAccessToken(), mTencent.getOpenId(), mTencent.getExpiresIn());
+ QQSDKPlugin.this.webView.sendPluginResult(new PluginResult(PluginResult.Status.OK, jo),
+ currentCallbackContext.getCallbackId());
+ }
+
+ @Override public void onError(UiError e) {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, e.errorMessage),
+ currentCallbackContext.getCallbackId());
+ }
+
+ @Override public void onCancel() {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, QQ_CANCEL_BY_USER),
+ currentCallbackContext.getCallbackId());
+ }
+ };
+ /**
+ * QQ分享监听
+ */
+ IUiListener qqShareListener = new IUiListener() {
+ @Override public void onCancel() {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, QQ_CANCEL_BY_USER),
+ currentCallbackContext.getCallbackId());
+ }
+
+ @Override public void onComplete(Object response) {
+ QQSDKPlugin.this.webView.sendPluginResult(new PluginResult(PluginResult.Status.OK),
+ currentCallbackContext.getCallbackId());
+ }
+
+ @Override public void onError(UiError e) {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, e.errorMessage),
+ currentCallbackContext.getCallbackId());
+ }
+ };
+ /**
+ * QQZONE 分享监听
+ */
+ IUiListener qZoneShareListener = new IUiListener() {
+
+ @Override public void onCancel() {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, QZONE_SHARE_CANCEL),
+ currentCallbackContext.getCallbackId());
+ }
+
+ @Override public void onError(UiError e) {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, e.errorMessage),
+ currentCallbackContext.getCallbackId());
+ }
+
+ @Override public void onComplete(Object response) {
+ QQSDKPlugin.this.webView.sendPluginResult(new PluginResult(PluginResult.Status.OK),
+ currentCallbackContext.getCallbackId());
+ }
+ };
+ /**
+ * 添加到QQ收藏监听
+ */
+ IUiListener addToQQFavoritesListener = new IUiListener() {
+ @Override public void onCancel() {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, QQFAVORITES_CANCEL),
+ currentCallbackContext.getCallbackId());
+ }
+
+ @Override public void onComplete(Object response) {
+ QQSDKPlugin.this.webView.sendPluginResult(new PluginResult(PluginResult.Status.OK),
+ currentCallbackContext.getCallbackId());
+ }
+
+ @Override public void onError(UiError e) {
+ QQSDKPlugin.this.webView.sendPluginResult(
+ new PluginResult(PluginResult.Status.ERROR, e.errorMessage),
+ currentCallbackContext.getCallbackId());
+ }
+ };
+
+ /**
+ * 组装JSON
+ */
+ private JSONObject makeJson(String access_token, String userid, long expires_time) {
+ String json = "{\"access_token\": \"" + access_token + "\", " +
+ " \"userid\": \"" + userid + "\", " +
+ " \"expires_time\": \"" + String.valueOf(expires_time) + "\"" +
+ "}";
+ JSONObject jo = null;
+ try {
+ jo = new JSONObject(json);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ return jo;
+ }
+
+ @Override public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+ if (resultCode == Constants.ACTIVITY_OK) {
+ if (requestCode == Constants.REQUEST_LOGIN) {
+ Tencent.onActivityResultData(requestCode, resultCode, intent, loginListener);
+ }
+ if (requestCode == Constants.REQUEST_QQ_SHARE) {
+ Tencent.onActivityResultData(requestCode, resultCode, intent, qqShareListener);
+ }
+ if (requestCode == Constants.REQUEST_QQ_FAVORITES) {
+ Tencent.onActivityResultData(requestCode, resultCode, intent, addToQQFavoritesListener);
+ }
+ }
+ super.onActivityResult(requestCode, resultCode, intent);
+ }
+
+ @Override public void onDestroy() {
+ super.onDestroy();
+ if (mTencent != null) {
+ mTencent.releaseResource();
+ }
+ }
+}
--- /dev/null
+//
+// CDVQQSDK.h
+// QQ
+//
+// Created by Van on 2016/12/16.
+//
+//
+#import <Cordova/CDVPlugin.h>
+#import <Cordova/CDVPluginResult.h>
+#import <TencentOpenAPI/TencentOAuth.h>
+#import <TencentOpenAPI/QQApiInterface.h>
+
+typedef NS_ENUM(NSInteger, QQShareScene) {
+ QQ,
+ QQZone,
+ Favorite,
+};
+
+typedef NS_ENUM(NSInteger, QQShareType) {
+ TextMessage,
+ ImageMesssage,
+ NewsMessageWithNetworkImage,
+ NewsMessageWithLocalImage,
+ AudioMessage,
+ VideoMessage,
+};
+
+@interface CDVQQSDK : CDVPlugin <TencentSessionDelegate, QQApiInterfaceDelegate>
+
+@property (nonatomic, copy) NSString *callback;
+
+- (void)checkClientInstalled:(CDVInvokedUrlCommand *)command;
+
+- (void)ssoLogin:(CDVInvokedUrlCommand *)command;
+
+- (void)logout:(CDVInvokedUrlCommand *)command;
+
+- (void)shareText:(CDVInvokedUrlCommand *)command;
+
+- (void)shareImage:(CDVInvokedUrlCommand *)command;
+
+- (void)shareNews:(CDVInvokedUrlCommand *)command;
+
+//- (void)shareAudio:(NSString *)previewUrl flashUrl:(NSString *)flashUrl
+// image:(NSString *)image
+// withTitle:(NSString *)title
+// description:(NSString *)description
+// shareScene:(QQShareScene)scene
+// command:(CDVInvokedUrlCommand
+// *)command;
+
+@end
--- /dev/null
+//
+// CDVQQSDK.m
+// QQ
+//
+// Created by Van on 2016/12/16.
+//
+//
+
+#import "CDVQQSDK.h"
+
+NSString *QQ_NOT_INSTALLED = @"QQ Client is not installed";
+NSString *QQ_PARAM_NOT_FOUND = @"param is not found";
+NSString *QQ_IMAGE_PARAM_INCORRECT = @"image param is incorrect";
+NSString *QQ_LOGIN_ERROR = @"QQ login error";
+NSString *QQ_LOGIN_CANCEL = @"QQ login cancelled";
+NSString *QQ_LOGIN_NETWORK_ERROR = @"QQ login network error";
+NSString *QQ_SHARE_CANCEL = @"QQ share cancelled by user";
+NSString *appId = @"";
+
+@implementation CDVQQSDK {
+ TencentOAuth *tencentOAuth;
+}
+/**
+ * 插件初始化,主要用户appkey注册
+ */
+- (void)pluginInitialize {
+ appId = [[self.commandDelegate settings] objectForKey:@"qq_app_id"];
+ if (nil == tencentOAuth) {
+ tencentOAuth = [[TencentOAuth alloc] initWithAppId:appId andDelegate:self];
+ }
+}
+/**
+ * 处理URL
+ *
+ * @param notification cordova 传递进来的消息
+ */
+- (void)handleOpenURL:(NSNotification *)notification {
+ NSURL *url = [notification object];
+ NSString *schemaPrefix = [@"tencent" stringByAppendingString:appId];
+ if ([url isKindOfClass:[NSURL class]] && [[url absoluteString] hasPrefix:[schemaPrefix stringByAppendingString:@"://response_from_qq"]]) {
+ [QQApiInterface handleOpenURL:url delegate:self];
+ } else {
+ [TencentOAuth HandleOpenURL:url];
+ }
+}
+
+/**
+ * 检查QQ官方客户端是否安装
+ *
+ * @param command CDVInvokedUrlCommand
+ */
+- (void)checkClientInstalled:(CDVInvokedUrlCommand *)command {
+ NSDictionary *args = [command.arguments objectAtIndex:0];
+ int type = [[args valueForKey:@"client"] intValue];
+ if(type == 0) {
+ [tencentOAuth setAuthShareType:AuthShareType_QQ];
+ [self checkQQInstalled:command];
+ } else if (type == 1) {
+ [self checkTIMInstalled:command];
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+/**
+ * 检查QQ官方客户端是否安装
+ *
+ * @param command CDVInvokedUrlCommand
+ */
+- (void)checkQQInstalled:(CDVInvokedUrlCommand *)command {
+ if ([TencentOAuth iphoneQQInstalled] && [TencentOAuth iphoneQQSupportSSOLogin]) {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+
+/**
+ * 检查TIM客户端是否安装
+ *
+ * @param command CDVInvokedUrlCommand
+ */
+- (void)checkTIMInstalled:(CDVInvokedUrlCommand *)command {
+ if ([TencentOAuth iphoneTIMInstalled] && [TencentOAuth iphoneTIMSupportSSOLogin]) {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+/**
+ * QQ 登出
+ *
+ * @param command CDVInvokedUrlCommand
+ */
+- (void)logout:(CDVInvokedUrlCommand *)command {
+ self.callback = command.callbackId;
+ [tencentOAuth logout:self];
+}
+
+/**
+ * QQ 登录
+ *
+ * @param command CDVInvokedUrlCommand
+ */
+- (void)ssoLogin:(CDVInvokedUrlCommand *)command {
+ if (nil == tencentOAuth) {
+ tencentOAuth = [[TencentOAuth alloc] initWithAppId:appId andDelegate:self];
+ }
+ NSDictionary *args = [command.arguments objectAtIndex:0];
+ self.callback = command.callbackId;
+ NSArray *permissions = [NSArray arrayWithObjects:
+ kOPEN_PERMISSION_GET_USER_INFO,
+ kOPEN_PERMISSION_GET_SIMPLE_USER_INFO,
+ kOPEN_PERMISSION_ADD_ALBUM,
+ kOPEN_PERMISSION_ADD_ONE_BLOG,
+ kOPEN_PERMISSION_ADD_SHARE,
+ kOPEN_PERMISSION_ADD_TOPIC,
+ kOPEN_PERMISSION_CHECK_PAGE_FANS,
+ kOPEN_PERMISSION_GET_INFO,
+ kOPEN_PERMISSION_GET_OTHER_INFO,
+ kOPEN_PERMISSION_LIST_ALBUM,
+ kOPEN_PERMISSION_UPLOAD_PIC,
+ kOPEN_PERMISSION_GET_VIP_INFO,
+ kOPEN_PERMISSION_GET_VIP_RICH_INFO,
+ nil];
+ int type = [[args valueForKey:@"client"] intValue];
+ if (type == 0) {
+ [tencentOAuth setAuthShareType:AuthShareType_QQ];
+ } else if (type == 1) {
+ [tencentOAuth setAuthShareType:AuthShareType_TIM];
+ }
+ [tencentOAuth authorize:permissions];
+
+}
+
+/**
+ 分享文本
+
+ @param command cordova参数
+ */
+- (void)shareText:(CDVInvokedUrlCommand *)command {
+ self.callback = command.callbackId;
+ NSDictionary *args = [command.arguments objectAtIndex:0];
+ if ([args objectForKey:@"text"]) {
+ NSString *text = [args objectForKey:@"text"];
+ int scene = [[args valueForKey:@"scene"] intValue];
+ int type = [[args valueForKey:@"client"] intValue];
+ [self shareObjectWithData:@{ @"text" : text } Type:TextMessage Scene:scene ClientType:type];
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_PARAM_NOT_FOUND];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+
+/**
+ 分享图片
+
+ @param command Cordova参数
+ */
+- (void)shareImage:(CDVInvokedUrlCommand *)command {
+ self.callback = command.callbackId;
+ NSDictionary *args = [command.arguments objectAtIndex:0];
+ if (args) {
+ NSString *title = [self check:@"title" in:args];
+ NSString *image = [self check:@"image" in:args];
+ NSString *description = [self check:@"description" in:args];
+ int scene = [[args valueForKey:@"scene"] intValue];
+ int type = [[args valueForKey:@"client"] intValue];
+ NSData *imageData = [self processImage:image];
+ if(!imageData) {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_IMAGE_PARAM_INCORRECT];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ } else {
+ [self shareObjectWithData:@{ @"image" : imageData,
+ @"title" : title,
+ @"description" : description }
+ Type:ImageMesssage
+ Scene:scene
+ ClientType:type];
+ }
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_PARAM_NOT_FOUND];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+
+/**
+ 分享新闻链接
+
+ @param command Cordova参数
+ */
+- (void)shareNews:(CDVInvokedUrlCommand *)command {
+ self.callback = command.callbackId;
+ NSDictionary *args = [command.arguments objectAtIndex:0];
+ if (args) {
+ NSString *title = [self check:@"title" in:args];
+ NSString *image = [self check:@"image" in:args];
+ NSString *description = [self check:@"description" in:args];
+ NSString *url = [self check:@"url" in:args];
+ int scene = [[args valueForKey:@"scene"] intValue];
+ int type = [[args valueForKey:@"client"] intValue];
+ NSData *imageData = [self processImage:image];
+ if(!imageData) {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_IMAGE_PARAM_INCORRECT];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ } else {
+ [self shareObjectWithData:@{ @"url" : url,
+ @"image" : imageData,
+ @"title" : title,
+ @"description" : description }
+ Type:NewsMessageWithLocalImage
+ Scene:scene
+ ClientType:type];
+
+ }
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_PARAM_NOT_FOUND];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+
+/**
+ 分享音乐链接
+
+ @param command Cordova参数
+ */
+- (void)shareAudio:(CDVInvokedUrlCommand *)command {
+ self.callback = command.callbackId;
+ NSDictionary *args = [command.arguments objectAtIndex:0];
+ if (args) {
+ NSString *title = [self check:@"title" in:args];
+ NSString *image = [self check:@"image" in:args];
+ NSString *description = [self check:@"description" in:args];
+ NSString *url = [self check:@"url" in:args];
+ NSString *flashUrl = [self check:@"flashUrl" in:args];
+ int scene = [[args valueForKey:@"scene"] intValue];
+ int type = [[args valueForKey:@"client"] intValue];
+ NSData *imageData = [self processImage:image];
+ if(!imageData) {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_IMAGE_PARAM_INCORRECT];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ } else {
+ [self shareObjectWithData:@{ @"url" : url,
+ @"image" : imageData,
+ @"flashUrl" : flashUrl,
+ @"title" : title,
+ @"description" : description }
+ Type:AudioMessage
+ Scene:scene
+ ClientType:type];
+ }
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_PARAM_NOT_FOUND];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+
+/**
+ 分享视频链接
+
+ @param command Cordova参数
+ */
+- (void)shareVideo:(CDVInvokedUrlCommand *)command {
+ self.callback = command.callbackId;
+ NSDictionary *args = [command.arguments objectAtIndex:0];
+ if (args) {
+ NSString *title = [self check:@"title" in:args];
+ NSString *image = [self check:@"image" in:args];
+ NSString *description = [self check:@"description" in:args];
+ NSString *url = [self check:@"url" in:args];
+ NSString *flashUrl = [self check:@"flashUrl" in:args];
+ int scene = [[args valueForKey:@"scene"] intValue];
+ int type = [[args valueForKey:@"client"] intValue];
+ NSData *imageData = [self processImage:image];
+ if(!imageData) {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_IMAGE_PARAM_INCORRECT];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ } else {
+ [self shareObjectWithData:@{ @"url" : url,
+ @"image" : imageData,
+ @"flashUrl" : flashUrl,
+ @"title" : title,
+ @"description" : description }
+ Type:VideoMessage
+ Scene:scene
+ ClientType:type];
+ }
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_PARAM_NOT_FOUND];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+
+/**
+ 分享文本到QQ空间
+
+ @param text 分享文本
+ */
+- (void)shareTextToQQZone:(NSString *)text Client:(int) client {
+ QQApiImageArrayForQZoneObject *txtObj = [QQApiImageArrayForQZoneObject objectWithimageDataArray:nil title:text extMap:nil]; if (client == 1) {
+ txtObj.shareDestType = AuthShareType_TIM;
+ } else {
+ txtObj.shareDestType = AuthShareType_QQ;
+ }
+ SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:txtObj];
+ QQApiSendResultCode sent = [QQApiInterface SendReqToQZone:req];
+ [self handleSendResult:sent];
+}
+
+/**
+ 分享方法
+
+ @param shareData 分享数据
+ @param type 分享的类型
+ @param scene 分享的场景
+ */
+- (void)shareObjectWithData:(NSDictionary *)shareData Type:(QQShareType)type Scene:(QQShareScene)scene ClientType:(int) client {
+ switch (type) {
+ case TextMessage: {
+ NSString *msg = [shareData objectForKey:@"text"];
+ QQApiTextObject *txtObj = [QQApiTextObject objectWithText:msg];
+ [txtObj setCflag:kQQAPICtrlFlagQZoneShareOnStart];
+ switch (scene) {
+ case QQZone:
+ [self shareTextToQQZone:msg Client:client];
+ return;
+ case Favorite:
+ [txtObj setCflag:kQQAPICtrlFlagQQShareFavorites];
+ break;
+ default:
+ [txtObj setCflag:kQQAPICtrlFlagQQShare];
+ break;
+ }
+ if (client == 1) {
+ txtObj.shareDestType = AuthShareType_TIM;
+ } else {
+ txtObj.shareDestType = AuthShareType_QQ;
+ }
+ SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:txtObj];
+ QQApiSendResultCode sent = [QQApiInterface sendReq:req];
+ [self handleSendResult:sent];
+ } break;
+ case ImageMesssage: {
+ NSData *data = [shareData objectForKey:@"image"];
+ NSString *title = [shareData objectForKey:@"title"];
+ NSString *description = [shareData objectForKey:@"description"];
+ QQApiImageObject *imgObj = [QQApiImageObject objectWithData:data
+ previewImageData:nil
+ title:title
+ description:description];
+ switch (scene) {
+ case QQZone:
+ [imgObj setCflag:kQQAPICtrlFlagQZoneShareOnStart];
+ break;
+ case Favorite:
+ [imgObj setCflag:kQQAPICtrlFlagQQShareFavorites];
+ break;
+ default:
+ [imgObj setCflag:kQQAPICtrlFlagQQShare];
+ break;
+ }
+ if (client == 1) {
+ imgObj.shareDestType = AuthShareType_TIM;
+ } else {
+ imgObj.shareDestType = AuthShareType_QQ;
+ }
+ SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:imgObj];
+ QQApiSendResultCode sent = [QQApiInterface sendReq:req];
+ [self handleSendResult:sent];
+ } break;
+ case NewsMessageWithLocalImage: {
+ NSData *data = [shareData objectForKey:@"image"];
+ NSURL *url = [NSURL URLWithString:[shareData objectForKey:@"url"]];
+ NSString *title = [shareData objectForKey:@"title"];
+ NSString *description = [shareData objectForKey:@"description"];
+ QQApiNewsObject *newsObj = [QQApiNewsObject objectWithURL:url
+ title:title
+ description:description
+ previewImageData:data];
+ switch (scene) {
+ case QQZone:
+ [newsObj setCflag:kQQAPICtrlFlagQZoneShareOnStart];
+ break;
+ case Favorite:
+ [newsObj setCflag:kQQAPICtrlFlagQQShareFavorites];
+ break;
+ default:
+ [newsObj setCflag:kQQAPICtrlFlagQQShare];
+ break;
+ }
+ if (client == 1) {
+ newsObj.shareDestType = AuthShareType_TIM;
+ } else {
+ newsObj.shareDestType = AuthShareType_QQ;
+ }
+ SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:newsObj];
+ QQApiSendResultCode sent = [QQApiInterface sendReq:req];
+ [self handleSendResult:sent];
+ } break;
+ case AudioMessage: {
+ NSData *data = [shareData objectForKey:@"image"];
+ NSURL *url = [NSURL URLWithString:[shareData objectForKey:@"url"]];
+ NSString *title = [shareData objectForKey:@"title"];
+ NSString *description = [shareData objectForKey:@"description"];
+ NSURL *flashUrl = [NSURL URLWithString:[shareData objectForKey:@"url"]];
+ QQApiAudioObject *audioObj = [QQApiAudioObject objectWithURL:url
+ title:title
+ description:description
+ previewImageData:data];
+ [audioObj setFlashURL:flashUrl];
+ switch (scene) {
+ case QQZone:
+ [audioObj setCflag:kQQAPICtrlFlagQZoneShareOnStart];
+ break;
+ case Favorite:
+ [audioObj setCflag:kQQAPICtrlFlagQQShareFavorites];
+ break;
+ default:
+ [audioObj setCflag:kQQAPICtrlFlagQQShare];
+ break;
+ }
+ if (client == 1) {
+ audioObj.shareDestType = AuthShareType_TIM;
+ } else {
+ audioObj.shareDestType = AuthShareType_QQ;
+ }
+ SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:audioObj];
+ QQApiSendResultCode sent = [QQApiInterface sendReq:req];
+ [self handleSendResult:sent];
+ } break;
+ case VideoMessage: {
+ NSData *data = [shareData objectForKey:@"image"];
+ NSURL *url = [NSURL URLWithString:[shareData objectForKey:@"url"]];
+ NSString *title = [shareData objectForKey:@"title"];
+ NSString *description = [shareData objectForKey:@"description"];
+ NSURL *flashUrl = [NSURL URLWithString:[shareData objectForKey:@"url"]];
+ QQApiVideoObject *videoObj = [QQApiVideoObject objectWithURL:url
+ title:title
+ description:description
+ previewImageData:data];
+ [videoObj setFlashURL:flashUrl];
+ switch (scene) {
+ case QQZone:
+ [videoObj setCflag:kQQAPICtrlFlagQZoneShareOnStart];
+ break;
+ case Favorite:
+ [videoObj setCflag:kQQAPICtrlFlagQQShareFavorites];
+ break;
+ default:
+ [videoObj setCflag:kQQAPICtrlFlagQQShare];
+ break;
+ }
+ if (client == 1) {
+ videoObj.shareDestType = AuthShareType_TIM;
+ } else {
+ videoObj.shareDestType = AuthShareType_QQ;
+ }
+ SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:videoObj];
+ QQApiSendResultCode sent = [QQApiInterface sendReq:req];
+ [self handleSendResult:sent];
+ }
+ default:
+ break;
+ }
+}
+
+/**
+ 分析那个结果处理
+
+ @param sendResult 分享结果
+ */
+- (void)handleSendResult:(QQApiSendResultCode)sendResult {
+ switch (sendResult) {
+ case EQQAPISENDSUCESS:
+ break;
+ case EQQAPIAPPSHAREASYNC:
+ break;
+ case EQQAPIAPPNOTREGISTED: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"App 未注册"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case EQQAPIMESSAGECONTENTINVALID:
+ case EQQAPIMESSAGECONTENTNULL:
+ case EQQAPIMESSAGETYPEINVALID: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"发送参数错误"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case EQQAPITIMNOTINSTALLED: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"没有安装 TIM"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case EQQAPIQQNOTINSTALLED: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"没有安装手机 QQ"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case EQQAPITIMNOTSUPPORTAPI:
+ case EQQAPIQQNOTSUPPORTAPI: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"API 接口不支持"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case EQQAPISENDFAILD: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"发送失败"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case EQQAPIVERSIONNEEDUPDATE: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"当前 QQ 版本太低"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case ETIMAPIVERSIONNEEDUPDATE: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"当前 TIM 版本太低"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case EQQAPIQZONENOTSUPPORTTEXT: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"QQZone 不支持 QQApiTextObject 分享"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case EQQAPIQZONENOTSUPPORTIMAGE: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"QQZone 不支持 QQApiImageObject 分享"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case EQQAPISHAREDESTUNKNOWN: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"未指定分享到 QQ 或 TIM"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ default: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"发生其他错误"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ }
+}
+
+#pragma mark - QQApiInterfaceDelegate
+- (void)onReq:(QQBaseReq *)req {
+}
+
+- (void)onResp:(QQBaseResp *)resp {
+ switch ([resp.result integerValue]) {
+ case 0: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ case -4: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_SHARE_CANCEL];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ default: {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ break;
+ }
+ }
+}
+
+- (void)isOnlineResponse:(NSDictionary *)response {
+}
+
+#pragma mark - TencentSessionDelegate
+- (void)tencentDidLogin {
+ if (tencentOAuth.accessToken && 0 != [tencentOAuth.accessToken length]) {
+ NSMutableDictionary *Dic = [NSMutableDictionary dictionaryWithCapacity:2];
+ [Dic setObject:tencentOAuth.openId forKey:@"userid"];
+ [Dic setObject:tencentOAuth.accessToken forKey:@"access_token"];
+ [Dic setObject:[NSString stringWithFormat:@"%f", [tencentOAuth.expirationDate timeIntervalSince1970] * 1000] forKey:@"expires_time"];
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:Dic];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_LOGIN_ERROR];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ }
+}
+
+- (void)tencentDidLogout {
+ tencentOAuth = nil;
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+}
+
+- (void)tencentDidNotLogin:(BOOL)cancelled {
+ if (cancelled) {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_LOGIN_CANCEL];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ } else {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_LOGIN_ERROR];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+ }
+}
+
+- (void)tencentDidNotNetWork {
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:QQ_LOGIN_NETWORK_ERROR];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callback];
+}
+
+/**
+ 图片处理
+
+ @param image 图片数据
+ @return 图片NSdata数据
+ */
+- (NSData *)processImage:(NSString *)image {
+ if ([self isBase64Data:image]) {
+ return [[NSData alloc] initWithBase64EncodedString:image options:0];
+ } else if ([image hasPrefix:@"http://"] || [image hasPrefix:@"https://"]) {
+ NSURL *url = [NSURL URLWithString:image];
+ return [NSData dataWithContentsOfURL:url];
+ } else {
+ return [NSData dataWithContentsOfFile:image];
+ }
+}
+
+/**
+ 检查图片是不是Base64
+
+ @param data 图片数据
+ @return 结果true or false
+ */
+- (BOOL)isBase64Data:(NSString *)data {
+ data = [[data componentsSeparatedByCharactersInSet:
+ [NSCharacterSet whitespaceAndNewlineCharacterSet]]
+ componentsJoinedByString:@""];
+ if ([data length] % 4 == 0) {
+ static NSCharacterSet *invertedBase64CharacterSet = nil;
+ if (invertedBase64CharacterSet == nil) {
+ invertedBase64CharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="] invertedSet];
+ }
+ return [data rangeOfCharacterFromSet:invertedBase64CharacterSet options:NSLiteralSearch].location == NSNotFound;
+ }
+ return NO;
+}
+
+/**
+ 检查参数是否存在
+
+ @param param 要检查的参数
+ @param args 参数字典
+ @return 参数
+ */
+- (NSString *)check:(NSString *)param in:(NSDictionary *)args {
+ NSString *data = [args objectForKey:param];
+ return data?data:@"";
+}
+
+@end
--- /dev/null
+///
+/// \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"
+
+/**
+ \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发起分享请求
+ \param req 分享内容的请求
+ \return 请求发送结果码
+ */
++ (QQApiSendResultCode)sendReq:(QQBaseReq *)req;
+
+/**
+ 向手Q QZone结合版发起分享请求
+ \note H5分享只支持单张网络图片的传递
+ \param req 分享内容的请求
+ \return 请求发送结果码
+ */
++ (QQApiSendResultCode)SendReqToQZone:(QQBaseReq *)req;
+
+/**
+ 向手Q 群部落发起分享请求
+ \note H5分享只支持单张网络图片的传递
+ \param req 分享内容的请求
+ \return 请求发送结果码
+ */
++ (QQApiSendResultCode)SendReqToQQGroupTribe:(QQBaseReq *)req;
+
+/**
+ 向手Q发送应答消息
+ \param resp 应答消息
+ \return 应答发送结果码
+ */
++ (QQApiSendResultCode)sendResp:(QQBaseResp *)resp;
+
+/**
+ 检测是否已安装QQ
+ \return 如果QQ已安装则返回YES,否则返回NO
+ */
++ (BOOL)isQQInstalled;
+
+/**
+ 检测是否已安装TIM
+ \return 如果TIM已安装则返回YES,否则返回NO
+ */
++ (BOOL)isTIMInstalled;
+
+/**
+ 批量检测QQ号码是否在线
+ */
++ (void)getQQUinOnlineStatues:(NSArray *)QQUins delegate:(id<QQApiInterfaceDelegate>)delegate;
+
+/**
+ 检测QQ是否支持API调用
+ \return 如果当前安装QQ版本支持API调用则返回YES,否则返回NO
+ */
++ (BOOL)isQQSupportApi;
+
+/**
+ 检测TIM是否支持API调用
+ \return 如果当前安装TIM版本支持API调用则返回YES,否则返回NO
+ */
++ (BOOL)isTIMSupportApi;
+
+/**
+ 启动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>和<code>QQApiInterface#isTIMSupportApi</code>检测发现TIM没安装或当前版本TIM不支持API调用,可引导用户通过打开此链接下载最新版TIM。
+ \return iPhoneTIM下载地址
+ */
++ (NSString *)getTIMInstallUrl;
+
+@end
--- /dev/null
+///
+/// \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 enum
+{
+ EQQAPISENDSUCESS = 0,
+ EQQAPIQQNOTINSTALLED = 1,
+ EQQAPIQQNOTSUPPORTAPI = 2,
+ EQQAPIMESSAGETYPEINVALID = 3,
+ EQQAPIMESSAGECONTENTNULL = 4,
+ EQQAPIMESSAGECONTENTINVALID = 5,
+ EQQAPIAPPNOTREGISTED = 6,
+ EQQAPIAPPSHAREASYNC = 7,
+ EQQAPIQQNOTSUPPORTAPI_WITH_ERRORSHOW = 8,
+ EQQAPISENDFAILD = -1,
+ EQQAPISHAREDESTUNKNOWN = -2, //未指定分享到QQ或TIM
+
+ EQQAPITIMNOTINSTALLED = 11, //TIM未安装
+ EQQAPITIMNOTSUPPORTAPI = 12, // TIM api不支持
+ //qzone分享不支持text类型分享
+ EQQAPIQZONENOTSUPPORTTEXT = 10000,
+ //qzone分享不支持image类型分享
+ EQQAPIQZONENOTSUPPORTIMAGE = 10001,
+ //当前QQ版本太低,需要更新至新版本才可以支持
+ EQQAPIVERSIONNEEDUPDATE = 10002,
+ ETIMAPIVERSIONNEEDUPDATE = 10004,
+} QQApiSendResultCode;
+
+#pragma mark - QQApiObject(分享对象类型)
+
+// QQApiObject control flags
+enum
+{
+ kQQAPICtrlFlagQZoneShareOnStart = 0x01,
+ kQQAPICtrlFlagQZoneShareForbid = 0x02,
+ kQQAPICtrlFlagQQShare = 0x04,
+ kQQAPICtrlFlagQQShareFavorites = 0x08, //收藏
+ kQQAPICtrlFlagQQShareDataline = 0x10, //数据线
+};
+
+// 分享到QQ或TIM
+typedef enum ShareDestType {
+ ShareDestTypeQQ,
+ ShareDestTypeTIM,
+}ShareDestType;
+
+// QQApiObject
+/** \brief 所有在QQ及插件间发送的数据对象的根类。
+ */
+__attribute__((visibility("default"))) @interface QQApiObject : NSObject
+@property(nonatomic,retain) NSString* title; ///< 标题,最长128个字符
+@property(nonatomic,retain) NSString* description; ///<简要描述,最长512个字符
+
+@property (nonatomic, assign) uint64_t cflag;
+@property (nonatomic, assign) ShareDestType shareDestType; //分享到QQ或TIM,必须指定
+@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 enum QQApiURLTargetType{
+ QQApiURLTargetTypeNotSpecified = 0x00,
+ QQApiURLTargetTypeAudio = 0x01,
+ QQApiURLTargetTypeVideo = 0x02,
+ QQApiURLTargetTypeNews = 0x03
+}QQApiURLTargetType;
+
+/** @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
+
+// 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可传ALAsset的ALAssetPropertyAssetURL,或者PHAsset的localIdentifier
+ @param extMap 扩展字段
+ */
+@interface QQApiVideoForQZoneObject : QQApiObject
+
+@property(nonatomic, retain) NSString *assetURL;
+@property(nonatomic,retain) NSDictionary* extMap; // 扩展字段
+
+- (id)initWithAssetURL:(NSString*)assetURL title:(NSString*)title extMap:(NSDictionary *)extMap;
+
++ (id)objectWithAssetURL:(NSString*)assetURL 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
+
+// QQApiGroupTribeImageObject
+/** @brief 群部落图片对象
+ 用于分享图片内容的对象,是一个指定为图片类型的 可以指定一些其他的附加数据<code>QQApiExtendObject</code>
+ */
+@interface QQApiGroupTribeImageObject : QQApiImageObject
+{
+ NSString *_bid;
+ NSString *_bname;
+}
+// 群部落id
+@property (nonatomic, retain)NSString* bid;
+
+// 群部落名称
+@property (nonatomic, retain)NSString* bname;
+
+@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
+
+// QQApiPayObject
+/** \brief 支付对象
+ */
+@interface QQApiPayObject : QQApiObject
+@property(nonatomic,retain)NSString* OrderNo; ///<支付订单号,必填
+@property(nonatomic,retain)NSString* AppInfo; ///<支付来源信息,必填
+
+-(id)initWithOrderNo:(NSString*)OrderNo AppInfo:(NSString*)AppInfo; ///<初始化方法
++(id)objectWithOrderNo:(NSString*)OrderNo AppInfo:(NSString*)AppInfo;///<工厂方法,获取一个QQApiPayObject对象.
+@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
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// 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
+
+// QQApiWPAObject
+/** \brief 发起WPA对象
+ */
+@interface QQApiWPAObject : QQApiObject
+@property(nonatomic,retain)NSString* uin; ///<想要对话的QQ号
+
+-(id)initWithUin:(NSString*)uin; ///<初始化方法
++(id)objectWithUin:(NSString*)uin;///<工厂方法,获取一个QQApiWPAObject对象.
+@end
+
+// QQApiAddFriendObject
+/** \brief 添加好友
+ */
+@interface QQApiAddFriendObject : QQApiObject
+@property (nonatomic,retain)NSString* openID;
+@property (nonatomic,retain)NSString* subID;
+@property (nonatomic,retain)NSString* remark;
+
+-(id)initWithOpenID:(NSString*)openID; ///<初始化方法
++(id)objecWithOpenID:(NSString*)openID; ///<工厂方法,获取一个QQApiAddFriendObject对象.
+
+@end
+
+// QQApiGameConsortiumBindingGroupObject
+/** \brief 游戏公会绑定群
+ */
+@interface QQApiGameConsortiumBindingGroupObject : QQApiObject
+@property (nonatomic,retain)NSString* signature;
+@property (nonatomic,retain)NSString* unionid;
+@property (nonatomic,retain)NSString* zoneID;
+@property (nonatomic,retain)NSString* appDisplayName;
+
+-(id)initWithGameConsortium:(NSString*)signature unionid:(NSString*)unionid zoneID:(NSString*)zoneID appDisplayName:(NSString*)appDisplayName; ///<初始化方法
++(id)objectWithGameConsortium:(NSString*)signature unionid:(NSString*)unionid zoneID:(NSString*)zoneID appDisplayName:(NSString*)appDisplayName; ///<工厂方法,获取一个QQApiAddFriendObject对象.
+
+@end
+
+// QQApiGameConsortiumBindingGroupObject
+/** \brief 加入群
+ */
+@interface QQApiJoinGroupObject : QQApiObject
+@property (nonatomic,retain)NSString* groupUin;
+@property (nonatomic,retain)NSString* groupKey;
+
+- (id)initWithGroupInfo:(NSString*)groupUin key:(NSString*)groupKey; ///<初始化方法
++ (id)objectWithGroupInfo:(NSString*)groupUin key:(NSString*)groupKey; ///<同时提供群号和群KEY 工厂方法,获取一个QQApiAddFriendObject对象.
++ (id)objectWithGroupKey:(NSString*)groupKey; ///<只需要群的KEY 工厂方法,获取一个QQApiAddFriendObject对象.
+
+@end
+
+// QQApiGroupChatObject
+/** \brief 发起群会话对象
+ */
+@interface QQApiGroupChatObject : QQApiObject
+@property(nonatomic,retain)NSString* groupID; ///<想要对话的群号
+
+-(id)initWithGroup:(NSString*)groupID; ///<初始化方法
++(id)objectWithGroup:(NSString*)groupID;///<工厂方法,获取一个QQApiGroupChatObject对象.
+@end
+
+#pragma mark - QQApi请求消息类型
+
+/**
+ QQApi请求消息类型
+ */
+enum QQApiInterfaceReqType
+{
+ EGETMESSAGEFROMQQREQTYPE = 0, ///< 手Q -> 第三方应用,请求第三方应用向手Q发送消息
+ ESENDMESSAGETOQQREQTYPE = 1, ///< 第三方应用 -> 手Q,第三方应用向手Q分享消息
+ ESHOWMESSAGEFROMQQREQTYPE = 2 ///< 手Q -> 第三方应用,请求第三方应用展现消息中的数据
+};
+
+/**
+ QQApi应答消息类型
+ */
+enum 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
+
+/**
+ GetMessageFromQQResp应答帮助类
+ */
+@interface GetMessageFromQQResp : QQBaseResp
+
+/**
+ 创建一个GetMessageFromQQResp应答实例
+ \param message 具体分享消息实例
+ \return 新创建的GetMessageFromQQResp应答实例
+ */
++ (GetMessageFromQQResp *)respWithContent:(QQApiObject *)message;
+
+/** 具体分享消息 */
+@property (nonatomic, retain) QQApiObject *message;
+
+@end
+
+/**
+ SendMessageToQQReq请求帮助类
+ */
+@interface SendMessageToQQReq : QQBaseReq
+
+/**
+ 创建一个SendMessageToQQReq请求实例
+ \param message 具体分享消息实例
+ \return 新创建的SendMessageToQQReq请求实例
+ */
++ (SendMessageToQQReq *)reqWithContent:(QQApiObject *)message;
+
+/** 具体分享消息 */
+@property (nonatomic, retain) QQApiObject *message;
+
+@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
+
+/**
+ ShowMessageFromQQResp应答帮助类
+ */
+@interface ShowMessageFromQQResp : QQBaseResp
+
+/**
+ 创建一个ShowMessageFromQQResp应答实例
+ \param result 展现消息结果
+ \param errDesp 具体错误描述信息
+ \return 新创建的ShowMessageFromQQResp应答实例
+ */
++ (ShowMessageFromQQResp *)respWithResult:(NSString *)result errorDescription:(NSString *)errDesp;
+
+@end
+
+#endif
--- /dev/null
+//
+// TencentMessage.h
+// TencentOpenApi_IOS
+//
+// Created by qqconnect on 13-5-29.
+// Copyright (c) 2013年 Tencent. All rights reserved.
+//
+
+#ifndef QQ_OPEN_SDK_LITE
+
+#import <Foundation/Foundation.h>
+#import "TencentMessageObject.h"
+
+typedef enum
+{
+ kIphoneQQ,
+ kIphoneQZONE,
+ kIphoneTIM,
+ kThirdApp,
+}
+TecnentPlatformType;
+
+typedef enum
+{
+ kTencentApiSuccess,
+ kTencentApiPlatformUninstall,
+ kTencentApiPlatformNotSupport,
+ kTencentApiParamsError,
+ kTencentApiFail,
+}
+TencentApiRetCode;
+
+@class TencentApiReq;
+@class TencentApiResp;
+
+/**
+ * \brief TencentApiInterface的回调
+ *
+ * TencentApiInterface的回调接口
+ * \note v1.0版本只支持腾讯业务拉起第三方请求内容
+ */
+@protocol TencentApiInterfaceDelegate <NSObject>
+
+@optional
+/**
+ * 请求获得内容 当前版本只支持第三方相应腾讯业务请求
+ */
+- (BOOL)onTencentReq:(TencentApiReq *)req;
+
+/**
+ * 响应请求答复 当前版本只支持腾讯业务相应第三方的请求答复
+ */
+- (BOOL)onTencentResp:(TencentApiResp *)resp;
+
+@end
+
+/**
+ * \brief TencentApiInterface的回调
+ *
+ * TencentApiInterface的调用接口
+ * \note v1.0版本只支持第三方答复内容
+ */
+@interface TencentApiInterface : NSObject
+
+/**
+ * 发送答复返回腾讯业务
+ * \param resp 答复内容
+ * \return 返回码
+ */
++ (TencentApiRetCode)sendRespMessageToTencentApp:(TencentApiResp *)resp;
+
+/**
+ * 是否可以处理拉起协议
+ * \param url
+ * \param delegate 指定的回调
+ * \return 是否是腾讯API认识的消息类型
+ */
++ (BOOL)canOpenURL:(NSURL *)url delegate:(id<TencentApiInterfaceDelegate>)delegate;
+
+/**
+ * 处理应用拉起协议
+ * \param url
+ * \param delegate 指定的回调
+ * \return 是否是腾讯API认识的消息类型
+ */
++ (BOOL)handleOpenURL:(NSURL *)url delegate:(id<TencentApiInterfaceDelegate>)delegate;
+
+/**
+ * 用户设备是否安装腾讯APP
+ * \param platform 指定的腾讯业务
+ * \return YES:安装 NO:未安装
+ */
++ (BOOL)isTencentAppInstall:(TecnentPlatformType)platform;
+
+/**
+ * 用户设备是否支持调用SDK
+ * \param platform 指定的腾讯业务
+ * \return YES:支持 NO:不支持
+ */
++ (BOOL)isTencentAppSupportTencentApi:(TecnentPlatformType)platform;
+
+@end
+
+#endif
--- /dev/null
+//
+// TencentMessageObject.h
+// TencentOpenApi_IOS
+//
+// Created by qqconnect on 13-5-27.
+// Copyright (c) 2013年 Tencent. All rights reserved.
+//
+
+#ifndef QQ_OPEN_SDK_LITE
+
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+#import "sdkdef.h"
+
+#define kTextLimit (1024 * 1024)
+#define kDataLimit (1024 * 1024 * 10)
+#define kPreviewDataLimit (1024 * 1024)
+
+@class TencentApiReq;
+@class TencentApiResp;
+
+/**
+ * 必填的NSArray型参数
+ */
+typedef NSArray *TCRequiredArray;
+
+/**
+ * 必填的NSDictionary型参数
+ */
+typedef NSDictionary *TCRequiredDictionary;
+
+/**
+ * 必填的TencentApiReq型参数
+ */
+typedef TencentApiReq *TCRequiredReq;
+
+/**
+ * 可选的UIImage类型参数
+ */
+typedef NSData *TCOptionalData;
+
+
+/**
+ * 可选的NSArray型参数
+ */
+typedef NSArray *TCOptionalArray;
+
+/**
+ * 可选的TencentApiReq型参数
+ */
+typedef TencentApiReq *TCOptionalReq;
+
+/**
+ * TencentReqMessageType 请求类型枚举参数
+ */
+typedef enum
+{
+ /** TX APP请求内容填充(需要第三方开发者填充完成内容后需要主动调用sendRespMessageToTencentApp)*/
+ ReqFromTencentAppQueryContent,
+ /** TX APP请求展现内容 (不用调用答复) */
+ ReqFromTencentAppShowContent,
+ /** 第三方 APP 请求内容 */
+ ReqFromThirdAppQueryContent,
+ /** 第三方 APP 请求展现内容(类似分享)*/
+ ReqFromThirdAppShowContent,
+}
+TencentReqMessageType;
+
+typedef enum
+{
+ RespFromTencentAppQueryContent,
+ RespFromTencentAppShowContent,
+ RespFromThirdAppQueryContent,
+ RespFromThirdAppShowContent,
+}
+TencentRespMessageType;
+
+/**
+ * TencentObjVersion 腾讯API消息类型枚举
+ */
+typedef enum
+{
+ /** 文本类型 */
+ TencentTextObj,
+ /** 图片类型 */
+ TencentImageObj,
+ /** 音频类型 */
+ TencentAudioObj,
+ /** 视频类型 */
+ TencentVideoObj,
+ /** 图片视频类 */
+ TencentImageAndVideoObj,
+}
+TencentObjVersion;
+
+/**
+ * \brief 请求包
+ *
+ * TencentApiReq用来向其他业务发送请求包
+ */
+@interface TencentApiReq : NSObject<NSCoding>
+
+/**
+ * 根据序列号生成一个请求包
+ * \param apiSeq 请求序列号
+ * \param type 请求类型
+ * \return tencentApiReq实例
+ */
++ (TencentApiReq *)reqFromSeq:(NSInteger)apiSeq type:(TencentReqMessageType)type;
+
+/** 请求类型 */
+@property (readonly, assign, nonatomic)TCRequiredInt nMessageType;
+
+/** 请求平台 */
+@property (readonly, assign, nonatomic)NSInteger nPlatform;
+
+/** 请求的SDK版本号 */
+@property (readonly, assign, nonatomic)NSInteger nSdkVersion;
+
+/** 请求序列号 */
+@property (readonly, assign, nonatomic)TCRequiredInt nSeq;
+
+/** 第三方的APPID */
+@property (nonatomic, retain)TCRequiredStr sAppID;
+
+/** 请求内容 TencentBaseMessageObj对象数组 */
+@property (nonatomic, retain)TCOptionalArray arrMessage;
+
+/** 请求的描述 可以用于告诉对方这个请求的特定场景 */
+@property (nonatomic, retain)TCOptionalStr sDescription;
+
+@end
+
+/**
+ * \brief 答复包
+ *
+ * TencentApiResp用来向其他业务发送答复包
+ */
+@interface TencentApiResp : NSObject<NSCoding>
+
+/**
+ * 根据序列号生成一个答复包
+ * \param req 答复对应的请求包(如果req不是TencentApiReq或者他的子类,会抛出异常)
+ * \return 答复包体
+ */
++ (TencentApiResp *)respFromReq:(TencentApiReq *)req;
+
+/** 返回码 */
+@property (nonatomic, assign)TCOptionalInt nRetCode;
+
+/** 返回消息 */
+@property (nonatomic, retain)TCOptionalStr sRetMsg;
+
+/** 答复对应的请求包 */
+@property (nonatomic, retain)TCOptionalReq objReq;
+
+@end
+
+/**
+ * \brief 消息体
+ *
+ * TencentBaseMessageObj 应用之间传递消息体
+ */
+@interface TencentBaseMessageObj : NSObject<NSCoding>
+
+/** 消息类型 */
+@property (nonatomic, assign)NSInteger nVersion;
+
+/** 消息描述 */
+@property (nonatomic, retain)NSString *sName;
+
+/** 消息的扩展信息 主要是可以用来进行一些请求消息体的描述 譬如图片要求的width height 文字的关键字什么的, 也可以不用填写*/
+@property (nonatomic, retain)NSDictionary *dictExpandInfo;
+
+/**
+ * 消息是否有效
+ */
+- (BOOL)isVaild;
+
+@end
+
+#pragma mark TencentTextMessage
+/**
+ * \brief 文本的消息体
+ *
+ * TencentTextMessageObjV1 应用之间传递的文本消息体
+ */
+@interface TencentTextMessageObjV1 : TencentBaseMessageObj
+
+/**
+ * 文本
+ * \note 文本长度不能超过4096个字
+ */
+@property (nonatomic, retain) NSString *sText;
+
+
+/**
+ * 初始化文本消息
+ * \param text 文本
+ * \return 初始化返回的文本消息
+ */
+- (id)initWithText:(NSString *)text;
+
+@end
+
+
+#pragma mark TecentImageMessage
+
+/**
+ * TencentApiImageSourceType 图片数据类型(请求方对数据类型可能会有限制)
+ */
+typedef enum
+{
+ /** 图片数据是url或二进制数据 */
+ AllImage,
+ /** 图片数据是url */
+ UrlImage,
+ /** 图片数据是二进制数据 */
+ DataImage,
+}TencentApiImageSourceType;
+
+/**
+ * \brief 图片的消息体
+ *
+ * TencentImageMessageObjV1 应用之间传递的图片消息体
+ */
+@interface TencentImageMessageObjV1 : TencentBaseMessageObj
+
+/**
+ * 图片数据
+ * \note 图片不能大于10M
+ */
+@property (nonatomic, retain) NSData *dataImage;
+
+/**
+ * 缩略图的数据
+ * \note 图片不能大于1M
+ */
+@property (nonatomic, retain) NSData *dataThumbImage;
+
+/** 图片URL */
+@property (nonatomic, retain) NSString *sUrl;
+
+/** 图片的描述 */
+@property (nonatomic, retain) NSString *sDescription;
+
+/** 图片的size */
+@property (nonatomic, assign) CGSize szImage;
+
+/**
+ * 图片来源
+ * \note TencentApiImageSourceType对应的类型
+ */
+@property (readonly, assign) NSInteger nType;
+
+/**
+ * 初始化图片消息
+ * \param dataImage 图片类型
+ * \return 初始化返回的图片消息
+ */
+- (id)initWithImageData:(NSData *)dataImage;
+
+/**
+ * 初始化图片消息
+ * \param url 图片url
+ * \return 初始化返回的图片消息
+ */
+- (id)initWithImageUrl:(NSString *)url;
+
+/**
+ * 初始化图片消息
+ * \param type 图片类型
+ * \return 初始化返回的图片消息
+ */
+- (id)initWithType:(TencentApiImageSourceType)type;
+@end
+
+
+#pragma mark TencentAudioMessage
+/**
+ * \brief 音频的消息体
+ *
+ * TencentAudioMessageObjV1 应用之间传递的音频消息体
+ */
+@interface TencentAudioMessageObjV1 : TencentBaseMessageObj
+
+/** 音频URL */
+@property (nonatomic, retain) NSString *sUrl;
+
+/**
+ * 音频的预览图
+ * \note图片不能大于1M
+ */
+@property (nonatomic, retain) NSData *dataImagePreview;
+
+/** 音频的预览图URL */
+@property (nonatomic, retain) NSString *sImagePreviewUrl;
+
+/** 音频的描述 */
+@property (nonatomic, retain) NSString *sDescription;
+
+/**
+ * 初始化图片消息
+ * \param url 音频URL
+ * \return 初始化返回的音频消息
+ */
+- (id)initWithAudioUrl:(NSString *)url;
+
+@end
+
+
+#pragma mark TencentVideoMessage
+
+/**
+ * TencentApiVideoSourceType 视频数据类型(请求方对数据类型可能会有限制)
+ */
+
+typedef enum
+{
+ /** 视频来源于本地或网络 */
+ AllVideo,
+ /** 视频来源于本地 */
+ LocalVideo,
+ /** 视频来源于网络 */
+ NetVideo,
+}TencentApiVideoSourceType;
+
+/**
+ * \brief 视频的消息体
+ *
+ * TencentVideoMessageV1 应用之间传递的视频消息体
+ */
+@interface TencentVideoMessageV1 : TencentBaseMessageObj
+
+/**
+ * 视频URL
+ * \note 不能超过1024
+ */
+@property (nonatomic, retain) NSString *sUrl;
+
+/**
+ * 视频来源 主要是用来让发起方指定视频的来源
+ * \note TencentApiVideoSourceType 对应的类型 只读参数
+ */
+@property (readonly, assign, nonatomic) NSInteger nType;
+
+/**
+ * 视频的预览图
+ * \note 图片不能大于1M
+ */
+@property (nonatomic, retain) NSData *dataImagePreview;
+
+/** 视频的预览图URL */
+@property (nonatomic, retain) NSString *sImagePreviewUrl;
+
+/** 视频的描述 */
+@property (nonatomic, retain) NSString *sDescription;
+
+/**
+ * 初始化视频消息
+ * \param url 视频URL
+ * \param type 视频来源类型
+ * \return 初始化返回的视频消息
+ */
+- (id)initWithVideoUrl:(NSString *)url type:(TencentApiVideoSourceType)type;
+
+
+/**
+ * 初始化视频消息
+ * \param type 视频来源类型
+ * \return 初始化返回的视频消息
+ */
+- (id)initWithType:(TencentApiVideoSourceType)type;
+@end
+
+#pragma mark TencentImageMessageObj
+/**
+ * \brief 视频图片消息体
+ *
+ * TencentVideoMessageV1 这是一个扩展的类 是一个图片视频类
+ * \note 图片视频可以任选一个内容填充 但是注意只能填一个 当有一种类型被填充后 另外一个种类型就无法填充了
+ */
+@interface TencentImageAndVideoMessageObjV1 : TencentBaseMessageObj
+
+/** 图片消息 */
+@property (nonatomic, retain) TencentImageMessageObjV1 *objImageMessage;
+
+/** 视频消息 */
+@property (nonatomic, retain) TencentVideoMessageV1 *objVideoMessage;
+
+/**
+ * 初始化图片消息
+ * \param dataImage 图片数据
+ * \param url 视频url
+ * \return 初始化返回的图片视频消息
+ */
+- (id)initWithMessage:(NSData *)dataImage videoUrl:(NSString *)url;
+
+/**
+ * 设置图片
+ * \param dataImage 图片数据
+ */
+- (void)setDataImage:(NSData *)dataImage;
+
+/**
+ * 设置视频
+ * \param videoUrl 视频URL
+ */
+- (void)setVideoUrl:(NSString *)videoUrl;
+@end
+
+#endif
--- /dev/null
+///
+/// \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"
+#import "TencentOAuthObject.h"
+#import "TencentApiInterface.h"
+
+@protocol TencentSessionDelegate;
+@protocol TencentLoginDelegate;
+@protocol TencentApiInterfaceDelegate;
+@protocol TencentWebViewDelegate;
+
+@class TencentApiReq;
+@class TencentApiResp;
+
+typedef enum
+{
+ kTencentNotAuthorizeState,
+ kTencentSSOAuthorizeState,
+ kTencentWebviewAuthorzieState,
+} TencentAuthorizeState;
+
+typedef enum
+{
+ kAuthModeClientSideToken,
+ kAuthModeServerSideCode,
+} TencentAuthMode;
+
+#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;
+
+/** 主要是互娱的游戏设置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;
+
+/**
+ * 用来获得当前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版本号
+ **/
++ (QQVersion)iphoneQQVersion;
+
+
+/**
+ * 用来获得当前手机TIM的版本号
+ * \return 返回手机qq版本号
+ **/
++ (QQVersion)iphoneTIMVersion;
+
+/**
+ * 初始化TencentOAuth对象
+ * \param appId 第三方应用在互联开放平台申请的唯一标识
+ * \param delegate 第三方应用用于接收请求返回结果的委托对象
+ * \return 初始化后的授权登录对象
+ */
+- (id)initWithAppId:(NSString *)appId
+ andDelegate:(id<TencentSessionDelegate>)delegate;
+
+
+/**
+ * 判断用户手机上是否安装手机QQ
+ * \return YES:安装 NO:没安装
+ */
++ (BOOL)iphoneQQInstalled;
+
+/**
+ * 判断用户手机上是否安装手机TIM
+ * \return YES:安装 NO:没安装
+ */
++ (BOOL)iphoneTIMInstalled;
+
+/**
+ * 判断用户手机上的手机QQ是否支持SSO登录
+ * \return YES:支持 NO:不支持
+ */
++ (BOOL)iphoneQQSupportSSOLogin;
+
+/**
+ * 判断用户手机上的手机TIM是否支持SSO登录
+ * \return YES:支持 NO:不支持
+ */
++ (BOOL)iphoneTIMSupportSSOLogin;
+
+/**
+ * 判断用户手机上是否安装手机QZone
+ * \return YES:安装 NO:没安装
+ */
++ (BOOL)iphoneQZoneInstalled;
+
+/**
+ * 判断用户手机上的手机QZone是否支持SSO登录
+ * \return YES:支持 NO:不支持
+ */
++ (BOOL)iphoneQZoneSupportSSOLogin;
+
+/**
+ * 登录授权
+ *
+ * \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;
+
+/**
+ * 增量授权,因用户没有授予相应接口调用的权限,需要用户确认是否授权
+ * \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;
+
+/**
+ * (静态方法)获取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;
+
+/**
+ * SDK内置webview实现定向分享时,第三方应用可以根据应用是否在白名单里来开启该配置开关,默认为关闭;
+ * 在白名单里的应用调用该接口后,即打开sdk内置webview的二级白名单开关(相对与sdk后台的白名单),
+ * 那么在sdk后台白名单校验请求失败的情况下,会继续先尝试采用内置webview进行分享。
+ */
+- (void)openSDKWebViewQQShareEnable;
+
+
+/**
+ * 获取用户QZone相册列表
+ * \attention 需\ref apply_perm
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)getListAlbum;
+
+/**
+ * 获取用户QZone相片列表
+ * \attention 需\ref apply_perm
+ * \param params 参数字典,字典的关键字参见TencentOAuthObject.h中的\ref TCListPhotoDic
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)getListPhotoWithParams:(NSMutableDictionary *)params;
+
+
+/**
+ * 分享到QZone
+ * \param params 参数字典,字典的关键字参见TencentOAuthObject.h中的\ref TCAddShareDic
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)addShareWithParams:(NSMutableDictionary *)params;
+
+
+/**
+ * 上传照片到QZone指定相册
+ * \attention 需\ref apply_perm
+ * \param params 参数字典,字典的关键字参见TencentOAuthObject.h中的\ref TCUploadPicDic
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)uploadPicWithParams:(NSMutableDictionary *)params;
+
+/**
+ * 在QZone相册中创建一个新的相册
+ * \attention 需\ref apply_perm
+ * \param params 参数字典,字典的关键字参见TencentOAuthObject.h中的\ref TCAddAlbumDic
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)addAlbumWithParams:(NSMutableDictionary *)params;
+
+/**
+ * 检查是否是QZone某个用户的粉丝
+ * \param params 参数字典,字典的关键字参见TencentOAuthObject.h中的\ref TCCheckPageFansDic
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)checkPageFansWithParams:(NSMutableDictionary *)params;
+
+/**
+ * 在QZone中发表一篇日志
+ * \attention 需\ref apply_perm
+ * \param params 参数字典,字典的关键字参见TencentOAuthObject.h中的\ref TCAddOneBlogDic
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)addOneBlogWithParams:(NSMutableDictionary *)params;
+
+/**
+ * 在QZone中发表一条说说
+ * \attention 需\ref apply_perm
+ * \param params 参数字典,字典的关键字参见TencentOAuthObject.h中的\ref TCAddTopicDic
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)addTopicWithParams:(NSMutableDictionary *)params;
+
+/**
+ * 设置QQ头像 使用默认的效果处理设置头像的界面
+ * \attention 需\ref apply_perm
+ * \param params 参数字典,字典的关键字参见TencentOAuthObject.h中的\ref TCSetUserHeadpic
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)setUserHeadpic:(NSMutableDictionary *)params;
+
+
+/**
+ * 设置QQ头像 会返回设置头像由第三方自己处理界面的弹出方式
+ * \attention 需\ref apply_perm
+ * \param params 参数字典,字典的关键字参见TencentOAuthObject.h中的\ref TCSetUserHeadpic
+ * \param viewController 设置头像的界面
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)setUserHeadpic:(NSMutableDictionary *)params andViewController:(UIViewController **)viewController;
+
+/**
+ * 获取QQ会员信息(仅包括是否为QQ会员,是否为年费QQ会员)
+ * \attention 需\ref apply_perm
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)getVipInfo;
+
+/**
+ * 获取QQ会员详细信息
+ * \attention 需\ref apply_perm
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)getVipRichInfo;
+
+/**
+ * QZone定向分享,可以@到具体好友,完成后将触发responseDidReceived:forMessage:回调,message:“SendStory”
+ * \param params 参数字典
+ * \param fopenIdArray 第三方应用预传人好友列表,好友以openid标识
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)sendStory:(NSMutableDictionary *)params friendList:(NSArray *)fopenIdArray;
+
+/**
+ * 发送应用邀请,完成后将触发responseDidReceived:forMessage:回调,message:“AppInvitation”
+ * \param desc 应用的描述文字,不超过35字符,如果为nil或@“”则显示默认描述
+ * \param imageUrl 应用的图标,如果为nil或者@“”则显示默认图标
+ * \param source 透传参数,由开发者自定义该参数内容
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)sendAppInvitationWithDescription:(NSString *)desc imageURL:(NSString *)imageUrl source:(NSString *)source;
+
+/**
+ * 发起PK或者发送炫耀,完成后将触发responseDidReceived:forMessage:回调,message:“AppChallenge”
+ * \param receiver 必须指定一位进行PK或者炫耀的好友,填写其OpenID,填写多个OpenID将截取第一个
+ * \param type 类型,"pk"或者“brag”
+ * \param imageUrl 炫耀/挑战场景图的URL
+ * \param message 炫耀/挑战中的内容描述,不超过50个字符,超过限制则自动截断
+ * \param source 透传参数,由开发者自定义该参数内容
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)sendChallenge:(NSString *)receiver type:(NSString *)type imageURL:(NSString *)imageUrl message:(NSString *)message source:(NSString *)source;
+
+/**
+ * 赠送或者请求礼物,完成后将触发responseDidReceived:forMessage:回调,message:“AppGiftRequest”
+ * \param receiver 赠送或者请求礼物的好友的OpenID,支持填写多个,OpenID之用","分隔,为nil时将由用户通过好友选择器选择好友
+ * \param exclude 用户通过好友选择器选择好友场景下,希望排除的好友(不显示在好友选择器)
+ * \param specified 用户通过好友选择器选择好友场景下,希望出现的指定好友
+ * \param only 是否只显示specified指定的好友
+ * \param type 类型,"request"或者“freegift”
+ * \param title 免费礼物或请求名称,不超过6个字符
+ * \param message 礼物或请求的默认赠言,控制在35个汉字以内,超过限制自动截断
+ * \param imageUrl 请求或礼物配图的URL,如果不传,则默认在弹框中显示应用的icon
+ * \param source 透传参数,由开发者自定义该参数内容
+ * \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
+ */
+- (BOOL)sendGiftRequest:(NSString *)receiver exclude:(NSString *)exclude specified:(NSString *)specified only:(BOOL)only type:(NSString *)type title:(NSString *)title message:(NSString *)message imageURL:(NSString *)imageUrl source:(NSString *)source;
+
+
+/**
+ * 退出指定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;
+
+@end
+
+#pragma mark - TencentSessionDelegate(开放接口回调协议)
+
+/**
+ * \brief TencentSessionDelegate iOS Open SDK 1.3 API回调协议
+ *
+ * 第三方应用需要实现每条需要调用的API的回调协议
+ */
+@protocol TencentSessionDelegate<NSObject, TencentLoginDelegate,
+ TencentApiInterfaceDelegate,
+ 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;
+
+
+/**
+ * 获取用户QZone相册列表回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/getListAlbumResponse.exp success
+ * 错误返回示例: \snippet example/getListAlbumResponse.exp fail
+ */
+- (void)getListAlbumResponse:(APIResponse*) response;
+
+/**
+ * 获取用户QZone相片列表
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/getListPhotoResponse.exp success
+ * 错误返回示例: \snippet example/getListPhotoResponse.exp fail
+ */
+- (void)getListPhotoResponse:(APIResponse*) response;
+
+/**
+ * 检查是否是QZone某个用户的粉丝回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/checkPageFansResponse.exp success
+ * 错误返回示例: \snippet example/checkPageFansResponse.exp fail
+ */
+- (void)checkPageFansResponse:(APIResponse*) response;
+
+/**
+ * 分享到QZone回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/addShareResponse.exp success
+ * 错误返回示例: \snippet example/addShareResponse.exp fail
+ */
+- (void)addShareResponse:(APIResponse*) response;
+
+/**
+ * 在QZone相册中创建一个新的相册回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/addAlbumResponse.exp success
+ * 错误返回示例: \snippet example/addAlbumResponse.exp fail
+ */
+- (void)addAlbumResponse:(APIResponse*) response;
+
+/**
+ * 上传照片到QZone指定相册回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/uploadPicResponse.exp success
+ * 错误返回示例: \snippet example/uploadPicResponse.exp fail
+ */
+- (void)uploadPicResponse:(APIResponse*) response;
+
+
+/**
+ * 在QZone中发表一篇日志回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/addOneBlogResponse.exp success
+ * 错误返回示例: \snippet example/addOneBlogResponse.exp fail
+ */
+- (void)addOneBlogResponse:(APIResponse*) response;
+
+/**
+ * 在QZone中发表一条说说回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/addTopicResponse.exp success
+ * 错误返回示例: \snippet example/addTopicResponse.exp fail
+ */
+- (void)addTopicResponse:(APIResponse*) response;
+
+/**
+ * 设置QQ头像回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/setUserHeadpicResponse.exp success
+ * 错误返回示例: \snippet example/setUserHeadpicResponse.exp fail
+ */
+- (void)setUserHeadpicResponse:(APIResponse*) response;
+
+/**
+ * 获取QQ会员信息回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \remarks 正确返回示例: \snippet example/getVipInfoResponse.exp success
+ * 错误返回示例: \snippet example/getVipInfoResponse.exp fail
+ */
+- (void)getVipInfoResponse:(APIResponse*) response;
+
+/**
+ * 获取QQ会员详细信息回调
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ */
+- (void)getVipRichInfoResponse:(APIResponse*) response;
+
+/**
+ * sendStory分享的回调(已废弃,使用responseDidReceived:forMessage:)
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ */
+- (void)sendStoryResponse:(APIResponse*) response;
+
+
+/**
+ * 社交API统一回调接口
+ * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
+ * \param message 响应的消息,目前支持‘SendStory’,‘AppInvitation’,‘AppChallenge’,‘AppGiftRequest’
+ */
+- (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
--- /dev/null
+///
+/// \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 = 1;GIF = 2;PNG = 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_nm,lbs_x,lbs_y通常一起使用,来明确标识一个地址。
+ */
+@property (nonatomic, retain) TCOptionalStr paramLbs_nm;
+
+/**
+ * 经度。-180.0到+180.0,+表示东经。lbs_nm,lbs_x,lbs_y通常一起使用,来明确标识一个地址。
+ */
+@property (nonatomic, retain) TCOptionalStr paramLbs_x;
+
+/**
+ * 纬度。-90.0到+90.0,+表示北纬。lbs_nm,lbs_x,lbs_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表示PC,1表示手机。用于当不传相册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
+ * \note(0:不发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
--- /dev/null
+///
+/// \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;
+
+/**
+ * \brief 手机qq的当前版本
+ */
+typedef enum QQVersion
+{
+ kQQUninstall,
+ kQQVersion3_0,
+ kQQVersion4_0, //支持sso登陆
+ kQQVersion4_2_1, //ios7兼容
+ kQQVersion4_5, //4.5版本,wpa会话
+ kQQVersion4_6, //4.6版本,sso登陆信令通道切换
+ kQQVersion4_7, //4.7版本 不确定新支持了什么样的属性
+} QQVersion;
+
+
+/**
+ * \breif TIM的当前版本
+ */
+typedef enum TIMVersion {
+ kTIMUinstall,
+ kTIMVersion1_1,
+}TIMVersion;
+
+/**
+ * \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_ONE_BLOG;
+
+/** 创建一个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;
+
+/** 同步分享到QQ空间、腾讯微博 */
+FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_ADD_SHARE;
+
+/** 验证是否认证空间粉丝 */
+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
+
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="X-UA-Compatible" content="IE=Edge">
+<meta charset="UTF-8">
+<title>社交渠道</title>
+<meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale = 1.0,user-scalable=no" />
+<meta name="format-detection" content="telephone=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<style>
+*{margin:0;padding:0}
+.header{text-align:center;height:44px;background:-webkit-gradient(linear,0 0,0 100%,from(#4c4c4c),to(#313131));border-top:#5b5b5b 1px solid;position:relative;line-height:44px}
+.header h1{color:#fff;font-weight:bold;font-size:20px}
+.header a{width:49px;height:29px;background-size:49px 29px;position:absolute;top:7px;display:block;text-indent:-999em;cursor:pointer}
+.header .back{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEkAAAAsCAYAAAApSpU1AAAFgElEQVR42u2bSWgsRRjH40XEg3rwIujBg6KCp4CH7AnZ933f9z0hK7kk8RCEhCwEMTmID81C8JIVQRJEfGQ5PEwOnpKDh+T0nomCGngolvUrpsaeYWbSnel5ODOv4Jfp/mrpqv9UffV1TyciwqYUGRn5keRjydeS7yWPgogfJOuSVsnrEXYn2ei7ku+Sk5NFZWWlaG1tFd3d3aK/vz9o6OnpES0tLaKoqEjIsfwu6bNToDzJbU1NjRgbGxPDw8NiYGAgqATSDA4OitHRUXXsEGvJDoEqJX8zcxCG2dPR0SHa2tqCkvb2dtHZ2Sl6e3vFyMiIKCwsRKgufwTKlTxFIKYqF2G6Njc3Bz2MA7EQTY7xRvLafQR6X/JHY2OjaoxGm5qaQgrEYlXk5OQgVJtVgV6W/FRRUaEEorFQE8goVFlZGSI9sCrS5wUFBaKrq0s1wmwKZZgMcsz7VgQqyszMVA4apRsaGkKe8vJyRHpoVqA3JL/U1dUpH4TKz0VyFegFybfEDuxmVK6vrw8LHD7JlEjdubm5aktEIGZTuFBaWnq3SLLAB0TUennV1taGFSUlJb5FkpkvcvNHQRw1lbj9CCfMiPQJy4ytngrV1dXPDEKMxcVFsbe390yv605xcbF3kWRGDPdlCMQMqqqq8gsCz5ubG7G7u+tiRwhscHJyIi4uLlQ5nW5vb8XU1JTXOlagntV+O250H3oS6BXJz3h2nBeFeQTiL4hA4lPb6DxCIA6Qh21jY0OJ46kd8km6jhm4BvWs9tlxk+tRpAcsMxw1BYk67eL4+Fh1Wp/TceO5GbRIVupwDepZ7a9HkaShOC0tTTlqBCKYshtCCX28s7Mjrq6uxMLCgld4bGGsTx2SlWsiEvWs9pVbMBeRHFH1NQqyxFhugUYP2FeijKc6+hwBPCXsxjLu7ZghPz//P5F0VJ2Xl6d2MgoQSNnF0NCQmJ+fd6LteiYZ8zQHBwdqsMbyug5Jn5+fn6tlbKzLOXZjGepZ7Td6GEXqycrKUo4agYgP7GR7e9vlW3a3M4i5uTmnnftDnC12b23pc8pgcy9jrOupjBmcIsk/bxFVs8RYh3YLdNcAr6+v1Sfp6OhICXR2dqZEYgb+X0RiqW2mpKSoDAKoQKEHqM8RCBvH6+vrShidODfThhbAvQx2X2XMwC5vXG6vSs5TU1NVABUo9AA5np2dVceTk5POfGaSTswmdllfbQACaBE02mYsg91qfx2Pb112tw8lf+KbiA8CwdbWlhogx3qpcYxQl5eXKm9tbU3BrMJGnrc2YH9/3ymKEey6DOfUs9rf7Oxsj3FSdVxcnIoPAoEeIMd0fHV11WlDsImJCWdZjhEKu7c2zKJFstpfJoy3iPvThIQEFSPYDd8uaXx83GnTQhHhu5fnh8Ll5WUXmxbJynW1SFb760skHpEcJSUlKe9uB319feL09FQNTn+ylDY3N50g1szMjEeor9ui7H0S9az2m2f6vp4CvCl5zI6Hh/eXpaUl1dGVlRV1Pj09LQ4PD112M1+J8rotLRI2s+gvxGq/MzIy7nyelMTjEtTEy/sLnfWV5wv3sgzYyrX5cnxd3xvp6emmHt+OxsbGKi8fjpgVSQWa7Hg4sXCDJyJmfy1RgWZiYqJyZOEEwbWVHydVoMmLWjizcIGNy7RIDqGqoqOjn4tkQqjPYmJilEMLB1g5ll6YcIj0kuRHHDlOLdTBD8vxfnGfl7jekfzGrUuoi8SqkWNtue/rgASaT1GaHSAU4bZMjvEJP7H5895kueSv+Ph45eBCjaioKERqsuMN3HTeeyYqDxVxmEEOgebtfJf7bcmu5B9CBJw6syvYoN8OcX7lPwMiApFkw+9JhiRfSb5h6wwyvpQ0evJB/wIFDhaTvqlwnwAAAABJRU5ErkJggg==);left:5px}
+</style>
+</head>
+<body>
+<div class="container" id="container">
+ <div class="header">
+ <h1 id="title"></h1>
+ <a href="javascript:void(0)" class="back" id="cancel">返回</a>
+ <a href="javascript:void(0)" style="display:none" id="confirm"></a>
+ </div>
+ <div id="main"></div>
+</div>
+<script>
+(function () {
+ try {
+ document.domain = "qq.com";
+ } catch (_) {
+ alert("invalid domain");
+ }
+ function getParam(name) {
+ var re = new RegExp("(?:\\?|#|&)" + name + "=([^&]*)(?:$|&|#)", "i"), m = re.exec(window.location.href);
+ var ret = m ? m[1] : "";
+ ret = ret.replace(/[+]/ig, "%20");
+ return ret;
+ }
+ var iface = getParam("iface");
+ switch (iface) {
+ case "AppChallenge":
+ case "AppInvitation":
+ case "AppGiftRequest":
+ case "SendStory": {
+ var appid = getParam("oauth_consumer_key"), type = getParam("type");
+ var url = "tencent" + appid + "://" + iface + "/cancel";
+ document.getElementById("cancel").addEventListener("click", function () {
+ setTimeout(function () {
+ window.open(url, "_self");
+ }, 0);
+ }, false);
+ document.getElementById("title").innerHTML = {
+ AppChallenge : type == "pk" ? "发送挑战" : "发送炫耀",
+ AppInvitation : "发送应用邀请",
+ AppGiftRequest : type == "request" ? "发送应用请求" : "发送免费礼物",
+ SendStory : "发送分享"
+ }[iface];
+ document.write('<script type="text/javascript" src="https://qzonestyle.gtimg.cn/open/mobile/' + {
+ AppChallenge : "brag_ios/js/sdk_brag.js",
+ AppInvitation : "invite_ios/js/sdk_invite.js",
+ AppGiftRequest : "request_ios/js/sdk_request.js",
+ SendStory : "story_ios/js/sdk_story.js"
+ }[iface] + '"><\/script>');
+ break;
+ }
+ default:
+ return;
+ }
+})();
+</script>
+</body>
+</html>
--- /dev/null
+
+var cordova = require('cordova');
+module.exports = {
+ Scene: {
+ QQ: 0, // QQ 好友
+ QQZone: 1, // QQ 空间
+ Favorite: 2 // 收藏
+ },
+ ClientType: {
+ QQ: 0, // QQ 手机客户端
+ TIM: 1 // TIM 客户端
+ },
+ ssoLogin:function(successCallback, errorCallback, args){
+ if(args === undefined) {
+ args = {}
+ }
+ cordova.exec(successCallback, errorCallback, "QQSDK", "ssoLogin",[args]);
+ },
+ logout:function(successCallback, errorCallback){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "logout", []);
+ },
+ checkClientInstalled:function(successCallback, errorCallback, args){
+ if(args === undefined) {
+ args = {}
+ }
+ cordova.exec(successCallback, errorCallback, "QQSDK", "checkClientInstalled", [args]);
+ },
+ shareText:function(successCallback, errorCallback, args){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "shareText", [args]);
+ },
+ shareImage:function(successCallback, errorCallback, args){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "shareImage", [args]);
+ },
+ shareNews:function(successCallback, errorCallback, args){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "shareNews", [args]);
+ },
+ shareAudio:function(successCallback, errorCallback, args){
+ cordova.exec(successCallback, errorCallback, "QQSDK", "shareAudio", [args]);
+ },
+};
},
"is_top_level": true,
"variables": {}
+ },
+ "cordova-plugin-qqsdk": {
+ "source": {
+ "type": "registry",
+ "id": "cordova-plugin-qqsdk"
+ },
+ "is_top_level": true,
+ "variables": {
+ "QQ_APP_ID": "101885581"
+ }
}
}
\ No newline at end of file
},
"cordova-plugin-prevent-screenshot-coffice": {
"PACKAGE_NAME": "$(PRODUCT_BUNDLE_IDENTIFIER)"
+ },
+ "cordova-plugin-qqsdk": {
+ "QQ_APP_ID": "101885581",
+ "PACKAGE_NAME": "$(PRODUCT_BUNDLE_IDENTIFIER)"
}
},
"dependent_plugins": {
<i class="aui-iconfont aui-icon-cert aui-text-info"></i>
</div>
<div class="aui-list-item-inner aui-list-item-arrow">
- <div class="aui-list-item-title">市民卡</div>
+ <div class="aui-list-item-title">银行卡</div>
<div class="aui-list-item-right" id="userbank"></div>
</div>
</li>
</div>
</li>
</ul>
+ <div id="wocao" style="background-color: red;">wo an</div>
</section>
</body>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/server.js"></script>
<script type="text/javascript" src="js/main.js"></script>
<script type="text/javascript">
+ var share = document.getElementById("wocao")
+ share.onclick=function(){
+ var args = {};
+ args.client = QQSDK.ClientType.QQ;//QQSDK.ClientType.QQ,QQSDK.ClientType.TIM;
+ args.scene = QQSDK.Scene.QQ;//QQSDK.Scene.QQZone,QQSDK.Scene.Favorite
+ args.url = 'https://cordova.apache.org/';
+ args.title = '这个是 Cordova QQ 新闻分享的标题';
+ args.description = '这个是 Cordova QQ 新闻分享的描述';
+ args.image = 'https://cordova.apache.org/static/img/cordova_bot.png';
+ QQSDK.shareNews(function () {
+ alert('shareNews success');
+ }, function (failReason) {
+ alert(failReason);
+ }, args);
+ }
</script>
</html>
\ No newline at end of file