mirror of
https://github.com/RxReader/tencent_kit.git
synced 2025-05-29 06:03:32 +08:00
tencent_kit
This commit is contained in:
31
.drone.yml
31
.drone.yml
@ -3,7 +3,7 @@ name: default
|
||||
|
||||
steps:
|
||||
- name: prepare
|
||||
image: v7lin/flutter:1.7.8-hotfix.3-stable
|
||||
image: v7lin/flutter:1.9.1-hotfix.6-stable
|
||||
volumes:
|
||||
- name: pub-cache
|
||||
path: /opt/flutter/.pub-cache
|
||||
@ -11,15 +11,26 @@ steps:
|
||||
- flutter packages get
|
||||
|
||||
#- name: build_runner
|
||||
# image: v7lin/flutter:1.7.8-hotfix.3-stable
|
||||
# image: v7lin/flutter:1.9.1-hotfix.6-stable
|
||||
# volumes:
|
||||
# - name: pub-cache
|
||||
# path: /opt/flutter/.pub-cache
|
||||
# commands:
|
||||
# - flutter packages pub run build_runner build
|
||||
# - flutter packages pub run build_runner build --delete-conflicting-outputs
|
||||
|
||||
- name: android-check
|
||||
image: v7lin/flutter:1.9.1-hotfix.6-stable
|
||||
volumes:
|
||||
- name: pub-cache
|
||||
path: /opt/flutter/.pub-cache
|
||||
- name: gradle
|
||||
path: /root/.gradle
|
||||
commands:
|
||||
- cd example/android/
|
||||
- ./gradlew :tencent_kit:check
|
||||
|
||||
- name: format
|
||||
image: v7lin/flutter:1.7.8-hotfix.3-stable
|
||||
image: v7lin/flutter:1.9.1-hotfix.6-stable
|
||||
volumes:
|
||||
- name: pub-cache
|
||||
path: /opt/flutter/.pub-cache
|
||||
@ -27,7 +38,7 @@ steps:
|
||||
- flutter format --dry-run --set-exit-if-changed .
|
||||
|
||||
- name: analyze
|
||||
image: v7lin/flutter:1.7.8-hotfix.3-stable
|
||||
image: v7lin/flutter:1.9.1-hotfix.6-stable
|
||||
volumes:
|
||||
- name: pub-cache
|
||||
path: /opt/flutter/.pub-cache
|
||||
@ -35,17 +46,17 @@ steps:
|
||||
- flutter analyze
|
||||
|
||||
- name: test
|
||||
image: v7lin/flutter:1.7.8-hotfix.3-stable
|
||||
image: v7lin/flutter:1.9.1-hotfix.6-stable
|
||||
volumes:
|
||||
- name: pub-cache
|
||||
path: /opt/flutter/.pub-cache
|
||||
commands:
|
||||
- flutter test --coverage
|
||||
- flutter test
|
||||
- cd example/
|
||||
- flutter test
|
||||
|
||||
- name: proguard
|
||||
image: v7lin/flutter:1.7.8-hotfix.3-stable
|
||||
image: v7lin/flutter:1.9.1-hotfix.6-stable
|
||||
volumes:
|
||||
- name: pub-cache
|
||||
path: /opt/flutter/.pub-cache
|
||||
@ -68,7 +79,7 @@ steps:
|
||||
- pull_request
|
||||
|
||||
- name: publish-check
|
||||
image: v7lin/flutter:1.7.8-hotfix.3-stable
|
||||
image: v7lin/flutter:1.9.1-hotfix.6-stable
|
||||
volumes:
|
||||
- name: pub-cache
|
||||
path: /opt/flutter/.pub-cache
|
||||
@ -111,7 +122,7 @@ steps:
|
||||
- rm $FLUTTER_HOME/credentials.json.enc
|
||||
|
||||
- name: publish
|
||||
image: v7lin/flutter:1.7.8-hotfix.3-stable
|
||||
image: v7lin/flutter:1.9.1-hotfix.6-stable
|
||||
volumes:
|
||||
- name: pub-cache
|
||||
path: /opt/flutter/.pub-cache
|
||||
|
5
.gitignore
vendored
5
.gitignore
vendored
@ -3,9 +3,10 @@
|
||||
|
||||
.packages
|
||||
.pub/
|
||||
pubspec.lock
|
||||
|
||||
build/
|
||||
|
||||
.idea/
|
||||
*.iml
|
||||
|
||||
.idea/
|
||||
pubspec.lock
|
@ -4,7 +4,7 @@
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: 5391447fae6209bb21a89e6a5a6583cac1af9b4b
|
||||
revision: 68587a0916366e9512a78df22c44163d041dd5f3
|
||||
channel: stable
|
||||
|
||||
project_type: plugin
|
||||
|
@ -1,3 +1,11 @@
|
||||
## 1.0.0 - 2019.11.14
|
||||
|
||||
* 更名 tencent_kit
|
||||
* 升级 Android/iOS SDK
|
||||
* 添加 Android 代码静态检查
|
||||
* 获取用户信息改走API接口
|
||||
* 新增获取UnionId功能
|
||||
|
||||
## 0.3.4 - 2019.9.10
|
||||
|
||||
* gradle兼容
|
||||
|
45
README.md
45
README.md
@ -1,14 +1,14 @@
|
||||
# fake_tencent
|
||||
# tencent_kit
|
||||
|
||||
[](https://cloud.drone.io/v7lin/fake_tencent)
|
||||
[](https://codecov.io/gh/v7lin/fake_tencent)
|
||||
[](https://github.com/v7lin/fake_tencent/releases)
|
||||
[](https://pub.dartlang.org/packages/fake_tencent)
|
||||
[](https://pub.dartlang.org/packages/tencent_kit)
|
||||
[](https://github.com/v7lin/fake_tencent/blob/master/LICENSE)
|
||||
|
||||
flutter版腾讯(QQ)SDK
|
||||
|
||||
## fake 系列 libraries
|
||||
## flutter toolkit
|
||||
|
||||
* [flutter版微信SDK](https://github.com/v7lin/fake_wechat)
|
||||
* [flutter版腾讯(QQ)SDK](https://github.com/v7lin/fake_tencent)
|
||||
@ -25,10 +25,11 @@ flutter版腾讯(QQ)SDK
|
||||
|
||||
* [腾讯开放平台](https://open.tencent.com/)
|
||||
* [QQ互联](http://wiki.connect.qq.com/)
|
||||
* [Universal Links](https://developer.apple.com/library/archive/documentation/General/Conceptual/AppSearch/UniversalLinks.html)
|
||||
|
||||
## android
|
||||
|
||||
````
|
||||
```
|
||||
...
|
||||
android {
|
||||
...
|
||||
@ -40,22 +41,22 @@ android {
|
||||
...
|
||||
}
|
||||
...
|
||||
````
|
||||
```
|
||||
|
||||
````
|
||||
```
|
||||
# 混淆已打入 Library,随 Library 引用,自动添加到 apk 打包混淆
|
||||
````
|
||||
```
|
||||
|
||||
## ios
|
||||
|
||||
````
|
||||
```
|
||||
在Xcode中,选择你的工程设置项,选中“TARGETS”一栏,在“info”标签栏的“URL type“添加“URL scheme”为你所注册的应用程序id
|
||||
|
||||
URL Types
|
||||
tencent: identifier=tencent schemes=tencent${appId}
|
||||
````
|
||||
```
|
||||
|
||||
````
|
||||
```
|
||||
iOS 9系统策略更新,限制了http协议的访问,此外应用需要在“Info.plist”中将要使用的URL Schemes列为白名单,才可正常检查其他应用是否安装。
|
||||
|
||||
<key>LSApplicationQueriesSchemes</key>
|
||||
@ -72,7 +73,13 @@ iOS 9系统策略更新,限制了http协议的访问,此外应用需要在
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
````
|
||||
```
|
||||
|
||||
```
|
||||
Universal Links
|
||||
|
||||
Capabilities -> Associated Domain -> Domain -> applinks:${your applinks}
|
||||
```
|
||||
|
||||
## flutter
|
||||
|
||||
@ -83,19 +90,19 @@ iOS 9系统策略更新,限制了http协议的访问,此外应用需要在
|
||||
|
||||
* snapshot
|
||||
|
||||
````
|
||||
```
|
||||
dependencies:
|
||||
fake_tencent:
|
||||
tencent_kit:
|
||||
git:
|
||||
url: https://github.com/v7lin/fake_tencent.git
|
||||
````
|
||||
```
|
||||
|
||||
* release
|
||||
|
||||
````
|
||||
```
|
||||
dependencies:
|
||||
fake_tencent: ^${latestTag}
|
||||
````
|
||||
tencent_kit: ^${latestTag}
|
||||
```
|
||||
|
||||
* example
|
||||
|
||||
@ -104,10 +111,10 @@ dependencies:
|
||||
## Getting Started
|
||||
|
||||
This project is a starting point for a Flutter
|
||||
[plug-in package](https://flutter.io/developing-packages/),
|
||||
[plug-in package](https://flutter.dev/developing-packages/),
|
||||
a specialized package that includes platform-specific implementation code for
|
||||
Android and/or iOS.
|
||||
|
||||
For help getting started with Flutter, view our
|
||||
[online documentation](https://flutter.io/docs), which offers tutorials,
|
||||
[online documentation](https://flutter.dev/docs), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
||||
|
@ -19,114 +19,117 @@ analyzer:
|
||||
# 'super_goes_last' is a deprecated lint rule and should not be used • included_file_warning
|
||||
included_file_warning: ignore
|
||||
|
||||
# 过滤 jaguar_serializer
|
||||
# 过滤 json_serializable
|
||||
exclude:
|
||||
- "**/*.jser.dart"
|
||||
- "**/*.g.dart"
|
||||
|
||||
linter:
|
||||
rules:
|
||||
# these rules are documented on and in the same order as
|
||||
# the Dart Lint rules page to make maintenance easier
|
||||
# http://dart-lang.github.io/linter/lints/
|
||||
# these rules are documented on and in the same order as
|
||||
# the Dart Lint rules page to make maintenance easier
|
||||
# http://dart-lang.github.io/linter/lints/
|
||||
|
||||
# === error rules ===
|
||||
- avoid_empty_else
|
||||
- avoid_slow_async_io
|
||||
- cancel_subscriptions
|
||||
# - close_sinks # https://github.com/flutter/flutter/issues/5789
|
||||
# - comment_references # blocked on https://github.com/dart-lang/dartdoc/issues/1153
|
||||
- control_flow_in_finally
|
||||
- empty_statements
|
||||
- hash_and_equals
|
||||
# - invariant_booleans # https://github.com/flutter/flutter/issues/5790
|
||||
- iterable_contains_unrelated_type
|
||||
- list_remove_unrelated_type
|
||||
# - literal_only_boolean_expressions # https://github.com/flutter/flutter/issues/5791
|
||||
- no_adjacent_strings_in_list
|
||||
- no_duplicate_case_values
|
||||
- test_types_in_equals
|
||||
- throw_in_finally
|
||||
- unrelated_type_equality_checks
|
||||
- valid_regexps
|
||||
# === error rules ===
|
||||
- avoid_empty_else
|
||||
- avoid_slow_async_io
|
||||
- cancel_subscriptions
|
||||
# - close_sinks # https://github.com/flutter/flutter/issues/5789
|
||||
# - comment_references # blocked on https://github.com/dart-lang/dartdoc/issues/1153
|
||||
- control_flow_in_finally
|
||||
- empty_statements
|
||||
- hash_and_equals
|
||||
# - invariant_booleans # https://github.com/flutter/flutter/issues/5790
|
||||
- iterable_contains_unrelated_type
|
||||
- list_remove_unrelated_type
|
||||
# - literal_only_boolean_expressions # https://github.com/flutter/flutter/issues/5791
|
||||
- no_adjacent_strings_in_list
|
||||
- no_duplicate_case_values
|
||||
- test_types_in_equals
|
||||
- throw_in_finally
|
||||
- unrelated_type_equality_checks
|
||||
- valid_regexps
|
||||
|
||||
# === style rules ===
|
||||
- always_declare_return_types
|
||||
# - always_put_control_body_on_new_line
|
||||
- always_require_non_null_named_parameters
|
||||
- always_specify_types
|
||||
- annotate_overrides
|
||||
# - avoid_annotating_with_dynamic # not yet tested
|
||||
# - avoid_as # 2019-01-30 removed for no-implicit-casts
|
||||
# - avoid_catches_without_on_clauses # not yet tested
|
||||
# - avoid_catching_errors # not yet tested
|
||||
# - avoid_classes_with_only_static_members # not yet tested
|
||||
# - avoid_function_literals_in_foreach_calls # not yet tested
|
||||
- avoid_init_to_null
|
||||
- avoid_null_checks_in_equality_operators
|
||||
# - avoid_positional_boolean_parameters # not yet tested
|
||||
- avoid_return_types_on_setters
|
||||
# - avoid_returning_null # not yet tested
|
||||
# - avoid_returning_this # not yet tested
|
||||
# - avoid_setters_without_getters # not yet tested
|
||||
# - avoid_types_on_closure_parameters # not yet tested
|
||||
- await_only_futures
|
||||
- camel_case_types
|
||||
# - cascade_invocations # not yet tested
|
||||
# - constant_identifier_names # https://github.com/dart-lang/linter/issues/204
|
||||
- directives_ordering
|
||||
- empty_catches
|
||||
- empty_constructor_bodies
|
||||
- implementation_imports
|
||||
# - join_return_with_assignment # not yet tested
|
||||
- library_names
|
||||
- library_prefixes
|
||||
- non_constant_identifier_names
|
||||
# - omit_local_variable_types # opposite of always_specify_types
|
||||
# - one_member_abstracts # too many false positives
|
||||
# - only_throw_errors # https://github.com/flutter/flutter/issues/5792
|
||||
- overridden_fields
|
||||
- package_api_docs
|
||||
- package_prefixed_library_names
|
||||
# - parameter_assignments # we do this commonly
|
||||
- prefer_adjacent_string_concatenation
|
||||
- prefer_collection_literals
|
||||
# - prefer_conditional_assignment # not yet tested
|
||||
- prefer_const_constructors
|
||||
# - prefer_constructors_over_static_methods # not yet tested
|
||||
- prefer_contains
|
||||
- prefer_equal_for_default_values
|
||||
# - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods
|
||||
# - prefer_final_fields # https://github.com/dart-lang/linter/issues/506
|
||||
# - prefer_final_locals
|
||||
# - prefer_foreach # not yet tested
|
||||
# - prefer_function_declarations_over_variables # not yet tested
|
||||
- prefer_initializing_formals
|
||||
# - prefer_interpolation_to_compose_strings # not yet tested
|
||||
- prefer_is_empty
|
||||
- prefer_is_not_empty
|
||||
- prefer_void_to_null
|
||||
# - recursive_getters # https://github.com/dart-lang/linter/issues/452
|
||||
- slash_for_doc_comments
|
||||
- sort_constructors_first
|
||||
- sort_unnamed_constructors_first
|
||||
# - super_goes_last
|
||||
# - type_annotate_public_apis # subset of always_specify_types
|
||||
- type_init_formals
|
||||
# - unawaited_futures # https://github.com/flutter/flutter/issues/5793
|
||||
- unnecessary_brace_in_string_interps
|
||||
- unnecessary_const
|
||||
- unnecessary_getters_setters
|
||||
# - unnecessary_lambdas # https://github.com/dart-lang/linter/issues/498
|
||||
- unnecessary_new
|
||||
- unnecessary_null_aware_assignments
|
||||
- unnecessary_null_in_if_null_operators
|
||||
# - unnecessary_overrides # https://github.com/dart-lang/linter/issues/626 and https://github.com/dart-lang/linter/issues/627
|
||||
- unnecessary_statements
|
||||
- unnecessary_this
|
||||
- use_rethrow_when_possible
|
||||
# - use_setters_to_change_properties # not yet tested
|
||||
# - use_string_buffers # https://github.com/dart-lang/linter/pull/664
|
||||
# - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review
|
||||
# === style rules ===
|
||||
- always_declare_return_types
|
||||
# - always_put_control_body_on_new_line
|
||||
- always_require_non_null_named_parameters
|
||||
- always_specify_types
|
||||
- annotate_overrides
|
||||
# - avoid_annotating_with_dynamic # not yet tested
|
||||
# - avoid_as # 2019-01-30 removed for no-implicit-casts
|
||||
# - avoid_catches_without_on_clauses # not yet tested
|
||||
# - avoid_catching_errors # not yet tested
|
||||
# - avoid_classes_with_only_static_members # not yet tested
|
||||
# - avoid_function_literals_in_foreach_calls # not yet tested
|
||||
- avoid_init_to_null
|
||||
- avoid_null_checks_in_equality_operators
|
||||
# - avoid_positional_boolean_parameters # not yet tested
|
||||
- avoid_return_types_on_setters
|
||||
# - avoid_returning_null # not yet tested
|
||||
# - avoid_returning_this # not yet tested
|
||||
# - avoid_setters_without_getters # not yet tested
|
||||
# - avoid_types_on_closure_parameters # not yet tested
|
||||
- await_only_futures
|
||||
- camel_case_types
|
||||
# - cascade_invocations # not yet tested
|
||||
# - constant_identifier_names # https://github.com/dart-lang/linter/issues/204
|
||||
- directives_ordering
|
||||
- empty_catches
|
||||
- empty_constructor_bodies
|
||||
- implementation_imports
|
||||
# - join_return_with_assignment # not yet tested
|
||||
- library_names
|
||||
- library_prefixes
|
||||
- non_constant_identifier_names
|
||||
# - omit_local_variable_types # opposite of always_specify_types
|
||||
# - one_member_abstracts # too many false positives
|
||||
# - only_throw_errors # https://github.com/flutter/flutter/issues/5792
|
||||
- overridden_fields
|
||||
- package_api_docs
|
||||
- package_prefixed_library_names
|
||||
# - parameter_assignments # we do this commonly
|
||||
- prefer_adjacent_string_concatenation
|
||||
- prefer_collection_literals
|
||||
# - prefer_conditional_assignment # not yet tested
|
||||
- prefer_const_constructors
|
||||
# - prefer_constructors_over_static_methods # not yet tested
|
||||
- prefer_contains
|
||||
- prefer_equal_for_default_values
|
||||
# - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods
|
||||
# - prefer_final_fields # https://github.com/dart-lang/linter/issues/506
|
||||
# - prefer_final_locals
|
||||
# - prefer_foreach # not yet tested
|
||||
# - prefer_function_declarations_over_variables # not yet tested
|
||||
- prefer_initializing_formals
|
||||
# - prefer_interpolation_to_compose_strings # not yet tested
|
||||
- prefer_is_empty
|
||||
- prefer_is_not_empty
|
||||
- prefer_void_to_null
|
||||
# - recursive_getters # https://github.com/dart-lang/linter/issues/452
|
||||
- slash_for_doc_comments
|
||||
- sort_constructors_first
|
||||
- sort_unnamed_constructors_first
|
||||
# - super_goes_last
|
||||
# - type_annotate_public_apis # subset of always_specify_types
|
||||
- type_init_formals
|
||||
# - unawaited_futures # https://github.com/flutter/flutter/issues/5793
|
||||
- unnecessary_brace_in_string_interps
|
||||
- unnecessary_const
|
||||
- unnecessary_getters_setters
|
||||
# - unnecessary_lambdas # https://github.com/dart-lang/linter/issues/498
|
||||
- unnecessary_new
|
||||
- unnecessary_null_aware_assignments
|
||||
- unnecessary_null_in_if_null_operators
|
||||
# - unnecessary_overrides # https://github.com/dart-lang/linter/issues/626 and https://github.com/dart-lang/linter/issues/627
|
||||
- unnecessary_statements
|
||||
- unnecessary_this
|
||||
- use_rethrow_when_possible
|
||||
# - use_setters_to_change_properties # not yet tested
|
||||
# - use_string_buffers # https://github.com/dart-lang/linter/pull/664
|
||||
# - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review
|
||||
|
||||
# === pub rules ===
|
||||
- package_names
|
||||
# === pub rules ===
|
||||
- package_names
|
||||
|
||||
# === doc rules ===
|
||||
# - public_member_api_docs
|
||||
|
@ -1,5 +1,5 @@
|
||||
group 'io.github.v7lin.faketencent'
|
||||
version '1.0-SNAPSHOT'
|
||||
group 'io.github.v7lin.tencent_kit'
|
||||
version '1.0.0'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
@ -8,7 +8,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath 'com.android.tools.build:gradle:3.5.2'
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,13 +20,18 @@ rootProject.allprojects {
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply from: './quality.gradle'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
|
||||
// library 混淆 -> 随 library 引用,自动添加到 apk 打包混淆
|
||||
consumerProguardFiles 'consumer-proguard-rules.pro'
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
@ -36,5 +41,5 @@ android {
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
|
||||
implementation 'io.github.v7lin:tencent-android:3.3.3+3'
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
}
|
||||
|
135
android/checkstyle.xml
Normal file
135
android/checkstyle.xml
Normal file
@ -0,0 +1,135 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
||||
"http://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd">
|
||||
|
||||
<module name="Checker">
|
||||
<!--module name="NewlineAtEndOfFile"/-->
|
||||
<module name="FileLength"/>
|
||||
<module name="FileTabCharacter"/>
|
||||
|
||||
<!-- Trailing spaces -->
|
||||
<module name="RegexpSingleline">
|
||||
<property name="format" value="\s+$"/>
|
||||
<property name="message" value="Line has trailing spaces."/>
|
||||
</module>
|
||||
|
||||
<!-- Space after 'for' and 'if' -->
|
||||
<module name="RegexpSingleline">
|
||||
<property name="format" value="^\s*(for|if)[^ ]\("/>
|
||||
<property name="message" value="Space needed before opening parenthesis."/>
|
||||
</module>
|
||||
|
||||
<!-- For each spacing -->
|
||||
<module name="RegexpSingleline">
|
||||
<property name="format" value="^\s*for \(.*?([^ ]:|:[^ ])"/>
|
||||
<property name="message" value="Space needed around ':' character."/>
|
||||
</module>
|
||||
|
||||
<module name="TreeWalker">
|
||||
<!--<property name="cacheFile" value="${checkstyle.cache.file}"/>-->
|
||||
|
||||
<!-- Checks for Javadoc comments. -->
|
||||
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
|
||||
<!--module name="JavadocMethod"/-->
|
||||
<!--module name="JavadocType"/-->
|
||||
<!--module name="JavadocVariable"/-->
|
||||
<!--module name="JavadocStyle"/-->
|
||||
|
||||
|
||||
<!-- Checks for Naming Conventions. -->
|
||||
<!-- See http://checkstyle.sf.net/config_naming.html -->
|
||||
<!--<module name="ConstantName"/>-->
|
||||
<module name="LocalFinalVariableName"/>
|
||||
<module name="LocalVariableName"/>
|
||||
<module name="MemberName"/>
|
||||
<module name="MethodName">
|
||||
<property name="format" value="^[a-z][a-zA-Z0-9_]*$"/>
|
||||
</module>
|
||||
<module name="PackageName"/>
|
||||
<module name="ParameterName"/>
|
||||
<module name="StaticVariableName"/>
|
||||
<module name="TypeName"/>
|
||||
|
||||
|
||||
<!-- Checks for imports -->
|
||||
<!-- See http://checkstyle.sf.net/config_import.html -->
|
||||
<module name="AvoidStarImport"/>
|
||||
<module name="IllegalImport"/>
|
||||
<module name="RedundantImport"/>
|
||||
<module name="UnusedImports">
|
||||
<property name="processJavadoc" value="true"/>
|
||||
</module>
|
||||
|
||||
|
||||
<!-- Checks for Size Violations. -->
|
||||
<!-- See http://checkstyle.sf.net/config_sizes.html -->
|
||||
<module name="LineLength">
|
||||
<property name="max" value="200"/>
|
||||
</module>
|
||||
<module name="MethodLength"/>
|
||||
<!--module name="ParameterNumber"/-->
|
||||
|
||||
|
||||
<!-- Checks for whitespace -->
|
||||
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
|
||||
<module name="GenericWhitespace"/>
|
||||
<module name="EmptyForIteratorPad"/>
|
||||
<module name="MethodParamPad"/>
|
||||
<!--<module name="NoWhitespaceAfter"/>-->
|
||||
<module name="NoWhitespaceBefore"/>
|
||||
<module name="OperatorWrap"/>
|
||||
<module name="ParenPad"/>
|
||||
<module name="TypecastParenPad"/>
|
||||
<module name="WhitespaceAfter"/>
|
||||
<module name="WhitespaceAround"/>
|
||||
|
||||
|
||||
<!-- Modifier Checks -->
|
||||
<!-- See http://checkstyle.sf.net/config_modifiers.html -->
|
||||
<module name="ModifierOrder"/>
|
||||
<module name="RedundantModifier"/>
|
||||
|
||||
|
||||
<!-- Checks for blocks. You know, those {}'s -->
|
||||
<!-- See http://checkstyle.sf.net/config_blocks.html -->
|
||||
<!--module name="AvoidNestedBlocks"/-->
|
||||
<!--module name="EmptyBlock"/-->
|
||||
<module name="LeftCurly"/>
|
||||
<!--module name="NeedBraces"/-->
|
||||
<module name="RightCurly"/>
|
||||
|
||||
|
||||
<!-- Checks for common coding problems -->
|
||||
<!-- See http://checkstyle.sf.net/config_coding.html -->
|
||||
<!--module name="AvoidInlineConditionals"/-->
|
||||
<module name="CovariantEquals"/>
|
||||
<module name="EmptyStatement"/>
|
||||
<!--<module name="EqualsAvoidNull"/>-->
|
||||
<module name="EqualsHashCode"/>
|
||||
<!--module name="HiddenField"/-->
|
||||
<module name="IllegalInstantiation"/>
|
||||
<!--<module name="InnerAssignment"/>-->
|
||||
<!--module name="MagicNumber"/-->
|
||||
<module name="MissingSwitchDefault"/>
|
||||
<!--<module name="RedundantThrows"/>-->
|
||||
<module name="SimplifyBooleanExpression"/>
|
||||
<module name="SimplifyBooleanReturn"/>
|
||||
|
||||
<!-- Checks for class design -->
|
||||
<!-- See http://checkstyle.sf.net/config_design.html -->
|
||||
<!--module name="DesignForExtension"/-->
|
||||
<!--module name="FinalClass"/-->
|
||||
<!--module name="HideUtilityClassConstructor"/-->
|
||||
<!--module name="InterfaceIsType"/-->
|
||||
<!--module name="VisibilityModifier"/-->
|
||||
|
||||
|
||||
<!-- Miscellaneous other checks. -->
|
||||
<!-- See http://checkstyle.sf.net/config_misc.html -->
|
||||
<!--module name="ArrayTypeStyle"/-->
|
||||
<!--module name="FinalParameters"/-->
|
||||
<!--module name="TodoComment"/-->
|
||||
<module name="UpperEll"/>
|
||||
</module>
|
||||
</module>
|
3
android/consumer-proguard-rules.pro
Normal file
3
android/consumer-proguard-rules.pro
Normal file
@ -0,0 +1,3 @@
|
||||
# --- open_sdk ---
|
||||
|
||||
-keep class com.tencent.** {*;}
|
@ -1 +1,5 @@
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
android.enableR8=true
|
||||
|
BIN
android/libs/open_sdk_r6199_lite.jar
Normal file
BIN
android/libs/open_sdk_r6199_lite.jar
Normal file
Binary file not shown.
17
android/quality.gradle
Normal file
17
android/quality.gradle
Normal file
@ -0,0 +1,17 @@
|
||||
apply plugin: 'checkstyle'
|
||||
|
||||
check.dependsOn 'checkstyle'
|
||||
|
||||
checkstyle {
|
||||
// toolVersion = "6.15"
|
||||
}
|
||||
|
||||
task checkstyle(type: Checkstyle) {
|
||||
configFile project.file('checkstyle.xml')
|
||||
source 'src/main/java'
|
||||
ignoreFailures false
|
||||
showViolations true
|
||||
include '**/*.java'
|
||||
|
||||
classpath = files()
|
||||
}
|
@ -1 +1 @@
|
||||
rootProject.name = 'fake_tencent'
|
||||
rootProject.name = 'tencent_kit'
|
||||
|
@ -1,3 +1,34 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="io.github.v7lin.faketencent">
|
||||
package="io.github.v7lin.tencent_kit">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<!--<uses-permission android:name="android.permission.WRITE_APN_SETTINGS"/>-->
|
||||
|
||||
<application android:usesCleartextTraffic="true">
|
||||
<uses-library
|
||||
android:name="org.apache.http.legacy"
|
||||
android:required="false" />
|
||||
|
||||
<activity
|
||||
android:name="com.tencent.tauth.AuthActivity"
|
||||
android:launchMode="singleTask"
|
||||
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="tencent${TENCENT_APP_ID}" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.tencent.connect.common.AssistActivity"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:screenOrientation="behind"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
@ -1,4 +1,4 @@
|
||||
package io.github.v7lin.faketencent;
|
||||
package io.github.v7lin.tencent_kit;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
@ -7,7 +7,8 @@ import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.tencent.connect.UserInfo;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.tencent.connect.common.Constants;
|
||||
import com.tencent.connect.share.QQShare;
|
||||
import com.tencent.connect.share.QzonePublish;
|
||||
@ -21,7 +22,6 @@ import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -33,55 +33,49 @@ import io.flutter.plugin.common.PluginRegistry;
|
||||
import io.flutter.plugin.common.PluginRegistry.Registrar;
|
||||
|
||||
/**
|
||||
* FakeTencentPlugin
|
||||
* TencentKitPlugin
|
||||
*/
|
||||
public class FakeTencentPlugin implements MethodCallHandler, PluginRegistry.ActivityResultListener {
|
||||
public class TencentKitPlugin implements MethodCallHandler, PluginRegistry.ActivityResultListener {
|
||||
/**
|
||||
* Plugin registration.
|
||||
*/
|
||||
public static void registerWith(Registrar registrar) {
|
||||
final MethodChannel channel = new MethodChannel(registrar.messenger(), "v7lin.github.io/fake_tencent");
|
||||
FakeTencentPlugin plugin = new FakeTencentPlugin(registrar, channel);
|
||||
final MethodChannel channel = new MethodChannel(registrar.messenger(), "v7lin.github.io/tencent_kit");
|
||||
TencentKitPlugin plugin = new TencentKitPlugin(registrar, channel);
|
||||
registrar.addActivityResultListener(plugin);
|
||||
channel.setMethodCallHandler(plugin);
|
||||
}
|
||||
|
||||
private static class TencentScene {
|
||||
public static final int SCENE_QQ = 0;
|
||||
public static final int SCENE_QZONE = 1;
|
||||
static final int SCENE_QQ = 0;
|
||||
static final int SCENE_QZONE = 1;
|
||||
}
|
||||
|
||||
private static class TencentRetCode {
|
||||
// 网络请求成功发送至服务器,并且服务器返回数据格式正确
|
||||
// 这里包括所请求业务操作失败的情况,例如没有授权等原因导致
|
||||
public static final int RET_SUCCESS = 0;
|
||||
static final int RET_SUCCESS = 0;
|
||||
// 网络异常,或服务器返回的数据格式不正确导致无法解析
|
||||
public static final int RET_FAILED = 1;
|
||||
public static final int RET_COMMON = -1;
|
||||
public static final int RET_USERCANCEL = -2;
|
||||
static final int RET_FAILED = 1;
|
||||
static final int RET_COMMON = -1;
|
||||
static final int RET_USERCANCEL = -2;
|
||||
}
|
||||
|
||||
private static final String METHOD_REGISTERAPP = "registerApp";
|
||||
private static final String METHOD_ISQQINSTALLED = "isQQInstalled";
|
||||
private static final String METHOD_ISQQSUPPORTSSOLOGIN = "isQQSupportSSOLogin";
|
||||
private static final String METHOD_ISINSTALLED = "isInstalled";
|
||||
private static final String METHOD_LOGIN = "login";
|
||||
private static final String METHOD_LOGOUT = "logout";
|
||||
private static final String METHOD_GETUSERINFO = "getUserInfo";
|
||||
private static final String METHOD_SHAREMOOD = "shareMood";
|
||||
private static final String METHOD_SHAREIMAGE = "shareImage";
|
||||
private static final String METHOD_SHAREMUSIC = "shareMusic";
|
||||
private static final String METHOD_SHAREWEBPAGE = "shareWebpage";
|
||||
|
||||
private static final String METHOD_ONLOGINRESP = "onLoginResp";
|
||||
private static final String METHOD_ONGETUSERINFORESP = "onGetUserInfoResp";
|
||||
private static final String METHOD_ONSHARERESP = "onShareResp";
|
||||
|
||||
private static final String ARGUMENT_KEY_APPID = "appId";
|
||||
// private static final String ARGUMENT_KEY_UNIVERSALLINK = "universalLink";
|
||||
private static final String ARGUMENT_KEY_SCOPE = "scope";
|
||||
private static final String ARGUMENT_KEY_OPENID = "openId";
|
||||
private static final String ARGUMENT_KEY_ACCESSTOKEN = "accessToken";
|
||||
private static final String ARGUMENT_KEY_EXPIRESIN = "expiresIn";
|
||||
private static final String ARGUMENT_KEY_CREATEAT = "createAt";
|
||||
private static final String ARGUMENT_KEY_SCENE = "scene";
|
||||
private static final String ARGUMENT_KEY_TITLE = "title";
|
||||
private static final String ARGUMENT_KEY_SUMMARY = "summary";
|
||||
@ -107,34 +101,31 @@ public class FakeTencentPlugin implements MethodCallHandler, PluginRegistry.Acti
|
||||
|
||||
private Tencent tencent;
|
||||
|
||||
private FakeTencentPlugin(Registrar registrar, MethodChannel channel) {
|
||||
private TencentKitPlugin(Registrar registrar, MethodChannel channel) {
|
||||
this.registrar = registrar;
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMethodCall(MethodCall call, Result result) {
|
||||
public void onMethodCall(MethodCall call, @NonNull Result result) {
|
||||
if (METHOD_REGISTERAPP.equals(call.method)) {
|
||||
String appId = call.argument(ARGUMENT_KEY_APPID);
|
||||
final String appId = call.argument(ARGUMENT_KEY_APPID);
|
||||
// final String universalLink = call.argument(ARGUMENT_KEY_UNIVERSALLINK);
|
||||
tencent = Tencent.createInstance(appId, registrar.context().getApplicationContext());
|
||||
result.success(null);
|
||||
} else if (METHOD_ISQQINSTALLED.equals(call.method)) {
|
||||
} else if (METHOD_ISINSTALLED.equals(call.method)) {
|
||||
boolean isQQInstalled = false;
|
||||
try {
|
||||
final PackageManager packageManager = registrar.context().getPackageManager();
|
||||
PackageInfo info = packageManager.getPackageInfo("com.tencent.mobileqq", PackageManager.GET_SIGNATURES);
|
||||
PackageInfo info = packageManager.getPackageInfo("com.tencent.mobileqq", 0);
|
||||
isQQInstalled = info != null;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
} catch (PackageManager.NameNotFoundException ignore) {
|
||||
}
|
||||
result.success(isQQInstalled);
|
||||
} else if (METHOD_ISQQSUPPORTSSOLOGIN.equals(call.method)) {
|
||||
result.success(tencent.isSupportSSOLogin(registrar.activity()));
|
||||
} else if (METHOD_LOGIN.equals(call.method)) {
|
||||
login(call, result);
|
||||
} else if (METHOD_LOGOUT.equals(call.method)) {
|
||||
logout(call, result);
|
||||
} else if (METHOD_GETUSERINFO.equals(call.method)) {
|
||||
getUserInfo(call, result);
|
||||
} else if (METHOD_SHAREMOOD.equals(call.method)) {
|
||||
shareMood(call, result);
|
||||
} else if (METHOD_SHAREIMAGE.equals(call.method)) {
|
||||
@ -217,62 +208,6 @@ public class FakeTencentPlugin implements MethodCallHandler, PluginRegistry.Acti
|
||||
}
|
||||
}
|
||||
|
||||
private void getUserInfo(MethodCall call, Result result) {
|
||||
if (tencent != null) {
|
||||
String openId = call.argument(ARGUMENT_KEY_OPENID);
|
||||
tencent.setOpenId(openId);
|
||||
String accessToken = call.argument(ARGUMENT_KEY_ACCESSTOKEN);
|
||||
int expiresIn = call.argument(ARGUMENT_KEY_EXPIRESIN);
|
||||
long createAt = call.argument(ARGUMENT_KEY_CREATEAT);
|
||||
tencent.setAccessToken(accessToken, String.valueOf(expiresIn - (System.currentTimeMillis() - createAt) / 1000));
|
||||
UserInfo info = new UserInfo(registrar.context().getApplicationContext(), tencent.getQQToken());
|
||||
info.getUserInfo(userInfoListener);
|
||||
}
|
||||
result.success(null);
|
||||
}
|
||||
|
||||
private IUiListener userInfoListener = new IUiListener() {
|
||||
@Override
|
||||
public void onComplete(Object o) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
try {
|
||||
if (o != null && o instanceof JSONObject) {
|
||||
JSONObject object = (JSONObject) o;
|
||||
int ret = !object.isNull(ARGUMENT_KEY_RESULT_RET) ? object.getInt(ARGUMENT_KEY_RESULT_RET) : TencentRetCode.RET_FAILED;
|
||||
String msg = !object.isNull(ARGUMENT_KEY_RESULT_MSG) ? object.getString(ARGUMENT_KEY_RESULT_MSG) : null;
|
||||
if (ret == TencentRetCode.RET_SUCCESS) {
|
||||
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_SUCCESS);
|
||||
Iterator<String> keys = object.keys();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
map.put(key, object.get(key));
|
||||
}
|
||||
} else {
|
||||
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_COMMON);
|
||||
map.put(ARGUMENT_KEY_RESULT_MSG, msg);
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_COMMON);
|
||||
map.put(ARGUMENT_KEY_RESULT_MSG, e.getMessage());
|
||||
}
|
||||
channel.invokeMethod(METHOD_ONGETUSERINFORESP, map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(UiError error) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_COMMON);
|
||||
map.put(ARGUMENT_KEY_RESULT_MSG, error.errorMessage);
|
||||
channel.invokeMethod(METHOD_ONGETUSERINFORESP, map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
// do nothing
|
||||
}
|
||||
};
|
||||
|
||||
private void shareMood(MethodCall call, Result result) {
|
||||
if (tencent != null) {
|
||||
int scene = call.argument(ARGUMENT_KEY_SCENE);
|
||||
@ -416,6 +351,8 @@ public class FakeTencentPlugin implements MethodCallHandler, PluginRegistry.Acti
|
||||
params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL, targetUrl);
|
||||
tencent.shareToQzone(registrar.activity(), params, shareListener);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
result.success(null);
|
||||
@ -465,23 +402,12 @@ public class FakeTencentPlugin implements MethodCallHandler, PluginRegistry.Acti
|
||||
@Override
|
||||
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
switch (requestCode) {
|
||||
case Constants.REQUEST_API:
|
||||
// unused
|
||||
break;
|
||||
case Constants.REQUEST_LOGIN:
|
||||
return Tencent.onActivityResultData(requestCode, resultCode, data, loginListener);
|
||||
case Constants.REQUEST_QQ_SHARE:
|
||||
return Tencent.onActivityResultData(requestCode, resultCode, data, shareListener);
|
||||
case Constants.REQUEST_QZONE_SHARE:
|
||||
return Tencent.onActivityResultData(requestCode, resultCode, data, shareListener);
|
||||
case Constants.REQUEST_QQ_FAVORITES:
|
||||
// unused
|
||||
break;
|
||||
case Constants.REQUEST_SEND_TO_MY_COMPUTER:
|
||||
// unused
|
||||
break;
|
||||
case Constants.REQUEST_SHARE_TO_TROOP_BAR:
|
||||
// unused
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
12
example/.gitignore
vendored
12
example/.gitignore
vendored
@ -1,6 +1,5 @@
|
||||
# Miscellaneous
|
||||
*.class
|
||||
*.lock
|
||||
*.log
|
||||
*.pyc
|
||||
*.swp
|
||||
@ -16,8 +15,10 @@
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
# Visual Studio Code related
|
||||
.vscode/
|
||||
# The .vscode folder contains launch configuration and tasks you configure in
|
||||
# VS Code which you may wish to be included in version control, so this line
|
||||
# is commented out by default.
|
||||
#.vscode/
|
||||
|
||||
# Flutter/Dart/Pub related
|
||||
**/doc/api/
|
||||
@ -26,7 +27,7 @@
|
||||
.packages
|
||||
.pub-cache/
|
||||
.pub/
|
||||
build/
|
||||
/build/
|
||||
|
||||
# Android related
|
||||
**/android/**/gradle-wrapper.jar
|
||||
@ -60,10 +61,9 @@ build/
|
||||
**/ios/Flutter/app.flx
|
||||
**/ios/Flutter/app.zip
|
||||
**/ios/Flutter/flutter_assets/
|
||||
**/ios/Flutter/flutter_export_environment.sh
|
||||
**/ios/ServiceDefinitions.json
|
||||
**/ios/Runner/GeneratedPluginRegistrant.*
|
||||
**/ios/Frameworks/
|
||||
**/ios/Runner.xcworkspace/xcshareddata/
|
||||
|
||||
# Exceptions to above rules.
|
||||
!**/ios/**/default.mode1v3
|
||||
|
@ -4,7 +4,7 @@
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: 5391447fae6209bb21a89e6a5a6583cac1af9b4b
|
||||
revision: 68587a0916366e9512a78df22c44163d041dd5f3
|
||||
channel: stable
|
||||
|
||||
project_type: app
|
||||
|
@ -1,6 +1,6 @@
|
||||
# fake_tencent_example
|
||||
# tencent_kit_example
|
||||
|
||||
Demonstrates how to use the fake_tencent plugin.
|
||||
Demonstrates how to use the tencent_kit plugin.
|
||||
|
||||
## Getting Started
|
||||
|
||||
@ -8,9 +8,9 @@ This project is a starting point for a Flutter application.
|
||||
|
||||
A few resources to get you started if this is your first Flutter project:
|
||||
|
||||
- [Lab: Write your first Flutter app](https://flutter.io/docs/get-started/codelab)
|
||||
- [Cookbook: Useful Flutter samples](https://flutter.io/docs/cookbook)
|
||||
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
|
||||
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
|
||||
|
||||
For help getting started with Flutter, view our
|
||||
[online documentation](https://flutter.io/docs), which offers tutorials,
|
||||
For help getting started with Flutter, view our
|
||||
[online documentation](https://flutter.dev/docs), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
||||
|
@ -10,23 +10,31 @@ analyzer:
|
||||
|
||||
linter:
|
||||
rules:
|
||||
- iterable_contains_unrelated_type
|
||||
- list_remove_unrelated_type
|
||||
- test_types_in_equals
|
||||
- unrelated_type_equality_checks
|
||||
- valid_regexps
|
||||
- annotate_overrides
|
||||
- hash_and_equals
|
||||
- prefer_is_not_empty
|
||||
- avoid_empty_else
|
||||
- cancel_subscriptions
|
||||
- close_sinks
|
||||
- always_declare_return_types
|
||||
- camel_case_types
|
||||
- empty_constructor_bodies
|
||||
- avoid_init_to_null
|
||||
# - constant_identifier_names
|
||||
- one_member_abstracts
|
||||
- slash_for_doc_comments
|
||||
- sort_constructors_first
|
||||
- unnecessary_new
|
||||
- iterable_contains_unrelated_type
|
||||
- list_remove_unrelated_type
|
||||
- test_types_in_equals
|
||||
- unrelated_type_equality_checks
|
||||
- valid_regexps
|
||||
- annotate_overrides
|
||||
- hash_and_equals
|
||||
- prefer_is_not_empty
|
||||
- avoid_empty_else
|
||||
- cancel_subscriptions
|
||||
- close_sinks
|
||||
- always_declare_return_types
|
||||
- camel_case_types
|
||||
- empty_constructor_bodies
|
||||
- avoid_init_to_null
|
||||
# - constant_identifier_names
|
||||
- one_member_abstracts
|
||||
- slash_for_doc_comments
|
||||
- sort_constructors_first
|
||||
- unnecessary_brace_in_string_interps
|
||||
|
||||
# === doc rules ===
|
||||
# - public_member_api_docs
|
||||
|
||||
# ignore specify types
|
||||
# - always_specify_types
|
||||
# ignore const for now
|
||||
# - prefer_const_constructors
|
||||
|
@ -33,7 +33,7 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId "io.github.v7lin.faketencentexample"
|
||||
applicationId "com.tencent.sample"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 28
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
@ -41,7 +41,13 @@ android {
|
||||
|
||||
manifestPlaceholders = [TENCENT_APP_ID: "222222"]
|
||||
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
debug {
|
||||
storeFile file('debug.keystore')
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
@ -51,7 +57,6 @@ android {
|
||||
signingConfig signingConfigs.debug
|
||||
|
||||
minifyEnabled true
|
||||
useProguard true
|
||||
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
@ -64,6 +69,6 @@ flutter {
|
||||
|
||||
dependencies {
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||
androidTestImplementation 'androidx.test:runner:1.1.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
||||
}
|
||||
|
BIN
example/android/app/debug.keystore
Normal file
BIN
example/android/app/debug.keystore
Normal file
Binary file not shown.
5
example/android/app/proguard-rules.pro
vendored
5
example/android/app/proguard-rules.pro
vendored
@ -1,8 +1,9 @@
|
||||
#Flutter Wrapper
|
||||
# Flutter Wrapper
|
||||
|
||||
-keep class io.flutter.app.** { *; }
|
||||
-keep class io.flutter.plugin.** { *; }
|
||||
-keep class io.flutter.util.** { *; }
|
||||
-keep class io.flutter.view.** { *; }
|
||||
-keep class io.flutter.** { *; }
|
||||
-keep class io.flutter.plugins.** { *; }
|
||||
-dontwarn io.flutter.**
|
||||
-dontwarn io.flutter.**
|
||||
|
7
example/android/app/src/debug/AndroidManifest.xml
Normal file
7
example/android/app/src/debug/AndroidManifest.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="io.github.v7lin.tencent_kit_example">
|
||||
<!-- Flutter needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
@ -1,11 +1,5 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="io.github.v7lin.faketencentexample">
|
||||
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
flutter needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
package="io.github.v7lin.tencent_kit_example">
|
||||
|
||||
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
||||
calls FlutterMain.startInitialization(this); in its onCreate method.
|
||||
@ -14,13 +8,13 @@
|
||||
FlutterApplication and put your custom class here. -->
|
||||
<application
|
||||
android:name="io.flutter.app.FlutterApplication"
|
||||
android:label="fake_tencent_example"
|
||||
android:label="tencent_kit_example"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- This keeps the window background of the activity showing
|
||||
|
@ -1,4 +1,4 @@
|
||||
package io.github.v7lin.faketencentexample;
|
||||
package io.github.v7lin.tencent_kit_example;
|
||||
|
||||
import android.os.Bundle;
|
||||
import io.flutter.app.FlutterActivity;
|
7
example/android/app/src/profile/AndroidManifest.xml
Normal file
7
example/android/app/src/profile/AndroidManifest.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="io.github.v7lin.tencent_kit_example">
|
||||
<!-- Flutter needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
5
example/android/app/src/release/AndroidManifest.xml
Normal file
5
example/android/app/src/release/AndroidManifest.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="io.github.v7lin.tencent_kit_example">
|
||||
<!-- network request -->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
@ -5,7 +5,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.0'
|
||||
classpath 'com.android.tools.build:gradle:3.5.2'
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1 +1,5 @@
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
android.enableR8=true
|
||||
|
@ -1,4 +1,4 @@
|
||||
#Tue Sep 10 20:41:08 CST 2019
|
||||
#Wed Nov 06 18:22:26 CST 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 190 KiB |
@ -3,7 +3,7 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>App</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
|
@ -41,7 +41,7 @@ target 'Runner' do
|
||||
# Flutter Pods
|
||||
generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig')
|
||||
if generated_xcode_build_settings.empty?
|
||||
puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first."
|
||||
puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first."
|
||||
end
|
||||
generated_xcode_build_settings.map { |p|
|
||||
if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
|
||||
@ -60,6 +60,9 @@ target 'Runner' do
|
||||
}
|
||||
end
|
||||
|
||||
# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
|
||||
install! 'cocoapods', :disable_input_output_paths => true
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
target.build_configurations.each do |config|
|
||||
|
28
example/ios/Podfile.lock
Normal file
28
example/ios/Podfile.lock
Normal file
@ -0,0 +1,28 @@
|
||||
PODS:
|
||||
- Flutter (1.0.0)
|
||||
- path_provider (0.0.1):
|
||||
- Flutter
|
||||
- tencent_kit (1.0.0):
|
||||
- Flutter
|
||||
|
||||
DEPENDENCIES:
|
||||
- Flutter (from `.symlinks/flutter/ios`)
|
||||
- path_provider (from `.symlinks/plugins/path_provider/ios`)
|
||||
- tencent_kit (from `.symlinks/plugins/tencent_kit/ios`)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
Flutter:
|
||||
:path: ".symlinks/flutter/ios"
|
||||
path_provider:
|
||||
:path: ".symlinks/plugins/path_provider/ios"
|
||||
tencent_kit:
|
||||
:path: ".symlinks/plugins/tencent_kit/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
|
||||
path_provider: fb74bd0465e96b594bb3b5088ee4a4e7bb1f2a9d
|
||||
tencent_kit: ef18a7780c8d8503b448f7d8f25b48abd2706e11
|
||||
|
||||
PODFILE CHECKSUM: 7fb83752f59ead6285236625b82473f90b1cb932
|
||||
|
||||
COCOAPODS: 1.8.0
|
@ -11,7 +11,7 @@
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
|
||||
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
9422253582A6C9D275F8D188 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EC2B9EE613E5EDCF95CDB72B /* libPods-Runner.a */; };
|
||||
6CE270E48E48FA2184491F5B /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22AA494CBAC5718A9A5B59FE /* libPods-Runner.a */; };
|
||||
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
|
||||
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
|
||||
@ -40,8 +40,11 @@
|
||||
/* Begin PBXFileReference section */
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||
22AA494CBAC5718A9A5B59FE /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
34BDC42E441A1D281667DFB2 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
|
||||
6E97E3F72373BCD2002BA53E /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
@ -54,7 +57,8 @@
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
EC2B9EE613E5EDCF95CDB72B /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C01AB4EEE4214A456A0AED3C /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
C907325B6974A5E7E013AA51 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -64,18 +68,21 @@
|
||||
files = (
|
||||
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
|
||||
3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
|
||||
9422253582A6C9D275F8D188 /* libPods-Runner.a in Frameworks */,
|
||||
6CE270E48E48FA2184491F5B /* libPods-Runner.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
5C6AC5BA9442E9AF04E7447D /* Pods */ = {
|
||||
15DE2C788FC69000FD6D9F20 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C907325B6974A5E7E013AA51 /* Pods-Runner.debug.xcconfig */,
|
||||
C01AB4EEE4214A456A0AED3C /* Pods-Runner.release.xcconfig */,
|
||||
34BDC42E441A1D281667DFB2 /* Pods-Runner.profile.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||
@ -97,8 +104,8 @@
|
||||
9740EEB11CF90186004384FC /* Flutter */,
|
||||
97C146F01CF9000F007C117D /* Runner */,
|
||||
97C146EF1CF9000F007C117D /* Products */,
|
||||
5C6AC5BA9442E9AF04E7447D /* Pods */,
|
||||
D579DE886E1BD687DF6DBF83 /* Frameworks */,
|
||||
15DE2C788FC69000FD6D9F20 /* Pods */,
|
||||
D53051BB3AA8D8CE3C0019AC /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@ -113,6 +120,7 @@
|
||||
97C146F01CF9000F007C117D /* Runner */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6E97E3F72373BCD2002BA53E /* Runner.entitlements */,
|
||||
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
|
||||
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
|
||||
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
||||
@ -134,10 +142,10 @@
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D579DE886E1BD687DF6DBF83 /* Frameworks */ = {
|
||||
D53051BB3AA8D8CE3C0019AC /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EC2B9EE613E5EDCF95CDB72B /* libPods-Runner.a */,
|
||||
22AA494CBAC5718A9A5B59FE /* libPods-Runner.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
@ -149,14 +157,14 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||
buildPhases = (
|
||||
0D238ADF129651F8319C4F7F /* [CP] Check Pods Manifest.lock */,
|
||||
3ACA0EBF42EA843298FCA536 /* [CP] Check Pods Manifest.lock */,
|
||||
9740EEB61CF901F6004384FC /* Run Script */,
|
||||
97C146EA1CF9000F007C117D /* Sources */,
|
||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||
97C146EC1CF9000F007C117D /* Resources */,
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||
7175A6E06323B12A711474E5 /* [CP] Embed Pods Frameworks */,
|
||||
44F7BC7464E022FF09A3806E /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@ -173,18 +181,19 @@
|
||||
97C146E61CF9000F007C117D /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0910;
|
||||
LastUpgradeCheck = 1020;
|
||||
ORGANIZATIONNAME = "The Chromium Authors";
|
||||
TargetAttributes = {
|
||||
97C146ED1CF9000F007C117D = {
|
||||
CreatedOnToolsVersion = 7.3.1;
|
||||
DevelopmentTeam = 78W43A3TE2;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
@ -216,16 +225,20 @@
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
0D238ADF129651F8319C4F7F /* [CP] Check Pods Manifest.lock */ = {
|
||||
3ACA0EBF42EA843298FCA536 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||
);
|
||||
@ -246,24 +259,21 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin\n";
|
||||
};
|
||||
7175A6E06323B12A711474E5 /* [CP] Embed Pods Frameworks */ = {
|
||||
44F7BC7464E022FF09A3806E /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
||||
"${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||
@ -278,7 +288,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
@ -329,12 +339,14 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
@ -368,6 +380,9 @@
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = 78W43A3TE2;
|
||||
ENABLE_BITCODE = NO;
|
||||
@ -381,8 +396,9 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.github.v7lin.fakeTencentExample;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.github.v7lin.tencentKitExample;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Profile;
|
||||
@ -401,12 +417,14 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
@ -455,12 +473,14 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
@ -494,6 +514,9 @@
|
||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = 78W43A3TE2;
|
||||
ENABLE_BITCODE = NO;
|
||||
@ -507,8 +530,9 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.github.v7lin.fakeTencentExample;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.github.v7lin.tencentKitExample;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Debug;
|
||||
@ -518,6 +542,9 @@
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = 78W43A3TE2;
|
||||
ENABLE_BITCODE = NO;
|
||||
@ -531,8 +558,9 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.github.v7lin.fakeTencentExample;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.github.v7lin.tencentKitExample;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Release;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0910"
|
||||
LastUpgradeVersion = "1020"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
@ -3,7 +3,7 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
@ -11,7 +11,7 @@
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>fake_tencent_example</string>
|
||||
<string>tencent_kit_example</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
|
@ -2,25 +2,12 @@ import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:fake_path_provider/fake_path_provider.dart';
|
||||
import 'package:fake_tencent/fake_tencent.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:path_provider/path_provider.dart' as path_provider;
|
||||
import 'package:tencent_kit/tencent_kit.dart';
|
||||
import 'package:okhttp_kit/okhttp_kit.dart';
|
||||
|
||||
void main() {
|
||||
runZoned(() {
|
||||
runApp(MyApp());
|
||||
}, onError: (Object error, StackTrace stack) {
|
||||
print(error);
|
||||
print(stack);
|
||||
});
|
||||
|
||||
if (Platform.isAndroid) {
|
||||
SystemUiOverlayStyle systemUiOverlayStyle =
|
||||
SystemUiOverlayStyle(statusBarColor: Colors.transparent);
|
||||
SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
|
||||
}
|
||||
}
|
||||
void main() => runApp(MyApp());
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
@override
|
||||
@ -44,7 +31,6 @@ class _HomeState extends State<Home> {
|
||||
Tencent _tencent = Tencent()..registerApp(appId: _TENCENT_APPID);
|
||||
|
||||
StreamSubscription<TencentLoginResp> _login;
|
||||
StreamSubscription<TencentUserInfoResp> _userInfo;
|
||||
StreamSubscription<TencentShareResp> _share;
|
||||
|
||||
TencentLoginResp _loginResp;
|
||||
@ -53,7 +39,6 @@ class _HomeState extends State<Home> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
_login = _tencent.loginResp().listen(_listenLogin);
|
||||
_userInfo = _tencent.userInfoResp().listen(_listenUserInfo);
|
||||
_share = _tencent.shareResp().listen(_listenShare);
|
||||
}
|
||||
|
||||
@ -63,11 +48,6 @@ class _HomeState extends State<Home> {
|
||||
_showTips('登录', content);
|
||||
}
|
||||
|
||||
void _listenUserInfo(TencentUserInfoResp resp) {
|
||||
String content = 'user info: ${resp.nickname} - ${resp.gender}';
|
||||
_showTips('用户', content);
|
||||
}
|
||||
|
||||
void _listenShare(TencentShareResp resp) {
|
||||
String content = 'share: ${resp.ret} - ${resp.msg}';
|
||||
_showTips('分享', content);
|
||||
@ -78,9 +58,6 @@ class _HomeState extends State<Home> {
|
||||
if (_login != null) {
|
||||
_login.cancel();
|
||||
}
|
||||
if (_userInfo != null) {
|
||||
_userInfo.cancel();
|
||||
}
|
||||
if (_share != null) {
|
||||
_share.cancel();
|
||||
}
|
||||
@ -91,15 +68,14 @@ class _HomeState extends State<Home> {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Fake Tencent Demo'),
|
||||
title: const Text('TencentKit Demo'),
|
||||
),
|
||||
body: ListView(
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
title: const Text('环境检查'),
|
||||
onTap: () async {
|
||||
String content =
|
||||
'tencent: ${await _tencent.isQQInstalled()} - ${await _tencent.isQQSupportSSOLogin()}';
|
||||
String content = 'tencent: ${await _tencent.isInstalled()}';
|
||||
_showTips('环境检查', content);
|
||||
},
|
||||
),
|
||||
@ -113,18 +89,39 @@ class _HomeState extends State<Home> {
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('获取用户信息'),
|
||||
onTap: () {
|
||||
onTap: () async {
|
||||
if (_loginResp != null &&
|
||||
_loginResp.ret == TencentResp.RET_SUCCESS) {
|
||||
if (DateTime.now().millisecondsSinceEpoch -
|
||||
_loginResp.createAt <
|
||||
_loginResp.expiresIn * 1000) {
|
||||
_tencent.getUserInfo(
|
||||
openId: _loginResp.openid,
|
||||
accessToken: _loginResp.accessToken,
|
||||
expiresIn: _loginResp.expiresIn,
|
||||
createAt: _loginResp.createAt,
|
||||
);
|
||||
_loginResp.isSuccessful() &&
|
||||
!_loginResp.isExpired()) {
|
||||
TencentUserInfoResp userInfo = await _tencent.getUserInfo(
|
||||
appId: _TENCENT_APPID,
|
||||
openid: _loginResp.openid,
|
||||
accessToken: _loginResp.accessToken,
|
||||
);
|
||||
if (userInfo.isSuccessful()) {
|
||||
_showTips('用户信息',
|
||||
'${userInfo.nickname} - ${userInfo.gender} - ${userInfo.genderType}');
|
||||
} else {
|
||||
_showTips('用户信息', '${userInfo.ret} - ${userInfo.msg}');
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('获取UnionID'),
|
||||
onTap: () async {
|
||||
if (_loginResp != null &&
|
||||
_loginResp.isSuccessful() &&
|
||||
!_loginResp.isExpired()) {
|
||||
TencentUnionidResp unionid = await _tencent.getUnionId(
|
||||
accessToken: _loginResp.accessToken,
|
||||
);
|
||||
if (unionid.isSuccessful()) {
|
||||
_showTips('UnionID',
|
||||
'${unionid.clientId} - ${unionid.openid} - ${unionid.unionid}');
|
||||
} else {
|
||||
_showTips('UnionID',
|
||||
'${unionid.error} - ${unionid.errorDescription}');
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -141,21 +138,31 @@ class _HomeState extends State<Home> {
|
||||
ListTile(
|
||||
title: const Text('图片分享'),
|
||||
onTap: () async {
|
||||
AssetImage image = const AssetImage('images/icon/timg.gif');
|
||||
AssetBundleImageKey key =
|
||||
await image.obtainKey(createLocalImageConfiguration(context));
|
||||
ByteData imageData = await key.bundle.load(key.name);
|
||||
Directory saveDir = await PathProvider.getDocumentsDirectory();
|
||||
File saveFile = File('${saveDir.path}${path.separator}timg.gif');
|
||||
if (!saveFile.existsSync()) {
|
||||
saveFile.createSync(recursive: true);
|
||||
saveFile.writeAsBytesSync(imageData.buffer.asUint8List(),
|
||||
flush: true);
|
||||
OkHttpClient client = OkHttpClientBuilder().build();
|
||||
Response resp = await client
|
||||
.newCall(RequestBuilder()
|
||||
.get()
|
||||
.url(HttpUrl.parse(
|
||||
'https://www.baidu.com/img/bd_logo1.png?where=super'))
|
||||
.build())
|
||||
.enqueue();
|
||||
if (resp.isSuccessful()) {
|
||||
Directory saveDir = Platform.isIOS
|
||||
? await path_provider.getApplicationDocumentsDirectory()
|
||||
: await path_provider.getExternalStorageDirectory();
|
||||
File saveFile = File(path.join(saveDir.path, 'timg.gif'));
|
||||
if (!saveFile.existsSync()) {
|
||||
saveFile.createSync(recursive: true);
|
||||
saveFile.writeAsBytesSync(
|
||||
await resp.body().bytes(),
|
||||
flush: true,
|
||||
);
|
||||
}
|
||||
await _tencent.shareImage(
|
||||
scene: TencentScene.SCENE_QQ,
|
||||
imageUri: Uri.file(saveFile.path),
|
||||
);
|
||||
}
|
||||
await _tencent.shareImage(
|
||||
scene: TencentScene.SCENE_QQ,
|
||||
imageUri: Uri.file(saveFile.path),
|
||||
);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
|
@ -1,5 +1,5 @@
|
||||
name: fake_tencent_example
|
||||
description: Demonstrates how to use the fake_tencent plugin.
|
||||
name: tencent_kit_example
|
||||
description: Demonstrates how to use the tencent_kit plugin.
|
||||
publish_to: 'none'
|
||||
|
||||
environment:
|
||||
@ -13,19 +13,20 @@ dependencies:
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^0.1.2
|
||||
|
||||
path: ^1.6.2
|
||||
fake_path_provider: ^0.0.1
|
||||
fake_tencent:
|
||||
path: ../
|
||||
path: ^1.6.4
|
||||
path_provider: ^1.4.0
|
||||
|
||||
okhttp_kit: ^1.0.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
pedantic: '>=1.4.0 <3.0.0'
|
||||
tencent_kit:
|
||||
path: ../
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://www.dartlang.org/tools/pub/pubspec
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
||||
# The following section is specific to Flutter.
|
||||
flutter:
|
||||
@ -36,14 +37,15 @@ flutter:
|
||||
uses-material-design: true
|
||||
|
||||
# To add assets to your application, add an assets section, like this:
|
||||
assets:
|
||||
- images/icon/timg.gif
|
||||
# assets:
|
||||
# - images/a_dot_burr.jpeg
|
||||
# - images/a_dot_ham.jpeg
|
||||
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.io/assets-and-images/#resolution-aware.
|
||||
# https://flutter.dev/assets-and-images/#resolution-aware.
|
||||
|
||||
# For details regarding adding assets from package dependencies, see
|
||||
# https://flutter.io/assets-and-images/#from-packages
|
||||
# https://flutter.dev/assets-and-images/#from-packages
|
||||
|
||||
# To add custom fonts to your application, add a fonts section here,
|
||||
# in this "flutter" section. Each entry in this list should have a
|
||||
@ -63,4 +65,4 @@ flutter:
|
||||
# weight: 700
|
||||
#
|
||||
# For details regarding fonts from package dependencies,
|
||||
# see https://flutter.io/custom-fonts/#from-packages
|
||||
# see https://flutter.dev/custom-fonts/#from-packages
|
||||
|
@ -5,4 +5,13 @@
|
||||
// gestures. You can also use WidgetTester to find child widgets in the widget
|
||||
// tree, read text, and verify that the values of widget properties are correct.
|
||||
|
||||
void main() {}
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:tencent_kit_example/main.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('smoke test', (WidgetTester tester) async {
|
||||
// Build our app and trigger a frame.
|
||||
await tester.pumpWidget(MyApp());
|
||||
});
|
||||
}
|
||||
|
1
ios/.gitignore
vendored
1
ios/.gitignore
vendored
@ -34,3 +34,4 @@ Icon?
|
||||
.tags*
|
||||
|
||||
/Flutter/Generated.xcconfig
|
||||
/Flutter/flutter_export_environment.sh
|
@ -1,4 +0,0 @@
|
||||
#import <Flutter/Flutter.h>
|
||||
|
||||
@interface FakeTencentPlugin : NSObject<FlutterPlugin>
|
||||
@end
|
@ -1,334 +0,0 @@
|
||||
#import "FakeTencentPlugin.h"
|
||||
#import <TencentOpenAPI/TencentOAuth.h>
|
||||
#import <TencentOpenAPI/QQApiInterface.h>
|
||||
|
||||
@interface FakeTencentPlugin () <TencentSessionDelegate, QQApiInterfaceDelegate>
|
||||
|
||||
@end
|
||||
|
||||
enum FakeTencentScene {
|
||||
SCENE_QQ = 0,
|
||||
SCENE_QZONE = 1,
|
||||
};
|
||||
|
||||
enum FakeTencentRetCode {
|
||||
// 网络请求成功发送至服务器,并且服务器返回数据格式正确
|
||||
// 这里包括所请求业务操作失败的情况,例如没有授权等原因导致
|
||||
RET_SUCCESS = 0,
|
||||
// 网络异常,或服务器返回的数据格式不正确导致无法解析
|
||||
RET_FAILED = 1,
|
||||
RET_COMMON = -1,
|
||||
RET_USERCANCEL = -2,
|
||||
};
|
||||
|
||||
@implementation FakeTencentPlugin {
|
||||
FlutterMethodChannel * _channel;
|
||||
TencentOAuth * _oauth;
|
||||
}
|
||||
|
||||
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
||||
FlutterMethodChannel* channel = [FlutterMethodChannel
|
||||
methodChannelWithName:@"v7lin.github.io/fake_tencent"
|
||||
binaryMessenger:[registrar messenger]];
|
||||
FakeTencentPlugin* instance = [[FakeTencentPlugin alloc] initWithChannel:channel];
|
||||
[registrar addApplicationDelegate:instance];
|
||||
[registrar addMethodCallDelegate:instance channel:channel];
|
||||
}
|
||||
|
||||
static NSString * const METHOD_REGISTERAPP = @"registerApp";
|
||||
static NSString * const METHOD_ISQQINSTALLED = @"isQQInstalled";
|
||||
static NSString * const METHOD_ISQQSUPPORTSSOLOGIN = @"isQQSupportSSOLogin";
|
||||
static NSString * const METHOD_LOGIN = @"login";
|
||||
static NSString * const METHOD_LOGOUT = @"logout";
|
||||
static NSString * const METHOD_GETUSERINFO = @"getUserInfo";
|
||||
static NSString * const METHOD_SHAREMOOD = @"shareMood";
|
||||
static NSString * const METHOD_SHAREIMAGE = @"shareImage";
|
||||
static NSString * const METHOD_SHAREMUSIC = @"shareMusic";
|
||||
static NSString * const METHOD_SHAREWEBPAGE = @"shareWebpage";
|
||||
|
||||
static NSString * const METHOD_ONLOGINRESP = @"onLoginResp";
|
||||
static NSString * const METHOD_ONGETUSERINFORESP = @"onGetUserInfoResp";
|
||||
static NSString * const METHOD_ONSHARERESP = @"onShareResp";
|
||||
|
||||
static NSString * const ARGUMENT_KEY_APPID = @"appId";
|
||||
static NSString * const ARGUMENT_KEY_SCOPE = @"scope";
|
||||
static NSString * const ARGUMENT_KEY_OPENID = @"openId";
|
||||
static NSString * const ARGUMENT_KEY_ACCESSTOKEN = @"accessToken";
|
||||
static NSString * const ARGUMENT_KEY_EXPIRESIN = @"expiresIn";
|
||||
static NSString * const ARGUMENT_KEY_CREATEAT = @"createAt";
|
||||
static NSString * const ARGUMENT_KEY_SCENE = @"scene";
|
||||
static NSString * const ARGUMENT_KEY_TITLE = @"title";
|
||||
static NSString * const ARGUMENT_KEY_SUMMARY = @"summary";
|
||||
static NSString * const ARGUMENT_KEY_IMAGEURI = @"imageUri";
|
||||
static NSString * const ARGUMENT_KEY_IMAGEURIS = @"imageUris";
|
||||
static NSString * const ARGUMENT_KEY_VIDEOURI = @"videoUri";
|
||||
static NSString * const ARGUMENT_KEY_MUSICURL = @"musicUrl";
|
||||
static NSString * const ARGUMENT_KEY_TARGETURL = @"targetUrl";
|
||||
static NSString * const ARGUMENT_KEY_APPNAME = @"appName";
|
||||
static NSString * const ARGUMENT_KEY_EXTINT = @"extInt";
|
||||
|
||||
static NSString * const ARGUMENT_KEY_RESULT_RET = @"ret";
|
||||
static NSString * const ARGUMENT_KEY_RESULT_MSG = @"msg";
|
||||
static NSString * const ARGUMENT_KEY_RESULT_OPENID = @"openid";
|
||||
static NSString * const ARGUMENT_KEY_RESULT_ACCESS_TOKEN = @"access_token";
|
||||
static NSString * const ARGUMENT_KEY_RESULT_EXPIRES_IN = @"expires_in";
|
||||
static NSString * const ARGUMENT_KEY_RESULT_CREATE_AT = @"create_at";
|
||||
|
||||
static NSString * const SCHEME_FILE = @"file";
|
||||
|
||||
-(instancetype)initWithChannel:(FlutterMethodChannel *)channel {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_channel = channel;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
if ([METHOD_REGISTERAPP isEqualToString:call.method]) {
|
||||
NSString * appId = call.arguments[ARGUMENT_KEY_APPID];
|
||||
_oauth = [[TencentOAuth alloc] initWithAppId:appId andDelegate:self];
|
||||
result(nil);
|
||||
} else if ([METHOD_ISQQINSTALLED isEqualToString:call.method]) {
|
||||
result([NSNumber numberWithBool:[TencentOAuth iphoneQQInstalled]]);
|
||||
} else if ([METHOD_ISQQSUPPORTSSOLOGIN isEqualToString:call.method]) {
|
||||
result([NSNumber numberWithBool:[TencentOAuth iphoneQQSupportSSOLogin]]);
|
||||
} else if ([METHOD_LOGIN isEqualToString:call.method]) {
|
||||
[self login:call result:result];
|
||||
} else if ([METHOD_LOGOUT isEqualToString:call.method]) {
|
||||
[self logout:call result:result];
|
||||
} else if ([METHOD_GETUSERINFO isEqualToString:call.method]) {
|
||||
[self getUserInfo:call result:result];
|
||||
} else if ([METHOD_SHAREMOOD isEqualToString:call.method]) {
|
||||
[self shareMood:call result:result];
|
||||
} else if ([METHOD_SHAREIMAGE isEqualToString:call.method]) {
|
||||
[self shareImage:call result:result];
|
||||
} else if ([METHOD_SHAREMUSIC isEqualToString:call.method]) {
|
||||
[self shareMusic:call result:result];
|
||||
} else if ([METHOD_SHAREWEBPAGE isEqualToString:call.method]) {
|
||||
[self shareWebpage:call result:result];
|
||||
} else {
|
||||
result(FlutterMethodNotImplemented);
|
||||
}
|
||||
}
|
||||
|
||||
-(void)login:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
NSString * scope = call.arguments[ARGUMENT_KEY_SCOPE];
|
||||
NSArray * permissions = [scope componentsSeparatedByString:@","];
|
||||
[_oauth authorize:permissions];
|
||||
result(nil);
|
||||
}
|
||||
|
||||
-(void)logout:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
[_oauth logout:self];
|
||||
result(nil);
|
||||
}
|
||||
|
||||
-(void)getUserInfo:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
NSString * openId = call.arguments[ARGUMENT_KEY_OPENID];
|
||||
NSString * accessToken = call.arguments[ARGUMENT_KEY_ACCESSTOKEN];
|
||||
NSNumber * expiresIn = call.arguments[ARGUMENT_KEY_EXPIRESIN];
|
||||
NSNumber * createAt = call.arguments[ARGUMENT_KEY_CREATEAT];
|
||||
NSTimeInterval secs = createAt.longLongValue / 1000.0 + expiresIn.longLongValue;
|
||||
[_oauth setOpenId:openId];
|
||||
[_oauth setAccessToken:accessToken];
|
||||
[_oauth setExpirationDate:[NSDate dateWithTimeIntervalSince1970:secs]];
|
||||
[_oauth getUserInfo];
|
||||
result(nil);
|
||||
}
|
||||
|
||||
-(void)shareMood:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
NSNumber * scene = call.arguments[ARGUMENT_KEY_SCENE];
|
||||
if (scene.intValue == SCENE_QZONE) {
|
||||
NSString * summary = call.arguments[ARGUMENT_KEY_SUMMARY];
|
||||
NSArray * imageUris = call.arguments[ARGUMENT_KEY_IMAGEURIS];
|
||||
NSString * videoUri = call.arguments[ARGUMENT_KEY_VIDEOURI];
|
||||
|
||||
if (videoUri == nil || videoUri.length == 0) {
|
||||
NSMutableArray * imageDatas = [NSMutableArray array];
|
||||
if (imageUris != nil && imageUris.count > 0) {
|
||||
for (NSString * imageUri in imageUris) {
|
||||
NSURL * imageUrl = [NSURL URLWithString:imageUri];
|
||||
NSData * imageData = [NSData dataWithContentsOfFile:imageUrl.path];
|
||||
[imageDatas addObject:imageData];
|
||||
}
|
||||
}
|
||||
QQApiImageArrayForQZoneObject * object = [QQApiImageArrayForQZoneObject objectWithimageDataArray:imageDatas title:summary extMap:nil];
|
||||
SendMessageToQQReq * req = [SendMessageToQQReq reqWithContent: object];
|
||||
[QQApiInterface sendReq:req];
|
||||
} else {
|
||||
QQApiVideoForQZoneObject * object = [QQApiVideoForQZoneObject objectWithAssetURL:videoUri title:summary extMap:nil];
|
||||
SendMessageToQQReq * req = [SendMessageToQQReq reqWithContent: object];
|
||||
[QQApiInterface sendReq:req];
|
||||
}
|
||||
}
|
||||
result(nil);
|
||||
}
|
||||
|
||||
-(void)shareImage:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
NSNumber * scene = call.arguments[ARGUMENT_KEY_SCENE];
|
||||
if (scene.intValue == SCENE_QQ) {
|
||||
NSString * imageUri = call.arguments[ARGUMENT_KEY_IMAGEURI];
|
||||
// NSString * appName = call.arguments[ARGUMENT_KEY_APPNAME];
|
||||
// NSNumber * extInt = call.arguments[ARGUMENT_KEY_EXTINT];
|
||||
|
||||
NSURL * imageUrl = [NSURL URLWithString:imageUri];
|
||||
NSData * imageData = [NSData dataWithContentsOfFile:imageUrl.path];
|
||||
QQApiImageObject * object = [QQApiImageObject objectWithData:imageData previewImageData:nil title:nil description:nil];
|
||||
SendMessageToQQReq * req = [SendMessageToQQReq reqWithContent: object];
|
||||
[QQApiInterface sendReq:req];
|
||||
}
|
||||
result(nil);
|
||||
}
|
||||
|
||||
-(void)shareMusic:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
NSNumber * scene = call.arguments[ARGUMENT_KEY_SCENE];
|
||||
NSString * title = call.arguments[ARGUMENT_KEY_TITLE];
|
||||
NSString * summary = call.arguments[ARGUMENT_KEY_SUMMARY];
|
||||
NSString * imageUri = call.arguments[ARGUMENT_KEY_IMAGEURI];
|
||||
NSString * musicUrl = call.arguments[ARGUMENT_KEY_MUSICURL];
|
||||
NSString * targetUrl = call.arguments[ARGUMENT_KEY_TARGETURL];
|
||||
// NSString * appName = call.arguments[ARGUMENT_KEY_APPNAME];
|
||||
// NSNumber * extInt = call.arguments[ARGUMENT_KEY_EXTINT];
|
||||
if (scene.intValue == SCENE_QQ) {
|
||||
QQApiAudioObject * object = nil;
|
||||
NSURL * imageUrl = [NSURL URLWithString:imageUri];
|
||||
if ([SCHEME_FILE isEqualToString:imageUrl.scheme]) {
|
||||
NSData * imageData = [NSData dataWithContentsOfFile:imageUrl.path];
|
||||
object = [QQApiAudioObject objectWithURL:[NSURL URLWithString:targetUrl] title:title description:summary previewImageData:imageData];
|
||||
} else {
|
||||
object = [QQApiAudioObject objectWithURL:[NSURL URLWithString:targetUrl] title:title description:summary previewImageURL:imageUrl];
|
||||
}
|
||||
object.flashURL = [NSURL URLWithString:musicUrl];
|
||||
SendMessageToQQReq * req = [SendMessageToQQReq reqWithContent: object];
|
||||
[QQApiInterface sendReq:req];
|
||||
}
|
||||
result(nil);
|
||||
}
|
||||
|
||||
-(void)shareWebpage:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
NSNumber * scene = call.arguments[ARGUMENT_KEY_SCENE];
|
||||
NSString * title = call.arguments[ARGUMENT_KEY_TITLE];
|
||||
NSString * summary = call.arguments[ARGUMENT_KEY_SUMMARY];
|
||||
NSString * imageUri = call.arguments[ARGUMENT_KEY_IMAGEURI];
|
||||
NSString * targetUrl = call.arguments[ARGUMENT_KEY_TARGETURL];
|
||||
// NSString * appName = call.arguments[ARGUMENT_KEY_APPNAME];
|
||||
// NSNumber * extInt = call.arguments[ARGUMENT_KEY_EXTINT];
|
||||
|
||||
QQApiNewsObject * object = nil;
|
||||
NSURL * imageUrl = [NSURL URLWithString:imageUri];
|
||||
if ([SCHEME_FILE isEqualToString:imageUrl.scheme]) {
|
||||
NSData * imageData = [NSData dataWithContentsOfFile:imageUrl.path];
|
||||
object = [QQApiNewsObject objectWithURL:[NSURL URLWithString:targetUrl] title:title description:summary previewImageData:imageData];
|
||||
} else {
|
||||
object = [QQApiNewsObject objectWithURL:[NSURL URLWithString:targetUrl] title:title description:summary previewImageURL:imageUrl];
|
||||
}
|
||||
SendMessageToQQReq * req = [SendMessageToQQReq reqWithContent: object];
|
||||
if (scene.intValue == SCENE_QQ) {
|
||||
[QQApiInterface sendReq:req];
|
||||
} else if (scene.intValue == SCENE_QZONE) {
|
||||
[QQApiInterface SendReqToQZone:req];
|
||||
}
|
||||
result(nil);
|
||||
}
|
||||
|
||||
# pragma mark - AppDelegate
|
||||
|
||||
-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
|
||||
return [QQApiInterface handleOpenURL:url delegate:self] || ([TencentOAuth CanHandleOpenURL:url] && [TencentOAuth HandleOpenURL:url]);
|
||||
}
|
||||
|
||||
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
|
||||
return [QQApiInterface handleOpenURL:url delegate:self] || ([TencentOAuth CanHandleOpenURL:url] && [TencentOAuth HandleOpenURL:url]);
|
||||
}
|
||||
|
||||
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||
return [QQApiInterface handleOpenURL:url delegate:self] || ([TencentOAuth CanHandleOpenURL:url] && [TencentOAuth HandleOpenURL:url]);
|
||||
}
|
||||
|
||||
# pragma mark - TencentSessionDelegate
|
||||
|
||||
-(void)tencentDidLogin {
|
||||
NSMutableDictionary * dictionary = [NSMutableDictionary dictionary];
|
||||
if (_oauth.accessToken != nil && _oauth.accessToken.length > 0) {
|
||||
NSString * openId = _oauth.openId;
|
||||
NSString * accessToken = _oauth.accessToken;
|
||||
long long expiresIn = ceil(_oauth.expirationDate.timeIntervalSinceNow);// 向上取整
|
||||
long long createAt = [[NSDate date] timeIntervalSince1970] * 1000.0;
|
||||
[dictionary setValue:[NSNumber numberWithInt:RET_SUCCESS] forKey:ARGUMENT_KEY_RESULT_RET];
|
||||
[dictionary setValue:openId forKey:ARGUMENT_KEY_RESULT_OPENID];
|
||||
[dictionary setValue:accessToken forKey:ARGUMENT_KEY_RESULT_ACCESS_TOKEN];
|
||||
[dictionary setValue:[NSNumber numberWithLongLong:expiresIn] forKey:ARGUMENT_KEY_RESULT_EXPIRES_IN];
|
||||
[dictionary setValue:[NSNumber numberWithLongLong:createAt] forKey:ARGUMENT_KEY_RESULT_CREATE_AT];
|
||||
} else {
|
||||
// 登录失败
|
||||
[dictionary setValue:[NSNumber numberWithInt:RET_COMMON] forKey:ARGUMENT_KEY_RESULT_RET];
|
||||
}
|
||||
[_channel invokeMethod:METHOD_ONLOGINRESP arguments:dictionary];
|
||||
}
|
||||
|
||||
-(void)tencentDidNotLogin:(BOOL)cancelled {
|
||||
NSMutableDictionary * dictionary = [NSMutableDictionary dictionary];
|
||||
if (cancelled) {
|
||||
// 取消登录
|
||||
[dictionary setValue:[NSNumber numberWithInt:RET_USERCANCEL] forKey:ARGUMENT_KEY_RESULT_RET];
|
||||
} else {
|
||||
// 登录失败
|
||||
[dictionary setValue:[NSNumber numberWithInt:RET_COMMON] forKey:ARGUMENT_KEY_RESULT_RET];
|
||||
}
|
||||
[_channel invokeMethod:METHOD_ONLOGINRESP arguments:dictionary];
|
||||
}
|
||||
|
||||
-(void)tencentDidNotNetWork {
|
||||
// 登录失败
|
||||
NSMutableDictionary * dictionary = [NSMutableDictionary dictionary];
|
||||
[dictionary setValue:[NSNumber numberWithInt:RET_COMMON] forKey:ARGUMENT_KEY_RESULT_RET];
|
||||
[_channel invokeMethod:METHOD_ONLOGINRESP arguments:dictionary];
|
||||
}
|
||||
|
||||
-(void)getUserInfoResponse:(APIResponse *)response {
|
||||
NSMutableDictionary * dictionary = [NSMutableDictionary dictionary];
|
||||
if (response.retCode == URLREQUEST_SUCCEED) {
|
||||
[dictionary setValue:[NSNumber numberWithInt:RET_SUCCESS] forKey:ARGUMENT_KEY_RESULT_RET];
|
||||
NSDictionary * json = response.jsonResponse;
|
||||
[dictionary addEntriesFromDictionary:json];
|
||||
} else {
|
||||
[dictionary setValue:[NSNumber numberWithInt:RET_COMMON] forKey:ARGUMENT_KEY_RESULT_RET];
|
||||
[dictionary setValue:response.errorMsg forKey:ARGUMENT_KEY_RESULT_MSG];
|
||||
}
|
||||
[_channel invokeMethod:METHOD_ONGETUSERINFORESP arguments:dictionary];
|
||||
}
|
||||
|
||||
# pragma mark - QQApiInterfaceDelegate
|
||||
|
||||
-(void)onReq:(QQBaseReq *)req {
|
||||
|
||||
}
|
||||
|
||||
- (void)onResp:(QQBaseResp *)resp {
|
||||
NSMutableDictionary * dictionary = [NSMutableDictionary dictionary];
|
||||
if ([resp isKindOfClass:[SendMessageToQQResp class]]) {
|
||||
switch (resp.result.intValue) {
|
||||
case 0:
|
||||
// 分享成功
|
||||
[dictionary setValue:[NSNumber numberWithInt:RET_SUCCESS] forKey:ARGUMENT_KEY_RESULT_RET];
|
||||
break;
|
||||
case -4:
|
||||
// 用户取消
|
||||
[dictionary setValue:[NSNumber numberWithInt:RET_USERCANCEL] forKey:ARGUMENT_KEY_RESULT_RET];
|
||||
break;
|
||||
default:
|
||||
[dictionary setValue:[NSNumber numberWithInt:RET_COMMON] forKey:ARGUMENT_KEY_RESULT_RET];
|
||||
NSString * errorMsg = [NSString stringWithFormat:@"result: %@, description: %@.", resp.result, resp.errorDescription];
|
||||
[dictionary setValue:errorMsg forKey:ARGUMENT_KEY_RESULT_MSG];
|
||||
break;
|
||||
}
|
||||
[_channel invokeMethod:METHOD_ONSHARERESP arguments:dictionary];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)isOnlineResponse:(NSDictionary *)response {
|
||||
|
||||
}
|
||||
|
||||
@end
|
4
ios/Classes/TencentKitPlugin.h
Normal file
4
ios/Classes/TencentKitPlugin.h
Normal file
@ -0,0 +1,4 @@
|
||||
#import <Flutter/Flutter.h>
|
||||
|
||||
@interface TencentKitPlugin : NSObject<FlutterPlugin>
|
||||
@end
|
313
ios/Classes/TencentKitPlugin.m
Normal file
313
ios/Classes/TencentKitPlugin.m
Normal file
@ -0,0 +1,313 @@
|
||||
#import "TencentKitPlugin.h"
|
||||
#import <TencentOpenAPI/TencentOAuth.h>
|
||||
#import <TencentOpenAPI/QQApiInterface.h>
|
||||
|
||||
enum TencentScene {
|
||||
SCENE_QQ = 0,
|
||||
SCENE_QZONE = 1,
|
||||
};
|
||||
|
||||
enum TencentRetCode {
|
||||
// 网络请求成功发送至服务器,并且服务器返回数据格式正确
|
||||
// 这里包括所请求业务操作失败的情况,例如没有授权等原因导致
|
||||
RET_SUCCESS = 0,
|
||||
// 网络异常,或服务器返回的数据格式不正确导致无法解析
|
||||
RET_FAILED = 1,
|
||||
RET_COMMON = -1,
|
||||
RET_USERCANCEL = -2,
|
||||
};
|
||||
|
||||
@interface TencentKitPlugin () <TencentSessionDelegate, QQApiInterfaceDelegate>
|
||||
|
||||
@end
|
||||
|
||||
@implementation TencentKitPlugin {
|
||||
FlutterMethodChannel* _channel;
|
||||
TencentOAuth* _oauth;
|
||||
}
|
||||
|
||||
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
||||
FlutterMethodChannel* channel = [FlutterMethodChannel
|
||||
methodChannelWithName:@"v7lin.github.io/tencent_kit"
|
||||
binaryMessenger:[registrar messenger]];
|
||||
TencentKitPlugin* instance = [[TencentKitPlugin alloc] initWithChannel:channel];
|
||||
[registrar addApplicationDelegate:instance];
|
||||
[registrar addMethodCallDelegate:instance channel:channel];
|
||||
}
|
||||
|
||||
static NSString* const METHOD_REGISTERAPP = @"registerApp";
|
||||
static NSString* const METHOD_ISINSTALLED = @"isInstalled";
|
||||
static NSString* const METHOD_LOGIN = @"login";
|
||||
static NSString* const METHOD_LOGOUT = @"logout";
|
||||
static NSString* const METHOD_SHAREMOOD = @"shareMood";
|
||||
static NSString* const METHOD_SHAREIMAGE = @"shareImage";
|
||||
static NSString* const METHOD_SHAREMUSIC = @"shareMusic";
|
||||
static NSString* const METHOD_SHAREWEBPAGE = @"shareWebpage";
|
||||
|
||||
static NSString* const METHOD_ONLOGINRESP = @"onLoginResp";
|
||||
static NSString* const METHOD_ONSHARERESP = @"onShareResp";
|
||||
|
||||
static NSString* const ARGUMENT_KEY_APPID = @"appId";
|
||||
static NSString* const ARGUMENT_KEY_UNIVERSALLINK = @"universalLink";
|
||||
static NSString* const ARGUMENT_KEY_SCOPE = @"scope";
|
||||
static NSString* const ARGUMENT_KEY_SCENE = @"scene";
|
||||
static NSString* const ARGUMENT_KEY_TITLE = @"title";
|
||||
static NSString* const ARGUMENT_KEY_SUMMARY = @"summary";
|
||||
static NSString* const ARGUMENT_KEY_IMAGEURI = @"imageUri";
|
||||
static NSString* const ARGUMENT_KEY_IMAGEURIS = @"imageUris";
|
||||
static NSString* const ARGUMENT_KEY_VIDEOURI = @"videoUri";
|
||||
static NSString* const ARGUMENT_KEY_MUSICURL = @"musicUrl";
|
||||
static NSString* const ARGUMENT_KEY_TARGETURL = @"targetUrl";
|
||||
static NSString* const ARGUMENT_KEY_APPNAME = @"appName";
|
||||
static NSString* const ARGUMENT_KEY_EXTINT = @"extInt";
|
||||
|
||||
static NSString* const ARGUMENT_KEY_RESULT_RET = @"ret";
|
||||
static NSString* const ARGUMENT_KEY_RESULT_MSG = @"msg";
|
||||
static NSString* const ARGUMENT_KEY_RESULT_OPENID = @"openid";
|
||||
static NSString* const ARGUMENT_KEY_RESULT_ACCESS_TOKEN = @"access_token";
|
||||
static NSString* const ARGUMENT_KEY_RESULT_EXPIRES_IN = @"expires_in";
|
||||
static NSString* const ARGUMENT_KEY_RESULT_CREATE_AT = @"create_at";
|
||||
|
||||
static NSString* const SCHEME_FILE = @"file";
|
||||
|
||||
-(instancetype)initWithChannel:(FlutterMethodChannel *)channel {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_channel = channel;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
if ([METHOD_REGISTERAPP isEqualToString:call.method]) {
|
||||
NSString* appId = call.arguments[ARGUMENT_KEY_APPID];
|
||||
NSString* universalLink = call.arguments[ARGUMENT_KEY_UNIVERSALLINK];
|
||||
if (universalLink != nil) {
|
||||
_oauth = [[TencentOAuth alloc] initWithAppId:appId andUniversalLink:universalLink andDelegate:self];
|
||||
} else {
|
||||
_oauth = [[TencentOAuth alloc] initWithAppId:appId andDelegate:self];
|
||||
}
|
||||
result(nil);
|
||||
} else if ([METHOD_ISINSTALLED isEqualToString:call.method]) {
|
||||
result([NSNumber numberWithBool:[TencentOAuth iphoneQQInstalled]]);
|
||||
} else if ([METHOD_LOGIN isEqualToString:call.method]) {
|
||||
[self login:call result:result];
|
||||
} else if ([METHOD_LOGOUT isEqualToString:call.method]) {
|
||||
[self logout:call result:result];
|
||||
} else if ([METHOD_SHAREMOOD isEqualToString:call.method]) {
|
||||
[self shareMood:call result:result];
|
||||
} else if ([METHOD_SHAREIMAGE isEqualToString:call.method]) {
|
||||
[self shareImage:call result:result];
|
||||
} else if ([METHOD_SHAREMUSIC isEqualToString:call.method]) {
|
||||
[self shareMusic:call result:result];
|
||||
} else if ([METHOD_SHAREWEBPAGE isEqualToString:call.method]) {
|
||||
[self shareWebpage:call result:result];
|
||||
} else {
|
||||
result(FlutterMethodNotImplemented);
|
||||
}
|
||||
}
|
||||
|
||||
-(void)login:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
NSString* scope = call.arguments[ARGUMENT_KEY_SCOPE];
|
||||
NSArray* permissions = [scope componentsSeparatedByString:@","];
|
||||
[_oauth authorize:permissions];
|
||||
result(nil);
|
||||
}
|
||||
|
||||
-(void)logout:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
[_oauth logout:self];
|
||||
result(nil);
|
||||
}
|
||||
|
||||
-(void)shareMood:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
NSNumber* scene = call.arguments[ARGUMENT_KEY_SCENE];
|
||||
if (scene.intValue == SCENE_QZONE) {
|
||||
NSString* summary = call.arguments[ARGUMENT_KEY_SUMMARY];
|
||||
NSArray* imageUris = call.arguments[ARGUMENT_KEY_IMAGEURIS];
|
||||
NSString* videoUri = call.arguments[ARGUMENT_KEY_VIDEOURI];
|
||||
|
||||
if (videoUri == nil || videoUri.length == 0) {
|
||||
NSMutableArray* imageDatas = [NSMutableArray array];
|
||||
if (imageUris != nil && imageUris.count > 0) {
|
||||
for (NSString* imageUri in imageUris) {
|
||||
NSURL* imageUrl = [NSURL URLWithString:imageUri];
|
||||
NSData* imageData = [NSData dataWithContentsOfFile:imageUrl.path];
|
||||
[imageDatas addObject:imageData];
|
||||
}
|
||||
}
|
||||
QQApiImageArrayForQZoneObject* object = [QQApiImageArrayForQZoneObject objectWithimageDataArray:imageDatas title:summary extMap:nil];
|
||||
SendMessageToQQReq* req = [SendMessageToQQReq reqWithContent: object];
|
||||
[QQApiInterface sendReq:req];
|
||||
} else {
|
||||
QQApiVideoForQZoneObject* object = [QQApiVideoForQZoneObject objectWithAssetURL:videoUri title:summary extMap:nil];
|
||||
SendMessageToQQReq* req = [SendMessageToQQReq reqWithContent: object];
|
||||
[QQApiInterface sendReq:req];
|
||||
}
|
||||
}
|
||||
result(nil);
|
||||
}
|
||||
|
||||
-(void)shareImage:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
NSNumber* scene = call.arguments[ARGUMENT_KEY_SCENE];
|
||||
if (scene.intValue == SCENE_QQ) {
|
||||
NSString* imageUri = call.arguments[ARGUMENT_KEY_IMAGEURI];
|
||||
// NSString* appName = call.arguments[ARGUMENT_KEY_APPNAME];
|
||||
// NSNumber* extInt = call.arguments[ARGUMENT_KEY_EXTINT];
|
||||
|
||||
NSURL* imageUrl = [NSURL URLWithString:imageUri];
|
||||
NSData* imageData = [NSData dataWithContentsOfFile:imageUrl.path];
|
||||
QQApiImageObject* object = [QQApiImageObject objectWithData:imageData previewImageData:nil title:nil description:nil];
|
||||
SendMessageToQQReq* req = [SendMessageToQQReq reqWithContent: object];
|
||||
[QQApiInterface sendReq:req];
|
||||
}
|
||||
result(nil);
|
||||
}
|
||||
|
||||
-(void)shareMusic:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
NSNumber* scene = call.arguments[ARGUMENT_KEY_SCENE];
|
||||
NSString* title = call.arguments[ARGUMENT_KEY_TITLE];
|
||||
NSString* summary = call.arguments[ARGUMENT_KEY_SUMMARY];
|
||||
NSString* imageUri = call.arguments[ARGUMENT_KEY_IMAGEURI];
|
||||
NSString* musicUrl = call.arguments[ARGUMENT_KEY_MUSICURL];
|
||||
NSString* targetUrl = call.arguments[ARGUMENT_KEY_TARGETURL];
|
||||
// NSString* appName = call.arguments[ARGUMENT_KEY_APPNAME];
|
||||
// NSNumber* extInt = call.arguments[ARGUMENT_KEY_EXTINT];
|
||||
if (scene.intValue == SCENE_QQ) {
|
||||
QQApiAudioObject* object = nil;
|
||||
NSURL* imageUrl = [NSURL URLWithString:imageUri];
|
||||
if ([SCHEME_FILE isEqualToString:imageUrl.scheme]) {
|
||||
NSData* imageData = [NSData dataWithContentsOfFile:imageUrl.path];
|
||||
object = [QQApiAudioObject objectWithURL:[NSURL URLWithString:targetUrl] title:title description:summary previewImageData:imageData];
|
||||
} else {
|
||||
object = [QQApiAudioObject objectWithURL:[NSURL URLWithString:targetUrl] title:title description:summary previewImageURL:imageUrl];
|
||||
}
|
||||
object.flashURL = [NSURL URLWithString:musicUrl];
|
||||
SendMessageToQQReq* req = [SendMessageToQQReq reqWithContent: object];
|
||||
[QQApiInterface sendReq:req];
|
||||
}
|
||||
result(nil);
|
||||
}
|
||||
|
||||
-(void)shareWebpage:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
NSNumber* scene = call.arguments[ARGUMENT_KEY_SCENE];
|
||||
NSString* title = call.arguments[ARGUMENT_KEY_TITLE];
|
||||
NSString* summary = call.arguments[ARGUMENT_KEY_SUMMARY];
|
||||
NSString* imageUri = call.arguments[ARGUMENT_KEY_IMAGEURI];
|
||||
NSString* targetUrl = call.arguments[ARGUMENT_KEY_TARGETURL];
|
||||
// NSString* appName = call.arguments[ARGUMENT_KEY_APPNAME];
|
||||
// NSNumber* extInt = call.arguments[ARGUMENT_KEY_EXTINT];
|
||||
|
||||
QQApiNewsObject* object = nil;
|
||||
NSURL* imageUrl = [NSURL URLWithString:imageUri];
|
||||
if ([SCHEME_FILE isEqualToString:imageUrl.scheme]) {
|
||||
NSData* imageData = [NSData dataWithContentsOfFile:imageUrl.path];
|
||||
object = [QQApiNewsObject objectWithURL:[NSURL URLWithString:targetUrl] title:title description:summary previewImageData:imageData];
|
||||
} else {
|
||||
object = [QQApiNewsObject objectWithURL:[NSURL URLWithString:targetUrl] title:title description:summary previewImageURL:imageUrl];
|
||||
}
|
||||
SendMessageToQQReq* req = [SendMessageToQQReq reqWithContent: object];
|
||||
if (scene.intValue == SCENE_QQ) {
|
||||
[QQApiInterface sendReq:req];
|
||||
} else if (scene.intValue == SCENE_QZONE) {
|
||||
[QQApiInterface SendReqToQZone:req];
|
||||
}
|
||||
result(nil);
|
||||
}
|
||||
|
||||
# pragma mark - AppDelegate
|
||||
|
||||
-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
|
||||
return [QQApiInterface handleOpenURL:url delegate:self] || ([TencentOAuth CanHandleOpenURL:url] && [TencentOAuth HandleOpenURL:url]);
|
||||
}
|
||||
|
||||
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
|
||||
return [QQApiInterface handleOpenURL:url delegate:self] || ([TencentOAuth CanHandleOpenURL:url] && [TencentOAuth HandleOpenURL:url]);
|
||||
}
|
||||
|
||||
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||
return [QQApiInterface handleOpenURL:url delegate:self] || ([TencentOAuth CanHandleOpenURL:url] && [TencentOAuth HandleOpenURL:url]);
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nonnull))restorationHandler {
|
||||
if([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
|
||||
NSURL* url = userActivity.webpageURL;
|
||||
if (url != nil) {
|
||||
return [QQApiInterface handleOpenUniversallink:url delegate:self] || ([TencentOAuth CanHandleUniversalLink:url] && [TencentOAuth HandleUniversalLink:url]);
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
# pragma mark - TencentSessionDelegate
|
||||
|
||||
-(void)tencentDidLogin {
|
||||
NSMutableDictionary* dictionary = [NSMutableDictionary dictionary];
|
||||
if (_oauth.accessToken != nil && _oauth.accessToken.length > 0) {
|
||||
NSString* openId = _oauth.openId;
|
||||
NSString* accessToken = _oauth.accessToken;
|
||||
long long expiresIn = ceil(_oauth.expirationDate.timeIntervalSinceNow);// 向上取整
|
||||
long long createAt = [[NSDate date] timeIntervalSince1970]* 1000.0;
|
||||
[dictionary setValue:[NSNumber numberWithInt:RET_SUCCESS] forKey:ARGUMENT_KEY_RESULT_RET];
|
||||
[dictionary setValue:openId forKey:ARGUMENT_KEY_RESULT_OPENID];
|
||||
[dictionary setValue:accessToken forKey:ARGUMENT_KEY_RESULT_ACCESS_TOKEN];
|
||||
[dictionary setValue:[NSNumber numberWithLongLong:expiresIn] forKey:ARGUMENT_KEY_RESULT_EXPIRES_IN];
|
||||
[dictionary setValue:[NSNumber numberWithLongLong:createAt] forKey:ARGUMENT_KEY_RESULT_CREATE_AT];
|
||||
} else {
|
||||
// 登录失败
|
||||
[dictionary setValue:[NSNumber numberWithInt:RET_COMMON] forKey:ARGUMENT_KEY_RESULT_RET];
|
||||
}
|
||||
[_channel invokeMethod:METHOD_ONLOGINRESP arguments:dictionary];
|
||||
}
|
||||
|
||||
-(void)tencentDidNotLogin:(BOOL)cancelled {
|
||||
NSMutableDictionary* dictionary = [NSMutableDictionary dictionary];
|
||||
if (cancelled) {
|
||||
// 取消登录
|
||||
[dictionary setValue:[NSNumber numberWithInt:RET_USERCANCEL] forKey:ARGUMENT_KEY_RESULT_RET];
|
||||
} else {
|
||||
// 登录失败
|
||||
[dictionary setValue:[NSNumber numberWithInt:RET_COMMON] forKey:ARGUMENT_KEY_RESULT_RET];
|
||||
}
|
||||
[_channel invokeMethod:METHOD_ONLOGINRESP arguments:dictionary];
|
||||
}
|
||||
|
||||
-(void)tencentDidNotNetWork {
|
||||
// 登录失败
|
||||
NSMutableDictionary* dictionary = [NSMutableDictionary dictionary];
|
||||
[dictionary setValue:[NSNumber numberWithInt:RET_COMMON] forKey:ARGUMENT_KEY_RESULT_RET];
|
||||
[_channel invokeMethod:METHOD_ONLOGINRESP arguments:dictionary];
|
||||
}
|
||||
|
||||
# pragma mark - QQApiInterfaceDelegate
|
||||
|
||||
-(void)onReq:(QQBaseReq *)req {
|
||||
|
||||
}
|
||||
|
||||
- (void)onResp:(QQBaseResp *)resp {
|
||||
NSMutableDictionary* dictionary = [NSMutableDictionary dictionary];
|
||||
if ([resp isKindOfClass:[SendMessageToQQResp class]]) {
|
||||
switch (resp.result.intValue) {
|
||||
case 0:
|
||||
// 分享成功
|
||||
[dictionary setValue:[NSNumber numberWithInt:RET_SUCCESS] forKey:ARGUMENT_KEY_RESULT_RET];
|
||||
break;
|
||||
case -4:
|
||||
// 用户取消
|
||||
[dictionary setValue:[NSNumber numberWithInt:RET_USERCANCEL] forKey:ARGUMENT_KEY_RESULT_RET];
|
||||
break;
|
||||
default:
|
||||
[dictionary setValue:[NSNumber numberWithInt:RET_COMMON] forKey:ARGUMENT_KEY_RESULT_RET];
|
||||
NSString* errorMsg = [NSString stringWithFormat:@"result: %@, description: %@.", resp.result, resp.errorDescription];
|
||||
[dictionary setValue:errorMsg forKey:ARGUMENT_KEY_RESULT_MSG];
|
||||
break;
|
||||
}
|
||||
[_channel invokeMethod:METHOD_ONSHARERESP arguments:dictionary];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)isOnlineResponse:(NSDictionary *)response {
|
||||
|
||||
}
|
||||
|
||||
@end
|
158
ios/Libraries/TencentOpenAPI.framework/Headers/QQApiInterface.h
Normal file
158
ios/Libraries/TencentOpenAPI.framework/Headers/QQApiInterface.h
Normal file
@ -0,0 +1,158 @@
|
||||
///
|
||||
/// \file QQApiInterface.h
|
||||
/// \brief QQApi接口简化封装
|
||||
///
|
||||
/// Created by Tencent on 12-5-15.
|
||||
/// Copyright (c) 2012年 Tencent. All rights reserved.
|
||||
///
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "QQApiInterfaceObject.h"
|
||||
|
||||
typedef void (^sendResultBlock)(NSDictionary *result);
|
||||
|
||||
/**
|
||||
\brief 处理来至QQ的请求及响应的回调协议
|
||||
*/
|
||||
@protocol QQApiInterfaceDelegate <NSObject>
|
||||
|
||||
/**
|
||||
处理来至QQ的请求
|
||||
*/
|
||||
- (void)onReq:(QQBaseReq *)req;
|
||||
|
||||
/**
|
||||
处理来至QQ的响应
|
||||
*/
|
||||
- (void)onResp:(QQBaseResp *)resp;
|
||||
|
||||
/**
|
||||
处理QQ在线状态的回调
|
||||
*/
|
||||
- (void)isOnlineResponse:(NSDictionary *)response;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
\brief 对QQApi的简单封装类
|
||||
*/
|
||||
@interface QQApiInterface : NSObject
|
||||
|
||||
/**
|
||||
处理由手Q唤起的普通跳转请求
|
||||
\param url 待处理的url跳转请求
|
||||
\param delegate 第三方应用用于处理来至QQ请求及响应的委托对象
|
||||
\return 跳转请求处理结果,YES表示成功处理,NO表示不支持的请求协议或处理失败
|
||||
*/
|
||||
+ (BOOL)handleOpenURL:(NSURL *)url delegate:(id<QQApiInterfaceDelegate>)delegate;
|
||||
|
||||
/**
|
||||
处理由手Q唤起的universallink跳转请求
|
||||
\param universallink 待处理的universallink跳转请求
|
||||
\param delegate 第三方应用用于处理来至QQ请求及响应的委托对象
|
||||
\return 跳转请求处理结果,YES表示成功处理,NO表示不支持的请求协议或处理失败
|
||||
*/
|
||||
+ (BOOL)handleOpenUniversallink:(NSURL*)universallink delegate:(id<QQApiInterfaceDelegate>)delegate;
|
||||
|
||||
/**
|
||||
向手Q发起分享请求
|
||||
\param req 分享内容的请求
|
||||
\return 请求发送结果码
|
||||
*/
|
||||
+ (QQApiSendResultCode)sendReq:(QQBaseReq *)req;
|
||||
|
||||
|
||||
/**
|
||||
向手Q QZone结合版发起分享请求
|
||||
\note H5分享只支持单张网络图片的传递
|
||||
\param req 分享内容的请求
|
||||
\return 请求发送结果码
|
||||
*/
|
||||
+ (QQApiSendResultCode)SendReqToQZone:(QQBaseReq *)req;
|
||||
|
||||
/**
|
||||
向手Q发起设置QQ头像
|
||||
\param req 分享内容的请求
|
||||
\return 请求发送结果码
|
||||
*/
|
||||
+ (QQApiSendResultCode)sendMessageToQQAvatarWithReq:(QQBaseReq*)req;
|
||||
|
||||
/**
|
||||
向手Q发起组图分享到表情收藏
|
||||
\param req 分享内容的请求
|
||||
\return 请求发送结果码
|
||||
*/
|
||||
+ (QQApiSendResultCode)sendMessageToFaceCollectionWithReq:(QQBaseReq*)req;
|
||||
|
||||
/**
|
||||
检测是否已安装QQ
|
||||
\return 如果QQ已安装则返回YES,否则返回NO
|
||||
|
||||
\note SDK目前已经支持QQ、TIM授权登录及分享功能, 会按照QQ>TIM的顺序进行调用。
|
||||
只要用户安装了QQ、TIM中任意一个应用,都可为第三方应用进行授权登录、分享功能。
|
||||
第三方应用在接入SDK时不需要判断是否安装QQ、TIM。若有判断安装QQ、TIM的逻辑建议移除。
|
||||
*/
|
||||
+ (BOOL)isQQInstalled;
|
||||
|
||||
/**
|
||||
检测是否已安装TIM
|
||||
\return 如果TIM已安装则返回YES,否则返回NO
|
||||
|
||||
\note SDK目前已经支持QQ、TIM授权登录及分享功能, 会按照QQ>TIM的顺序进行调用。
|
||||
只要用户安装了QQ、TIM中任意一个应用,都可为第三方应用进行授权登录、分享功能。
|
||||
第三方应用在接入SDK时不需要判断是否安装QQ、TIM。若有判断安装QQ、TIM的逻辑建议移除。
|
||||
*/
|
||||
+ (BOOL)isTIMInstalled;
|
||||
|
||||
/**
|
||||
检测QQ是否支持API调用
|
||||
\return 如果当前安装QQ版本支持API调用则返回YES,否则返回NO
|
||||
*/
|
||||
+ (BOOL)isQQSupportApi;
|
||||
|
||||
/**
|
||||
检测TIM是否支持API调用
|
||||
\return 如果当前安装TIM版本支持API调用则返回YES,否则返回NO
|
||||
*/
|
||||
+ (BOOL)isTIMSupportApi __attribute__((deprecated("已过期, 建议删除调用,调用地方用YES替代。")));
|
||||
|
||||
/**
|
||||
检测是否支持分享
|
||||
\return 如果当前已安装QQ且QQ版本支持API调用 或者 当前已安装TIM且TIM版本支持API调用则返回YES,否则返回NO
|
||||
*/
|
||||
+ (BOOL)isSupportShareToQQ;
|
||||
|
||||
/**
|
||||
检测是否支持分享到QQ结合版QZone
|
||||
\return 如果当前已安装QQ且QQ版本支持API调用则返回YES,否则返回NO
|
||||
*/
|
||||
+ (BOOL)isSupportPushToQZone;
|
||||
|
||||
/**
|
||||
启动QQ
|
||||
\return 成功返回YES,否则返回NO
|
||||
*/
|
||||
+ (BOOL)openQQ;
|
||||
|
||||
/**
|
||||
启动TIM
|
||||
\return 成功返回YES,否则返回NO
|
||||
*/
|
||||
+ (BOOL)openTIM;
|
||||
|
||||
/**
|
||||
获取QQ下载地址
|
||||
|
||||
如果App通过<code>QQApiInterface#isQQInstalled</code>和<code>QQApiInterface#isQQSupportApi</code>检测发现QQ没安装或当前版本QQ不支持API调用,可引导用户通过打开此链接下载最新版QQ。
|
||||
\return iPhoneQQ下载地址
|
||||
*/
|
||||
+ (NSString *)getQQInstallUrl;
|
||||
|
||||
/**
|
||||
获取TIM下载地址
|
||||
|
||||
如果App通过<code>QQApiInterface#isTIMInstalled</code>检测发现TIM没安装或当前版本TIM不支持API调用,可引导用户通过打开此链接下载最新版TIM。
|
||||
\return iPhoneTIM下载地址
|
||||
*/
|
||||
+ (NSString *)getTIMInstallUrl;
|
||||
@end
|
@ -0,0 +1,645 @@
|
||||
///
|
||||
/// \file QQApiInterfaceObject.h
|
||||
/// \brief QQApiInterface所依赖的请求及应答消息对象封装帮助类
|
||||
///
|
||||
/// Created by Tencent on 12-5-15.
|
||||
/// Copyright (c) 2012年 Tencent. All rights reserved.
|
||||
///
|
||||
|
||||
#ifndef QQApiInterface_QQAPIOBJECT_h
|
||||
#define QQApiInterface_QQAPIOBJECT_h
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef NS_ENUM(NSInteger,QQApiSendResultCode) {
|
||||
EQQAPISENDSUCESS = 0,
|
||||
EQQAPIQQNOTINSTALLED = 1, //QQ未安装
|
||||
EQQAPIQQNOTSUPPORTAPI = 2, // QQ api不支持
|
||||
EQQAPIMESSAGETYPEINVALID = 3,
|
||||
EQQAPIMESSAGECONTENTNULL = 4,
|
||||
EQQAPIMESSAGECONTENTINVALID = 5,
|
||||
EQQAPIAPPNOTREGISTED = 6,
|
||||
EQQAPIAPPSHAREASYNC = 7,
|
||||
EQQAPIQQNOTSUPPORTAPI_WITH_ERRORSHOW = 8, //QQ api不支持 && SDK显示error提示(已废弃)
|
||||
EQQAPIMESSAGEARKCONTENTNULL = 9, //ark内容为空
|
||||
EQQAPIMESSAGE_MINI_CONTENTNULL = 10, //小程序参数为空
|
||||
EQQAPISENDFAILD = -1, //发送失败
|
||||
EQQAPISHAREDESTUNKNOWN = -2, //未指定分享到QQ或TIM
|
||||
EQQAPITIMSENDFAILD = -3, //发送失败
|
||||
EQQAPITIMNOTINSTALLED = 11, //TIM未安装
|
||||
EQQAPITIMNOTSUPPORTAPI = 12, // TIM api不支持
|
||||
EQQAPI_INCOMING_PARAM_ERROR = 13, // 外部传参错误
|
||||
EQQAPI_THIRD_APP_GROUP_ERROR_APP_NOT_AUTHORIZIED = 14, // APP未获得授权
|
||||
EQQAPI_THIRD_APP_GROUP_ERROR_CGI_FAILED = 15, // CGI请求失败
|
||||
EQQAPI_THIRD_APP_GROUP_ERROR_HAS_BINDED = 16, // 该组织已经绑定群聊
|
||||
EQQAPI_THIRD_APP_GROUP_ERROR_NOT_BINDED = 17, // 该组织尚未绑定群聊
|
||||
EQQAPIQZONENOTSUPPORTTEXT = 10000, //qzone分享不支持text类型分享
|
||||
EQQAPIQZONENOTSUPPORTIMAGE = 10001, //qzone分享不支持image类型分享
|
||||
EQQAPIVERSIONNEEDUPDATE = 10002, //当前QQ版本太低,需要更新至新版本才可以支持
|
||||
ETIMAPIVERSIONNEEDUPDATE = 10004, //当前TIM版本太低,需要更新至新版本才可以支持
|
||||
};
|
||||
|
||||
#pragma mark - QQApiObject(分享对象类型)
|
||||
|
||||
// QQApiObject control flags
|
||||
typedef NS_ENUM(NSUInteger,kQQAPICtrlFlag) {
|
||||
kQQAPICtrlFlagQZoneShareOnStart = 0x01,
|
||||
kQQAPICtrlFlagQZoneShareForbid = 0x02,
|
||||
kQQAPICtrlFlagQQShare = 0x04,
|
||||
kQQAPICtrlFlagQQShareFavorites = 0x08, //收藏
|
||||
kQQAPICtrlFlagQQShareDataline = 0x10, //数据线
|
||||
kQQAPICtrlFlagQQShareEnableArk = 0x20, //支持ARK
|
||||
kQQAPICtrlFlagQQShareEnableMiniProgram = 0x40, //支持小程序
|
||||
};
|
||||
|
||||
// 分享到QQ或TIM
|
||||
typedef NS_ENUM(NSUInteger, ShareDestType) {
|
||||
ShareDestTypeQQ = 0,
|
||||
ShareDestTypeTIM,
|
||||
};
|
||||
|
||||
//小程序的类型
|
||||
typedef NS_ENUM(NSUInteger, MiniProgramType) {
|
||||
MiniProgramType_Develop=0, // 开发版
|
||||
MiniProgramType_Test=1, // 测试版
|
||||
MiniProgramType_Online=3, // 正式版,默认
|
||||
MiniProgramType_Preview=4, // 预览版
|
||||
};
|
||||
|
||||
// QQApiObject
|
||||
/** \brief 所有在QQ及插件间发送的数据对象的根类。
|
||||
*/
|
||||
__attribute__((visibility("default"))) @interface QQApiObject : NSObject
|
||||
@property(nonatomic, retain) NSString* title; ///< 标题,最长128个字符
|
||||
@property(nonatomic, retain) NSString* description; ///<简要描述,最长512个字符
|
||||
@property(nonatomic, retain) NSString* universalLink; ///(>=3.3.7)支持第三方传入在互联开放平台注册的universallink
|
||||
@property(nonatomic, assign) uint64_t cflag;
|
||||
/*
|
||||
* 分享到QQ/TIM
|
||||
* SDK根据是否安装对应客户端进行判断,判断顺序:QQ > TIM
|
||||
* 默认分享到QQ,如果QQ未安装检测TIM是否安装
|
||||
*/
|
||||
@property (nonatomic, assign) ShareDestType shareDestType;
|
||||
@end
|
||||
|
||||
// ArkObject
|
||||
/** \brief 支持Ark的根类。
|
||||
*/
|
||||
__attribute__((visibility("default"))) @interface ArkObject : NSObject
|
||||
@property(nonatomic,retain) NSString* arkData; ///< 显示Ark所需的数据,json串,长度暂不限制
|
||||
@property(nonatomic,assign) QQApiObject* qqApiObject; ///<原有老版本的QQApiObject
|
||||
|
||||
- (id)initWithData:(NSString *)arkData qqApiObject:(QQApiObject*)qqApiObject;
|
||||
+ (id)objectWithData:(NSString *)arkData qqApiObject:(QQApiObject*)qqApiObject;
|
||||
@end
|
||||
|
||||
#pragma mark QQ小程序
|
||||
//分享小程序消息 - QQ 8.0.8
|
||||
__attribute__((visibility("default"))) @interface QQApiMiniProgramObject : NSObject
|
||||
@property(nonatomic,retain) QQApiObject* qqApiObject; //原有老版本的QQApiObject
|
||||
@property(nonatomic,retain) NSString* miniAppID; //必填,小程序的AppId(注:必须在QQ互联平台中,将该小程序与分享的App绑定)
|
||||
@property(nonatomic,retain) NSString* miniPath; //必填,小程序的展示路径
|
||||
@property(nonatomic,retain) NSString* webpageUrl; //必填,兼容低版本的网页链接
|
||||
@property(nonatomic,assign) MiniProgramType miniprogramType; //非必填,小程序的类型,默认正式版(3),可选测试版(1)、预览版(4)
|
||||
@end
|
||||
|
||||
//唤起小程序 - QQ 8.1.8
|
||||
__attribute__((visibility("default"))) @interface QQApiLaunchMiniProgramObject : QQApiObject
|
||||
@property(nonatomic,retain) NSString* miniAppID; //必填,小程序的AppId(注:必须在QQ互联平台中,将该小程序与分享的App绑定)
|
||||
@property(nonatomic,retain) NSString* miniPath; //必填,小程序的展示路径
|
||||
@property(nonatomic,assign) MiniProgramType miniprogramType; //非必填,小程序的类型,默认正式版(3),可选测试版(1)、开发版(0)
|
||||
@end
|
||||
// QQApiResultObject
|
||||
/** \brief 用于请求回应的数据类型。
|
||||
<h3>可能错误码及描述如下:</h3>
|
||||
<TABLE>
|
||||
<TR><TD>error</TD><TD>errorDescription</TD><TD>注释</TD></TR>
|
||||
<TR><TD>0</TD><TD>nil</TD><TD>成功</TD></TR>
|
||||
<TR><TD>-1</TD><TD>param error</TD><TD>参数错误</TD></TR>
|
||||
<TR><TD>-2</TD><TD>group code is invalid</TD><TD>该群不在自己的群列表里面</TD></TR>
|
||||
<TR><TD>-3</TD><TD>upload photo failed</TD><TD>上传图片失败</TD></TR>
|
||||
<TR><TD>-4</TD><TD>user give up the current operation</TD><TD>用户放弃当前操作</TD></TR>
|
||||
<TR><TD>-5</TD><TD>client internal error</TD><TD>客户端内部处理错误</TD></TR>
|
||||
</TABLE>
|
||||
*/
|
||||
__attribute__((visibility("default"))) @interface QQApiResultObject : QQApiObject
|
||||
@property(nonatomic,retain) NSString* error; ///<错误
|
||||
@property(nonatomic,retain) NSString* errorDescription; ///<错误描述
|
||||
@property(nonatomic,retain) NSString* extendInfo; ///<扩展信息
|
||||
@end
|
||||
|
||||
// QQApiTextObject
|
||||
/** \brief 文本对象
|
||||
*/
|
||||
@interface QQApiTextObject : QQApiObject
|
||||
@property(nonatomic,retain)NSString* text; ///<文本内容,必填,最长1536个字符
|
||||
|
||||
-(id)initWithText:(NSString*)text; ///<初始化方法
|
||||
+(id)objectWithText:(NSString*)text;///<工厂方法,获取一个QQApiTextObject对象.
|
||||
@end
|
||||
|
||||
// QQApiURLObject
|
||||
typedef NS_ENUM(NSUInteger, QQApiURLTargetType) {
|
||||
QQApiURLTargetTypeNotSpecified = 0x00,
|
||||
QQApiURLTargetTypeAudio = 0x01,
|
||||
QQApiURLTargetTypeVideo = 0x02,
|
||||
QQApiURLTargetTypeNews = 0x03
|
||||
};
|
||||
|
||||
/** @brief URL对象类型。
|
||||
|
||||
包括URL地址,URL地址所指向的目标类型及预览图像。
|
||||
*/
|
||||
__attribute__((visibility("default"))) @interface QQApiURLObject : QQApiObject
|
||||
/**
|
||||
URL地址所指向的目标类型.
|
||||
@note 参见QQApi.h 中的 QQApiURLTargetType 定义.
|
||||
*/
|
||||
@property(nonatomic)QQApiURLTargetType targetContentType;
|
||||
|
||||
@property(nonatomic,retain)NSURL* url; ///<URL地址,必填,最长512个字符
|
||||
@property(nonatomic,retain)NSData* previewImageData;///<预览图像数据,最大1M字节
|
||||
@property(nonatomic, retain) NSURL *previewImageURL; ///<预览图像URL **预览图像数据与预览图像URL可二选一
|
||||
|
||||
/**
|
||||
初始化方法
|
||||
*/
|
||||
-(id)initWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageData:(NSData*)data targetContentType:(QQApiURLTargetType)targetContentType;
|
||||
-(id)initWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageURL:(NSURL*)previewURL targetContentType:(QQApiURLTargetType)targetContentType;
|
||||
/**
|
||||
工厂方法,获取一个QQApiURLObject对象
|
||||
*/
|
||||
+(id)objectWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageData:(NSData*)data targetContentType:(QQApiURLTargetType)targetContentType;
|
||||
+(id)objectWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageURL:(NSURL*)previewURL targetContentType:(QQApiURLTargetType)targetContentType;
|
||||
@end
|
||||
|
||||
// QQApiExtendObject
|
||||
/** @brief 扩展数据类型
|
||||
*/
|
||||
@interface QQApiExtendObject : QQApiObject
|
||||
@property(nonatomic,retain) NSData* data;///<具体数据内容,必填,最大5M字节
|
||||
@property(nonatomic,retain) NSData* previewImageData;///<预览图像,最大1M字节
|
||||
@property(nonatomic,retain) NSArray* imageDataArray;///图片数组(多图暂只支持分享到手机QQ收藏功能)
|
||||
|
||||
/**
|
||||
初始化方法
|
||||
@param data 数据内容
|
||||
@param previewImageData 用于预览的图片
|
||||
@param title 标题
|
||||
@param description 此对象,分享的描述
|
||||
*/
|
||||
- (id)initWithData:(NSData*)data previewImageData:(NSData*)previewImageData title:(NSString*)title description:(NSString*)description;
|
||||
|
||||
/**
|
||||
初始化方法
|
||||
@param data 数据内容
|
||||
@param title 标题
|
||||
@param description 此对象,分享的描述
|
||||
@param imageDataArray 发送的多张图片队列
|
||||
*/
|
||||
- (id)initWithData:(NSData *)data previewImageData:(NSData*)previewImageData title:(NSString *)title description:(NSString *)description imageDataArray:(NSArray *)imageDataArray;
|
||||
|
||||
/**
|
||||
helper方法获取一个autorelease的<code>QQApiExtendObject</code>对象
|
||||
@param data 数据内容
|
||||
@param previewImageData 用于预览的图片
|
||||
@param title 标题
|
||||
@param description 此对象,分享的描述
|
||||
@return
|
||||
一个自动释放的<code>QQApiExtendObject</code>实例
|
||||
*/
|
||||
+ (id)objectWithData:(NSData*)data previewImageData:(NSData*)previewImageData title:(NSString*)title description:(NSString*)description;
|
||||
|
||||
/**
|
||||
helper方法获取一个autorelease的<code>QQApiExtendObject</code>对象
|
||||
@param data 数据内容
|
||||
@param previewImageData 用于预览的图片
|
||||
@param title 标题
|
||||
@param description 此对象,分享的描述
|
||||
@param imageDataArray 发送的多张图片队列
|
||||
@return
|
||||
一个自动释放的<code>QQApiExtendObject</code>实例
|
||||
*/
|
||||
+ (id)objectWithData:(NSData*)data previewImageData:(NSData*)previewImageData title:(NSString*)title description:(NSString*)description imageDataArray:(NSArray*)imageDataArray;
|
||||
|
||||
@end
|
||||
|
||||
// QQApiImageObject
|
||||
/** @brief 图片对象
|
||||
用于分享图片内容的对象,是一个指定为图片类型的<code>QQApiExtendObject</code>
|
||||
*/
|
||||
@interface QQApiImageObject : QQApiExtendObject
|
||||
@end
|
||||
|
||||
// QQApiImageForQQAvatarObject
|
||||
/** @brief 图片对象
|
||||
用于设置QQ头像内容的对象,是一个指定为图片类型的<code>QQApiExtendObject</code>
|
||||
*/
|
||||
@interface QQApiImageForQQAvatarObject : QQApiExtendObject
|
||||
@end
|
||||
/**
|
||||
* @brief 视频对象
|
||||
* 用于设置动态头像
|
||||
* assetURL可传ALAsset的ALAssetPropertyAssetURL,或者PHAsset的localIdentifier
|
||||
从手Q返回的错误码:
|
||||
//第三方设置动态头像结果
|
||||
@"ret=0"//设置成功
|
||||
@"ret=-10&error_des=user cancel"//用户取消设置
|
||||
@"ret=-11&error_des=pasteboard have no video data"//剪切板没有数据
|
||||
@"ret=-12&error_des=export data failed"//从剪切板导出数据到本地失败
|
||||
@"ret=-13&error_des=url param invalid"//sdk传递过来的数据有误
|
||||
@"ret=-14&error_des=video param invalid"//视频的参数不符合要求(检测第三方视频源方案:1、分辨率跟480*480保持一致;2、视频长度0.5s~8s)
|
||||
@"ret=-15&error_des=app authorised failed"//应用鉴权失败
|
||||
@"ret=-16&error_des=upload video failed"//设置头像,上传到后台失败
|
||||
@"ret=-17&error_des=account diff"//账号不一致
|
||||
*/
|
||||
@interface QQApiVideoForQQAvatarObject : QQApiExtendObject
|
||||
@property(nonatomic, retain) NSString *assetURL;
|
||||
@end
|
||||
|
||||
// QQApiImageArrayForFaceCollectionObject
|
||||
/** @brief 图片数组对象
|
||||
用于分享图片组到表情收藏,是一个指定为图片类型的<code>QQApiObject</code>
|
||||
*/
|
||||
@interface QQApiImageArrayForFaceCollectionObject : QQApiObject
|
||||
|
||||
@property(nonatomic,retain) NSArray* imageDataArray;///图片数组
|
||||
|
||||
/**
|
||||
初始化方法
|
||||
@param imageDataArray 图片数组
|
||||
*/
|
||||
- (id)initWithImageArrayData:(NSArray*)imageDataArray;
|
||||
/**
|
||||
helper方法获取一个autorelease的<code>QQApiObject</code>对象
|
||||
@param imageDataArray 发送的多张图片队列
|
||||
@return
|
||||
一个自动释放的<code>QQApiObject</code>实例
|
||||
*/
|
||||
+ (id)objectWithimageDataArray:(NSArray *)imageDataArray;
|
||||
|
||||
@end
|
||||
|
||||
// QQApiImageArrayForQZoneObject
|
||||
/** @brief 图片对象
|
||||
用于分享图片到空间,走写说说路径,是一个指定为图片类型的,当图片数组为空时,默认走文本写说说<code>QQApiObject</code>
|
||||
*/
|
||||
@interface QQApiImageArrayForQZoneObject : QQApiObject
|
||||
|
||||
@property(nonatomic,retain) NSArray* imageDataArray;///图片数组
|
||||
@property(nonatomic,retain) NSDictionary* extMap; // 扩展字段
|
||||
|
||||
/**
|
||||
初始化方法
|
||||
@param imageDataArray 图片数组
|
||||
@param title 写说说的内容,可以为空
|
||||
@param extMap 扩展字段
|
||||
*/
|
||||
- (id)initWithImageArrayData:(NSArray*)imageDataArray title:(NSString*)title extMap:(NSDictionary *)extMap;
|
||||
|
||||
/**
|
||||
helper方法获取一个autorelease的<code>QQApiExtendObject</code>对象
|
||||
@param title 写说说的内容,可以为空
|
||||
@param imageDataArray 发送的多张图片队列
|
||||
@param extMap 扩展字段
|
||||
@return
|
||||
一个自动释放的<code>QQApiExtendObject</code>实例
|
||||
*/
|
||||
+ (id)objectWithimageDataArray:(NSArray*)imageDataArray title:(NSString*)title extMap:(NSDictionary *)extMap;
|
||||
|
||||
@end
|
||||
|
||||
// QQApiVideoForQZoneObject
|
||||
/** @brief 视频对象
|
||||
用于分享视频到空间,走写说说路径<code>QQApiObject</code>,assetURL和videoData两个参数必须设置至少一个参数,如果assetURL设置了忽略videoData参数
|
||||
@param assetURL可传ALAsset的ALAssetPropertyAssetURL,或者PHAsset的localIdentifier
|
||||
@param extMap 扩展字段
|
||||
@param videoData 视频数据,大小不超过50M
|
||||
*/
|
||||
@interface QQApiVideoForQZoneObject : QQApiObject
|
||||
|
||||
@property(nonatomic, retain) NSString *assetURL;
|
||||
@property(nonatomic,retain) NSDictionary* extMap; // 扩展字段
|
||||
@property(nonatomic,retain) NSData* videoData;
|
||||
|
||||
- (id)initWithAssetURL:(NSString*)assetURL title:(NSString*)title extMap:(NSDictionary *)extMap;
|
||||
|
||||
+ (id)objectWithAssetURL:(NSString*)assetURL title:(NSString*)title extMap:(NSDictionary *)extMap;
|
||||
|
||||
- (id)initWithVideoData:(NSData*)videoData title:(NSString*)title extMap:(NSDictionary *)extMap;
|
||||
|
||||
+ (id)objectWithVideoData:(NSData*)videoData title:(NSString*)title extMap:(NSDictionary *)extMap;
|
||||
|
||||
@end
|
||||
|
||||
// QQApiWebImageObject
|
||||
/** @brief 图片对象
|
||||
用于分享网络图片内容的对象,是一个指定网络图片url的: 该类型只在2.9.0的h5分享中才支持,
|
||||
原有的手q分享是不支持该类型的。
|
||||
*/
|
||||
@interface QQApiWebImageObject : QQApiObject
|
||||
|
||||
@property(nonatomic, retain) NSURL *previewImageURL; ///<预览图像URL
|
||||
|
||||
/**
|
||||
初始化方法
|
||||
@param previewImageURL 用于预览的图片
|
||||
@param title 标题
|
||||
@param description 此对象,分享的描述
|
||||
*/
|
||||
- (id)initWithPreviewImageURL:(NSURL*)previewImageURL title:(NSString*)title description:(NSString*)description;
|
||||
|
||||
/**
|
||||
helper方法获取一个autorelease的<code>QQApiWebImageObject</code>对象
|
||||
@param previewImageURL 用于预览的图片
|
||||
@param title 标题
|
||||
@param description 此对象,分享的描述
|
||||
*/
|
||||
+ (id)objectWithPreviewImageURL:(NSURL*)previewImageURL title:(NSString*)title description:(NSString*)description;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
//QQApiFileObject
|
||||
/** @brief 本地文件对象(暂只支持分享到手机QQ数据线功能)
|
||||
用于分享文件内容的对象,是一个指定为文件类型的<code>QQApiExtendObject</code>
|
||||
*/
|
||||
@interface QQApiFileObject : QQApiExtendObject
|
||||
{
|
||||
NSString* _fileName;
|
||||
}
|
||||
@property(nonatomic, retain)NSString* fileName;
|
||||
@end
|
||||
|
||||
// QQApiAudioObject
|
||||
/** @brief 音频URL对象
|
||||
用于分享目标内容为音频的URL的对象
|
||||
*/
|
||||
@interface QQApiAudioObject : QQApiURLObject
|
||||
|
||||
@property (nonatomic, retain) NSURL *flashURL; ///<音频URL地址,最长512个字符
|
||||
|
||||
/**
|
||||
获取一个autorelease的<code>QQApiAudioObject</code>
|
||||
@param url 音频内容的目标URL
|
||||
@param title 分享内容的标题
|
||||
@param description 分享内容的描述
|
||||
@param data 分享内容的预览图像
|
||||
@note 如果url为空,调用<code>QQApi#sendMessage:</code>时将返回FALSE
|
||||
*/
|
||||
+(id)objectWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageData:(NSData*)data;
|
||||
|
||||
/**
|
||||
获取一个autorelease的<code>QQApiAudioObject</code>
|
||||
@param url 音频内容的目标URL
|
||||
@param title 分享内容的标题
|
||||
@param description 分享内容的描述
|
||||
@param previewURL 分享内容的预览图像URL
|
||||
@note 如果url为空,调用<code>QQApi#sendMessage:</code>时将返回FALSE
|
||||
*/
|
||||
+(id)objectWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageURL:(NSURL*)previewURL;
|
||||
|
||||
@end
|
||||
|
||||
// QQApiVideoObject
|
||||
/** @brief 视频URL对象
|
||||
用于分享目标内容为视频的URL的对象
|
||||
|
||||
QQApiVideoObject类型的分享,目前在Android和PC QQ上接收消息时,展现有待完善,待手机QQ版本以后更新支持
|
||||
目前如果要分享视频,推荐使用 QQApiNewsObject 类型
|
||||
*/
|
||||
@interface QQApiVideoObject : QQApiURLObject
|
||||
|
||||
@property (nonatomic, retain) NSURL *flashURL; ///<视频URL地址,最长512个字符
|
||||
|
||||
/**
|
||||
获取一个autorelease的<code>QQApiVideoObject</code>
|
||||
@param url 视频内容的目标URL
|
||||
@param title 分享内容的标题
|
||||
@param description 分享内容的描述
|
||||
@param data 分享内容的预览图像
|
||||
@note 如果url为空,调用<code>QQApi#sendMessage:</code>时将返回FALSE
|
||||
*/
|
||||
+(id)objectWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageData:(NSData*)data;
|
||||
|
||||
/**
|
||||
获取一个autorelease的<code>QQApiVideoObject</code>
|
||||
@param url 视频内容的目标URL
|
||||
@param title 分享内容的标题
|
||||
@param description 分享内容的描述
|
||||
@param previewURL 分享内容的预览图像URL
|
||||
@note 如果url为空,调用<code>QQApi#sendMessage:</code>时将返回FALSE
|
||||
*/
|
||||
+(id)objectWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageURL:(NSURL*)previewURL;
|
||||
|
||||
@end
|
||||
|
||||
// QQApiNewsObject
|
||||
/** @brief 新闻URL对象
|
||||
用于分享目标内容为新闻的URL的对象
|
||||
*/
|
||||
@interface QQApiNewsObject : QQApiURLObject
|
||||
/**
|
||||
获取一个autorelease的<code>QQApiNewsObject</code>
|
||||
@param url 视频内容的目标URL
|
||||
@param title 分享内容的标题
|
||||
@param description 分享内容的描述
|
||||
@param data 分享内容的预览图像
|
||||
@note 如果url为空,调用<code>QQApi#sendMessage:</code>时将返回FALSE
|
||||
*/
|
||||
+(id)objectWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageData:(NSData*)data;
|
||||
|
||||
/**
|
||||
获取一个autorelease的<code>QQApiNewsObject</code>
|
||||
@param url 视频内容的目标URL
|
||||
@param title 分享内容的标题
|
||||
@param description 分享内容的描述
|
||||
@param previewURL 分享内容的预览图像URL
|
||||
@note 如果url为空,调用<code>QQApi#sendMessage:</code>时将返回FALSE
|
||||
*/
|
||||
+(id)objectWithURL:(NSURL*)url title:(NSString*)title description:(NSString*)description previewImageURL:(NSURL*)previewURL;
|
||||
|
||||
@end
|
||||
|
||||
// QQApiCommonContentObject;
|
||||
/** @brief 通用模板类型对象
|
||||
用于分享一个固定显示模板的图文混排对象
|
||||
@note 图片列表和文本列表不能同时为空
|
||||
*/
|
||||
@interface QQApiCommonContentObject : QQApiObject
|
||||
/**
|
||||
预定义的界面布局类型
|
||||
*/
|
||||
@property(nonatomic,assign) unsigned int layoutType;
|
||||
@property(nonatomic,assign) NSData* previewImageData;///<预览图
|
||||
@property(nonatomic,retain) NSArray* textArray;///<文本列表
|
||||
@property(nonatomic,retain) NSArray* pictureDataArray;///<图片列表
|
||||
+(id)objectWithLayoutType:(int)layoutType textArray:(NSArray*)textArray pictureArray:(NSArray*)pictureArray previewImageData:(NSData*)data;
|
||||
/**
|
||||
将一个NSDictionary对象转化为QQApiCommomContentObject,如果无法转换,则返回空
|
||||
*/
|
||||
+(id)objectWithDictionary:(NSDictionary*)dic;
|
||||
-(NSDictionary*)toDictionary;
|
||||
@end
|
||||
|
||||
// QQApiExtraServiceObject;
|
||||
/**
|
||||
@brief OpenSDK扩展支持的服务,通用接口,后续会扩充能力
|
||||
@param serviceID [必选] 扩展支持的服务类型ID,参考官方文档说明
|
||||
@param openID [必选] 授权登录后对该用户的唯一标识
|
||||
@param toUin [可选] 对方的QQ号码
|
||||
@param extraInfo [可选] 扩展字段
|
||||
@note 该接口的使用须先登录
|
||||
*/
|
||||
@interface QQApiExtraServiceObject : QQApiObject
|
||||
@property (nonatomic,retain) NSString* serviceID;
|
||||
@property (nonatomic,retain) NSString* openID;
|
||||
@property (nonatomic,retain) NSString* toUin;
|
||||
@property (nonatomic,retain) NSDictionary* extraInfo;
|
||||
|
||||
- (id)initWithOpenID:(NSString *)openID serviceID:(NSString *)serviceID;
|
||||
+ (id)objecWithOpenID:(NSString *)openID serviceID:(NSString *)serviceID;
|
||||
@end
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Ad item object definition
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/** @brief 广告数据对象
|
||||
*/
|
||||
@interface QQApiAdItem : NSObject
|
||||
@property(nonatomic,retain) NSString* title; ///<名称
|
||||
@property(nonatomic,retain) NSString* description;///<描述
|
||||
@property(nonatomic,retain) NSData* imageData;///<广告图片
|
||||
@property(nonatomic,retain) NSURL* target;///<广告目标链接
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - QQApi请求消息类型
|
||||
|
||||
/**
|
||||
QQApi请求消息类型
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, QQApiInterfaceReqType) {
|
||||
EGETMESSAGEFROMQQREQTYPE = 0, ///< 手Q -> 第三方应用,请求第三方应用向手Q发送消息
|
||||
ESENDMESSAGETOQQREQTYPE = 1, ///< 第三方应用 -> 手Q,第三方应用向手Q分享消息
|
||||
ESHOWMESSAGEFROMQQREQTYPE = 2, ///< 手Q -> 第三方应用,请求第三方应用展现消息中的数据
|
||||
ESENDMESSAGEARKTOQQREQTYPE = 3, ///< 第三方应用 -> 手Q,第三方应用向手Q分享Ark消息
|
||||
ESENDMESSAGE_MINI_TOQQREQTYPE = 4 ///< 第三方应用 -> 手Q,第三方应用向手Q分享小程序消息
|
||||
};
|
||||
|
||||
/**
|
||||
QQApi应答消息类型
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, QQApiInterfaceRespType) {
|
||||
ESHOWMESSAGEFROMQQRESPTYPE = 0, ///< 第三方应用 -> 手Q,第三方应用应答消息展现结果
|
||||
EGETMESSAGEFROMQQRESPTYPE = 1, ///< 第三方应用 -> 手Q,第三方应用回应发往手Q的消息
|
||||
ESENDMESSAGETOQQRESPTYPE = 2 ///< 手Q -> 第三方应用,手Q应答处理分享消息的结果
|
||||
};
|
||||
|
||||
/**
|
||||
QQApi请求消息基类
|
||||
*/
|
||||
@interface QQBaseReq : NSObject
|
||||
|
||||
/** 请求消息类型,参见\ref QQApiInterfaceReqType */
|
||||
@property (nonatomic, assign) int type;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
QQApi应答消息基类
|
||||
*/
|
||||
@interface QQBaseResp : NSObject
|
||||
|
||||
/** 请求处理结果 */
|
||||
@property (nonatomic, copy) NSString* result;
|
||||
|
||||
/** 具体错误描述信息 */
|
||||
@property (nonatomic, copy) NSString* errorDescription;
|
||||
|
||||
/** 应答消息类型,参见\ref QQApiInterfaceRespType */
|
||||
@property (nonatomic, assign) int type;
|
||||
|
||||
/** 扩展信息 */
|
||||
@property (nonatomic, assign) NSString* extendInfo;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
GetMessageFromQQReq请求帮助类
|
||||
*/
|
||||
@interface GetMessageFromQQReq : QQBaseReq
|
||||
|
||||
/**
|
||||
创建一个GetMessageFromQQReq请求实例
|
||||
*/
|
||||
+ (GetMessageFromQQReq *)req;
|
||||
|
||||
@end
|
||||
|
||||
@interface SendMessageToQQReq : QQBaseReq
|
||||
|
||||
/**
|
||||
创建一个SendMessageToQQReq请求实例
|
||||
\param message 具体分享消息实例
|
||||
\return 新创建的SendMessageToQQReq请求实例
|
||||
*/
|
||||
+ (SendMessageToQQReq *)reqWithContent:(QQApiObject *)message;
|
||||
|
||||
/**
|
||||
创建一个支持Ark的SendMessageToQQReq请求实例
|
||||
\param message 具体分享消息实例
|
||||
\return 新创建的SendMessageToQQReq请求实例
|
||||
*/
|
||||
+ (SendMessageToQQReq *)reqWithArkContent:(ArkObject *)message;
|
||||
/**
|
||||
* 创建一个支持小程序的消息请求实例
|
||||
* @param miniMessage 小程序实例对象
|
||||
* @return 消息请求实例
|
||||
*/
|
||||
+(SendMessageToQQReq*) reqWithMiniContent:(QQApiMiniProgramObject *)miniMessage;
|
||||
/** 具体分享消息 */
|
||||
@property (nonatomic, retain) QQApiObject *message;
|
||||
|
||||
/** 支持Ark的具体分享消息 */
|
||||
@property (nonatomic, retain) ArkObject *arkMessage;
|
||||
/** 支持小程序的具体分享消息 */
|
||||
@property (nonatomic, retain) QQApiMiniProgramObject *miniMessage;
|
||||
@end
|
||||
|
||||
/**
|
||||
SendMessageToQQResp应答帮助类
|
||||
*/
|
||||
@interface SendMessageToQQResp : QQBaseResp
|
||||
|
||||
/**
|
||||
创建一个SendMessageToQQResp应答实例
|
||||
\param result 请求处理结果
|
||||
\param errDesp 具体错误描述信息
|
||||
\param extendInfo 扩展信息
|
||||
\return 新创建的SendMessageToQQResp应答实例
|
||||
*/
|
||||
+ (SendMessageToQQResp *)respWithResult:(NSString *)result errorDescription:(NSString *)errDesp extendInfo:(NSString*)extendInfo;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
ShowMessageFromQQReq请求帮助类
|
||||
*/
|
||||
@interface ShowMessageFromQQReq : QQBaseReq
|
||||
|
||||
/**
|
||||
创建一个ShowMessageFromQQReq请求实例
|
||||
\param message 具体待展现消息实例
|
||||
\return 新创建的ShowMessageFromQQReq请求实例
|
||||
*/
|
||||
+ (ShowMessageFromQQReq *)reqWithContent:(QQApiObject *)message;
|
||||
|
||||
/** 具体待展现消息 */
|
||||
@property (nonatomic, retain) QQApiObject *message;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#endif
|
494
ios/Libraries/TencentOpenAPI.framework/Headers/TencentOAuth.h
Normal file
494
ios/Libraries/TencentOpenAPI.framework/Headers/TencentOAuth.h
Normal file
@ -0,0 +1,494 @@
|
||||
///
|
||||
/// \file TencentOAuth.h
|
||||
/// \brief QQ互联开放平台授权登录及相关开放接口实现类
|
||||
///
|
||||
/// Created by Tencent on 12-12-21.
|
||||
/// Copyright (c) 2012年 Tencent. All rights reserved.
|
||||
///
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "sdkdef.h"
|
||||
|
||||
@protocol TencentSessionDelegate;
|
||||
@protocol TencentLoginDelegate;
|
||||
@protocol TencentApiInterfaceDelegate;
|
||||
@protocol TencentWebViewDelegate;
|
||||
|
||||
@class TencentApiReq;
|
||||
@class TencentApiResp;
|
||||
|
||||
typedef NS_ENUM(NSUInteger, TencentAuthorizeState) {
|
||||
kTencentNotAuthorizeState,
|
||||
kTencentSSOAuthorizeState,
|
||||
kTencentWebviewAuthorzieState,
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSUInteger, TencentAuthMode) {
|
||||
kAuthModeClientSideToken,
|
||||
kAuthModeServerSideCode,
|
||||
};
|
||||
|
||||
#pragma mark - TencentOAuth(授权登录及相关开放接口调用)
|
||||
|
||||
/**
|
||||
* \brief TencentOpenAPI授权登录及相关开放接口调用
|
||||
*
|
||||
* TencentOAuth实现授权登录逻辑以及相关开放接口的请求调用
|
||||
*/
|
||||
@interface TencentOAuth : NSObject
|
||||
{
|
||||
NSMutableDictionary* _apiRequests;
|
||||
NSString* _accessToken;
|
||||
NSDate* _expirationDate;
|
||||
id<TencentSessionDelegate> _sessionDelegate;
|
||||
NSString* _localAppId;
|
||||
NSString* _openId;
|
||||
NSString* _redirectURI;
|
||||
NSArray* _permissions;
|
||||
}
|
||||
|
||||
/** Access Token凭证,用于后续访问各开放接口 */
|
||||
@property(nonatomic, copy) NSString* accessToken;
|
||||
|
||||
/** Access Token的失效期 */
|
||||
@property(nonatomic, copy) NSDate* expirationDate;
|
||||
|
||||
/** 已实现的开放接口的回调委托对象 */
|
||||
@property(nonatomic, assign) id<TencentSessionDelegate> sessionDelegate;
|
||||
|
||||
/** 第三方应用在开发过程中设置的URLSchema,用于浏览器登录后后跳到第三方应用 */
|
||||
@property(nonatomic, copy) NSString* localAppId;
|
||||
|
||||
/** 用户授权登录后对该用户的唯一标识 */
|
||||
@property(nonatomic, copy) NSString* openId;
|
||||
|
||||
/** 用户登录成功过后的跳转页面地址 */
|
||||
@property(nonatomic, copy) NSString* redirectURI;
|
||||
|
||||
/** 第三方应用在互联开放平台申请的appID */
|
||||
@property(nonatomic, retain) NSString* appId;
|
||||
|
||||
/** 第三方应用在互联开放平台注册的UniversalLink */
|
||||
@property(nonatomic, retain) NSString* universalLink;
|
||||
|
||||
/** 主要是互娱的游戏设置uin */
|
||||
@property(nonatomic, retain) NSString* uin;
|
||||
|
||||
/** 主要是互娱的游戏设置鉴定票据 */
|
||||
@property(nonatomic, retain) NSString* skey;
|
||||
|
||||
/** 登陆透传的数据 */
|
||||
@property(nonatomic, copy) NSDictionary* passData;
|
||||
|
||||
/** 授权方式(Client Side Token或者Server Side Code) */
|
||||
@property(nonatomic, assign) TencentAuthMode authMode;
|
||||
|
||||
/** union id */
|
||||
@property(nonatomic, retain) NSString* unionid;
|
||||
|
||||
/** 第三方在授权登录/分享 时选择 QQ,还是TIM 。在授权前一定要指定其中一个类型*/
|
||||
@property(nonatomic, assign) TencentAuthShareType authShareType;
|
||||
|
||||
/**
|
||||
* 获取上次登录得到的token
|
||||
*
|
||||
**/
|
||||
- (NSString *)getCachedToken;
|
||||
|
||||
/**
|
||||
* 获取上次登录得到的openid
|
||||
*
|
||||
**/
|
||||
- (NSString *)getCachedOpenID;
|
||||
|
||||
/**
|
||||
* 获取上次登录的token过期日期
|
||||
*
|
||||
**/
|
||||
- (NSDate *)getCachedExpirationDate;
|
||||
|
||||
/**
|
||||
* 上次登录的token是否过期(本地判断)
|
||||
**/
|
||||
- (BOOL)isCachedTokenValid;
|
||||
|
||||
/**
|
||||
* 删除上次登录登录的token信息
|
||||
*
|
||||
**/
|
||||
- (BOOL)deleteCachedToken;
|
||||
|
||||
/**
|
||||
* 用来获得当前sdk的版本号
|
||||
* \return 返回sdk版本号
|
||||
**/
|
||||
|
||||
+ (NSString*)sdkVersion;
|
||||
|
||||
/**
|
||||
* 用来获得当前sdk的小版本号
|
||||
* \return 返回sdk小版本号
|
||||
**/
|
||||
|
||||
+ (NSString*)sdkSubVersion;
|
||||
|
||||
/**
|
||||
* 用来获得当前sdk的是否精简版
|
||||
* \return 返回YES表示精简版
|
||||
**/
|
||||
|
||||
+ (BOOL)isLiteSDK;
|
||||
|
||||
/**
|
||||
* 主要是用来帮助判断是否有登陆被发起,但是还没有过返回结果
|
||||
* \return
|
||||
* kTencentNotAuthorizeState:无授权
|
||||
* kTencentSSOAuthorizeState:有人发起了sso授权但无返回
|
||||
* kTencentWebviewAuthorzieState:有人发起了webview授权还未返回
|
||||
**/
|
||||
|
||||
+ (TencentAuthorizeState *)authorizeState;
|
||||
|
||||
/**
|
||||
* 用来获得当前手机qq的版本号
|
||||
* \return 返回手机qq版本号
|
||||
**/
|
||||
+ (int)iphoneQQVersion __attribute__((deprecated("已过期, 建议删除调用")));
|
||||
|
||||
|
||||
/**
|
||||
* 用来获得当前手机TIM的版本号
|
||||
* \return 返回手机qq版本号
|
||||
**/
|
||||
+ (int)iphoneTIMVersion __attribute__((deprecated("已过期, 建议删除调用")));
|
||||
|
||||
/**
|
||||
* 初始化TencentOAuth对象
|
||||
* \param appId 第三方应用在互联开放平台申请的唯一标识
|
||||
* \param delegate 第三方应用用于接收请求返回结果的委托对象
|
||||
* \return 初始化后的授权登录对象
|
||||
*/
|
||||
- (id)initWithAppId:(NSString *)appId
|
||||
andDelegate:(id<TencentSessionDelegate>)delegate;
|
||||
|
||||
/**
|
||||
* 初始化TencentOAuth对象(>=3.3.7)
|
||||
* \param appId 第三方应用在互联开放平台申请的唯一标识
|
||||
* \param universalLink 第三方应用在互联开放平台注册的universallink,和bundleID一一对应
|
||||
* \param delegate 第三方应用用于接收请求返回结果的委托对象
|
||||
* \return 初始化后的授权登录对象
|
||||
*/
|
||||
- (id)initWithAppId:(NSString *)appId
|
||||
andUniversalLink:(NSString *)universalLink
|
||||
andDelegate:(id<TencentSessionDelegate>)delegate;
|
||||
|
||||
/**
|
||||
* 判断用户手机上是否安装手机QQ
|
||||
* \return YES:安装 NO:没安装
|
||||
*
|
||||
* \note SDK目前已经支持QQ、TIM授权登录及分享功能, 会按照QQ>TIM的顺序进行调用。
|
||||
* 只要用户安装了QQ、TIM中任意一个应用,都可为第三方应用进行授权登录、分享功能。
|
||||
* 第三方应用在接入SDK时不需要判断是否安装QQ、TIM。若有判断安装QQ、TIM的逻辑建议移除。
|
||||
*/
|
||||
+ (BOOL)iphoneQQInstalled;
|
||||
|
||||
/**
|
||||
* 判断用户手机上是否安装手机TIM
|
||||
* \return YES:安装 NO:没安装
|
||||
*
|
||||
* \note SDK目前已经支持QQ、TIM授权登录及分享功能, 会按照QQ>TIM的顺序进行调用。
|
||||
* 只要用户安装了QQ、TIM中任意一个应用,都可为第三方应用进行授权登录、分享功能。
|
||||
* 第三方应用在接入SDK时不需要判断是否安装QQ、TIM。若有判断安装QQ、TIM的逻辑建议移除。
|
||||
*/
|
||||
+ (BOOL)iphoneTIMInstalled;
|
||||
|
||||
/**
|
||||
* 判断用户手机上的手机QQ是否支持SSO登录
|
||||
* \return YES:支持 NO:不支持
|
||||
*/
|
||||
+ (BOOL)iphoneQQSupportSSOLogin __attribute__((deprecated("QQ版本均支持SSO登录。该接口已过期, 建议删除调用")));
|
||||
|
||||
/**
|
||||
* 判断用户手机上的手机TIM是否支持SSO登录
|
||||
* \return YES:支持 NO:不支持
|
||||
*/
|
||||
+ (BOOL)iphoneTIMSupportSSOLogin __attribute__((deprecated("TIM版本均支持SSO登录。该接口已过期, 建议删除调用")));
|
||||
|
||||
/**
|
||||
* 登录授权
|
||||
*
|
||||
* \param permissions 授权信息列
|
||||
*/
|
||||
- (BOOL)authorize:(NSArray *)permissions;
|
||||
|
||||
/**
|
||||
* 登录授权
|
||||
* \param permissions 授权信息列表
|
||||
* \param bInSafari 是否使用safari进行登录.<b>IOS SDK 1.3版本开始此参数废除</b>
|
||||
*/
|
||||
- (BOOL)authorize:(NSArray *)permissions
|
||||
inSafari:(BOOL)bInSafari;
|
||||
|
||||
/**
|
||||
* 登录授权
|
||||
* \param permissions 授权信息列表
|
||||
* \param localAppId 应用APPID
|
||||
* \param bInSafari 是否使用safari进行登录.<b>IOS SDK 1.3版本开始此参数废除</b>
|
||||
*/
|
||||
- (BOOL)authorize:(NSArray *)permissions
|
||||
localAppId:(NSString *)localAppId
|
||||
inSafari:(BOOL)bInSafari;
|
||||
|
||||
/**
|
||||
* 登录授权<web为二维码扫码方式>
|
||||
*
|
||||
* \param permissions 授权信息列
|
||||
*/
|
||||
- (BOOL)authorizeWithQRlogin:(NSArray *)permissions;
|
||||
|
||||
/**
|
||||
* 增量授权,因用户没有授予相应接口调用的权限,需要用户确认是否授权
|
||||
* \param permissions 需增量授权的信息列表
|
||||
* \return 增量授权调用是否成功
|
||||
*/
|
||||
- (BOOL)incrAuthWithPermissions:(NSArray *)permissions;
|
||||
|
||||
/**
|
||||
* 重新授权,因token废除或失效导致接口调用失败,需用户重新授权
|
||||
* \param permissions 授权信息列表,同登录授权
|
||||
* \return 授权调用是否成功
|
||||
*/
|
||||
- (BOOL)reauthorizeWithPermissions:(NSArray *)permissions;
|
||||
|
||||
/**
|
||||
* 获取UnindID,可以根据UnindID的比较来确定OpenID是否属于同一个用户
|
||||
* \return NO未登录,信息不足;YES条件满足,发送请求成功,请等待回调
|
||||
*/
|
||||
- (BOOL)RequestUnionId;
|
||||
|
||||
/**
|
||||
* (静态方法)处理应用拉起协议
|
||||
* \param url 处理被其他应用呼起时的逻辑
|
||||
* \return 处理结果,YES表示成功,NO表示失败
|
||||
*/
|
||||
+ (BOOL)HandleOpenURL:(NSURL *)url;
|
||||
|
||||
/**
|
||||
* (静态方法)sdk是否可以处理应用拉起协议
|
||||
* \param url 处理被其他应用呼起时的逻辑
|
||||
* \return 处理结果,YES表示可以 NO表示不行
|
||||
*/
|
||||
+ (BOOL)CanHandleOpenURL:(NSURL *)url;
|
||||
|
||||
/**
|
||||
* (静态方法)处理应用的UniversalLink拉起协议
|
||||
* \param url 处理被其他应用呼起时的逻辑
|
||||
* \return 处理结果,YES表示成功,NO表示失败
|
||||
*/
|
||||
+ (BOOL)HandleUniversalLink:(NSURL *)url;
|
||||
|
||||
/**
|
||||
* (静态方法)sdk是否可以处理应用的Universallink拉起协议
|
||||
* \param url 处理被其他应用呼起时的逻辑(应用的Universallink链接须满足官网注册时的格式要求)
|
||||
* \return 处理结果,YES表示可以 NO表示不行
|
||||
* 注:在调用其他Universallink相关处理接口之前,均需进行此项判断
|
||||
*/
|
||||
+ (BOOL)CanHandleUniversalLink:(NSURL *)url;
|
||||
|
||||
/**
|
||||
* (静态方法)获取TencentOAuth调用的上一次错误信息
|
||||
*/
|
||||
+ (NSString *)getLastErrorMsg;
|
||||
|
||||
/**
|
||||
* 以Server Side Code模式授权登录时,通过此接口获取返回的code值;
|
||||
* 以Client Side Token模式授权登录时,忽略此接口。
|
||||
*/
|
||||
- (NSString *)getServerSideCode;
|
||||
|
||||
/**
|
||||
* 退出登录(退出登录后,TecentOAuth失效,需要重新初始化)
|
||||
* \param delegate 第三方应用用于接收请求返回结果的委托对象
|
||||
*/
|
||||
- (void)logout:(id<TencentSessionDelegate>)delegate;
|
||||
|
||||
/**
|
||||
* 判断登录态是否有效
|
||||
* \return 处理结果,YES表示有效,NO表示无效,请用户重新登录授权
|
||||
*/
|
||||
- (BOOL)isSessionValid;
|
||||
|
||||
/**
|
||||
* 获取用户个人信息
|
||||
* \return 处理结果,YES表示API调用成功,NO表示API调用失败,登录态失败,重新登录
|
||||
*/
|
||||
- (BOOL)getUserInfo;
|
||||
|
||||
/**
|
||||
* 退出指定API调用
|
||||
* \param userData 用户调用某条API的时候传入的保留参数
|
||||
* \return 处理结果,YES表示成功 NO表示失败
|
||||
*/
|
||||
- (BOOL)cancel:(id)userData;
|
||||
|
||||
/**
|
||||
* CGI类任务创建接口
|
||||
* \param apiURL CGI请求的URL地址
|
||||
* \param method CGI请求方式:"GET","POST"
|
||||
* \param params CGI请求参数字典
|
||||
* \param callback CGI请求结果的回调接口对象
|
||||
* \return CGI请求任务实例,用于取消任务,返回nil代表任务创建失败
|
||||
*/
|
||||
- (TCAPIRequest *)cgiRequestWithURL:(NSURL *)apiURL method:(NSString *)method params:(NSDictionary *)params callback:(id<TCAPIRequestDelegate>)callback;
|
||||
|
||||
/**
|
||||
* TencentOpenApi发送任务统一接口
|
||||
* \param request 请求发送的任务
|
||||
* \param callback 任务发送后的回调地址
|
||||
*/
|
||||
- (BOOL)sendAPIRequest:(TCAPIRequest *)request callback:(id<TCAPIRequestDelegate>)callback;
|
||||
|
||||
- (NSString *)getUserOpenID;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - TencentLoginDelegate(授权登录回调协议)
|
||||
|
||||
/**
|
||||
* \brief TencentLoginDelegate iOS Open SDK 1.3 API回调协议
|
||||
*
|
||||
* 第三方应用实现登录的回调协议
|
||||
*/
|
||||
@protocol TencentLoginDelegate <NSObject>
|
||||
|
||||
@required
|
||||
|
||||
/**
|
||||
* 登录成功后的回调
|
||||
*/
|
||||
- (void)tencentDidLogin;
|
||||
|
||||
/**
|
||||
* 登录失败后的回调
|
||||
* \param cancelled 代表用户是否主动退出登录
|
||||
*/
|
||||
- (void)tencentDidNotLogin:(BOOL)cancelled;
|
||||
|
||||
/**
|
||||
* 登录时网络有问题的回调
|
||||
*/
|
||||
- (void)tencentDidNotNetWork;
|
||||
|
||||
@optional
|
||||
/**
|
||||
* 登录时权限信息的获得
|
||||
*/
|
||||
- (NSArray *)getAuthorizedPermissions:(NSArray *)permissions withExtraParams:(NSDictionary *)extraParams;
|
||||
|
||||
/**
|
||||
* unionID获得
|
||||
*/
|
||||
- (void)didGetUnionID;
|
||||
|
||||
/**
|
||||
* 强制网页登录,包括账号密码登录和二维码登录
|
||||
* return YES时,就算本地有手Q也会打开web界面
|
||||
*/
|
||||
- (BOOL)forceWebLogin;
|
||||
@end
|
||||
|
||||
#pragma mark - TencentSessionDelegate(开放接口回调协议)
|
||||
|
||||
/**
|
||||
* \brief TencentSessionDelegate iOS Open SDK 1.3 API回调协议
|
||||
*
|
||||
* 第三方应用需要实现每条需要调用的API的回调协议
|
||||
*/
|
||||
@protocol TencentSessionDelegate<NSObject, TencentLoginDelegate,
|
||||
TencentWebViewDelegate>
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
* 退出登录的回调
|
||||
*/
|
||||
- (void)tencentDidLogout;
|
||||
|
||||
/**
|
||||
* 因用户未授予相应权限而需要执行增量授权。在用户调用某个api接口时,如果服务器返回操作未被授权,则触发该回调协议接口,由第三方决定是否跳转到增量授权页面,让用户重新授权。
|
||||
* \param tencentOAuth 登录授权对象。
|
||||
* \param permissions 需增量授权的权限列表。
|
||||
* \return 是否仍然回调返回原始的api请求结果。
|
||||
* \note 不实现该协议接口则默认为不开启增量授权流程。若需要增量授权请调用\ref TencentOAuth#incrAuthWithPermissions: \n注意:增量授权时用户可能会修改登录的帐号
|
||||
*/
|
||||
- (BOOL)tencentNeedPerformIncrAuth:(TencentOAuth *)tencentOAuth withPermissions:(NSArray *)permissions;
|
||||
|
||||
/**
|
||||
* [该逻辑未实现]因token失效而需要执行重新登录授权。在用户调用某个api接口时,如果服务器返回token失效,则触发该回调协议接口,由第三方决定是否跳转到登录授权页面,让用户重新授权。
|
||||
* \param tencentOAuth 登录授权对象。
|
||||
* \return 是否仍然回调返回原始的api请求结果。
|
||||
* \note 不实现该协议接口则默认为不开启重新登录授权流程。若需要重新登录授权请调用\ref TencentOAuth#reauthorizeWithPermissions: \n注意:重新登录授权时用户可能会修改登录的帐号
|
||||
*/
|
||||
- (BOOL)tencentNeedPerformReAuth:(TencentOAuth *)tencentOAuth;
|
||||
|
||||
/**
|
||||
* 用户通过增量授权流程重新授权登录,token及有效期限等信息已被更新。
|
||||
* \param tencentOAuth token及有效期限等信息更新后的授权实例对象
|
||||
* \note 第三方应用需更新已保存的token及有效期限等信息。
|
||||
*/
|
||||
- (void)tencentDidUpdate:(TencentOAuth *)tencentOAuth;
|
||||
|
||||
/**
|
||||
* 用户增量授权过程中因取消或网络问题导致授权失败
|
||||
* \param reason 授权失败原因,具体失败原因参见sdkdef.h文件中\ref UpdateFailType
|
||||
*/
|
||||
- (void)tencentFailedUpdate:(UpdateFailType)reason;
|
||||
|
||||
/**
|
||||
* 获取用户个人信息回调
|
||||
* \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
|
||||
* \remarks 正确返回示例: \snippet example/getUserInfoResponse.exp success
|
||||
* 错误返回示例: \snippet example/getUserInfoResponse.exp fail
|
||||
*/
|
||||
- (void)getUserInfoResponse:(APIResponse*) response;
|
||||
|
||||
/**
|
||||
* 社交API统一回调接口
|
||||
* \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
|
||||
* \param message 响应的消息,目前支持‘SendStory’,‘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
|
414
ios/Libraries/TencentOpenAPI.framework/Headers/sdkdef.h
Normal file
414
ios/Libraries/TencentOpenAPI.framework/Headers/sdkdef.h
Normal file
@ -0,0 +1,414 @@
|
||||
///
|
||||
/// \file sdkdef.h
|
||||
/// \brief SDK中相关常量定义
|
||||
///
|
||||
/// Created by Tencent on 12-12-25.
|
||||
/// Copyright (c) 2012年 Tencent. All rights reserved.
|
||||
///
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
/**
|
||||
* \brief 设置sdk的log等级
|
||||
*/
|
||||
typedef enum {
|
||||
TCOLogLevel_Disabled = -1, // 关闭所有log
|
||||
TCOLogLevel_Error = 0,
|
||||
TCOLogLevel_Warning,
|
||||
TCOLogLevel_Info,
|
||||
TCOLogLevel_Debug,
|
||||
} TCOLogLevel;
|
||||
|
||||
/**
|
||||
* \breif 授权/分享 方式
|
||||
*/
|
||||
typedef enum TencentAuthShareType {
|
||||
AuthShareType_QQ,
|
||||
AuthShareType_TIM,
|
||||
}TencentAuthShareType;
|
||||
|
||||
/**
|
||||
* \brief APIResponse.retCode可能的枚举常量
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
URLREQUEST_SUCCEED = 0, /**< 网络请求成功发送至服务器,并且服务器返回数据格式正确
|
||||
* \note 这里包括所请求业务操作失败的情况,例如没有授权等原因导致
|
||||
*/
|
||||
|
||||
URLREQUEST_FAILED = 1, /**< 网络异常,或服务器返回的数据格式不正确导致无法解析 */
|
||||
} REPONSE_RESULT;
|
||||
|
||||
/**
|
||||
* \brief 增量授权失败原因
|
||||
*
|
||||
* \note 增量授权失败不影响原token的有效性(原token已失效的情况除外)
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
kUpdateFailUnknown = 1, ///< 未知原因
|
||||
kUpdateFailUserCancel, ///< 用户取消
|
||||
kUpdateFailNetwork, ///< 网络问题
|
||||
} UpdateFailType;
|
||||
|
||||
/**
|
||||
* \brief 封装服务器返回的结果
|
||||
*
|
||||
* APIResponse用于封装所有请求的返回结果,包括错误码、错误信息、原始返回数据以及返回数据的json格式字典
|
||||
*/
|
||||
@interface APIResponse : NSObject<NSCoding> {
|
||||
int _detailRetCode;
|
||||
int _retCode;
|
||||
int _seq;
|
||||
NSString *_errorMsg;
|
||||
NSDictionary *_jsonResponse;
|
||||
NSString *_message;
|
||||
id _userData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增的详细错误码\n
|
||||
* detailRetCode主要用于区分不同的错误情况,参见\ref OpenSDKError
|
||||
*/
|
||||
@property (nonatomic, assign) int detailRetCode;
|
||||
|
||||
/**
|
||||
* 网络请求是否成功送达服务器,以及服务器返回的数据格式是否正确\n
|
||||
* retCode具体取值可参考\ref REPONSE_RESULT
|
||||
*/
|
||||
@property (nonatomic, assign) int retCode;
|
||||
|
||||
/**
|
||||
* 网络请求对应的递增序列号,方便内部管理
|
||||
*/
|
||||
@property (nonatomic, assign) int seq;
|
||||
|
||||
/**
|
||||
* 错误提示语
|
||||
*/
|
||||
@property (nonatomic, retain) NSString *errorMsg;
|
||||
|
||||
/**
|
||||
* 服务器返回数据的json格式字典\n
|
||||
* 字典内具体参数的命名和含义请参考\ref api_spec
|
||||
*/
|
||||
@property (nonatomic, retain) NSDictionary *jsonResponse;
|
||||
|
||||
/**
|
||||
* 服务器返回的原始数据字符串
|
||||
*/
|
||||
@property (nonatomic, retain) NSString *message;
|
||||
|
||||
/**
|
||||
* 用户保留数据
|
||||
*/
|
||||
@property (nonatomic, retain) id userData;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/**
|
||||
* 用户自定义的保留字段
|
||||
*/
|
||||
FOUNDATION_EXTERN NSString * const PARAM_USER_DATA;
|
||||
|
||||
/**
|
||||
* \name 应用邀请参数字段定义
|
||||
*/
|
||||
///@{
|
||||
|
||||
/** 应用邀请展示图片url的key */
|
||||
FOUNDATION_EXTERN NSString * const PARAM_APP_ICON;
|
||||
|
||||
/** 应用邀请描述文本的key */
|
||||
FOUNDATION_EXTERN NSString * const PARAM_APP_DESC;
|
||||
|
||||
/** 应用邀请好友列表的key */
|
||||
FOUNDATION_EXTERN NSString * const PARAM_APP_INVITED_OPENIDS;
|
||||
|
||||
///@}
|
||||
|
||||
/**
|
||||
* \name sendStory新分享参数字段定义
|
||||
*/
|
||||
///@{
|
||||
|
||||
/** 预填入接受人列表的key */
|
||||
FOUNDATION_EXTERN NSString * const PARAM_SENDSTORY_RECEIVER;
|
||||
|
||||
/** 分享feeds标题的key */
|
||||
FOUNDATION_EXTERN NSString * const PARAM_SENDSTORY_TITLE;
|
||||
|
||||
/** 分享feeds评论内容的key */
|
||||
FOUNDATION_EXTERN NSString * const PARAM_SENDSTORY_COMMENT;
|
||||
|
||||
/** 分享feeds摘要的key */
|
||||
FOUNDATION_EXTERN NSString * const PARAM_SENDSTORY_SUMMARY;
|
||||
|
||||
/** 分享feeds展示图片url的key */
|
||||
FOUNDATION_EXTERN NSString * const PARAM_SENDSTORY_IMAGE;
|
||||
|
||||
/** 分享feeds跳转链接url的key */
|
||||
FOUNDATION_EXTERN NSString * const PARAM_SENDSTORY_URL;
|
||||
|
||||
/** 分享feeds点击操作默认行为的key */
|
||||
FOUNDATION_EXTERN NSString * const PARAM_SENDSTORY_ACT;
|
||||
|
||||
///@}
|
||||
|
||||
/**
|
||||
* \name 设置头像参数字段定义
|
||||
*/
|
||||
///@{
|
||||
|
||||
/** 头像图片数据的key */
|
||||
FOUNDATION_EXTERN NSString * const PARAM_SETUSERHEAD_PIC;
|
||||
|
||||
/** 头像图片文件名的key */
|
||||
FOUNDATION_EXTERN NSString * const PARAM_SETUSERHEAD_FILENAME;
|
||||
|
||||
///@}
|
||||
|
||||
/**
|
||||
* \name 服务器返回数据的参数字段定义
|
||||
*/
|
||||
///@{
|
||||
|
||||
/** 服务器返回码的key */
|
||||
FOUNDATION_EXTERN NSString * const PARAM_RETCODE;
|
||||
|
||||
/** 服务器返回错误信息的key */
|
||||
FOUNDATION_EXTERN NSString * const PARAM_MESSAGE;
|
||||
|
||||
/** 服务器返回额外数据的key */
|
||||
FOUNDATION_EXTERN NSString * const PARAM_DATA;
|
||||
|
||||
///@}
|
||||
|
||||
/**
|
||||
* \name 错误信息相关常量定义
|
||||
*/
|
||||
///@{
|
||||
|
||||
/** 详细错误信息字典中额外信息的key */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorKeyExtraInfo;
|
||||
|
||||
/** 详细错误信息字典中返回码的key */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorKeyRetCode;
|
||||
|
||||
/** 详细错误信息字典中错误语句的key */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorKeyMsg;
|
||||
|
||||
/** 不支持的接口 */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgUnsupportedAPI;
|
||||
|
||||
/** 操作成功 */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgSuccess;
|
||||
|
||||
/** 未知错误 */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgUnknown;
|
||||
|
||||
/** 用户取消 */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgUserCancel;
|
||||
|
||||
/** 请重新登录 */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgReLogin;
|
||||
|
||||
/** 应用没有操作权限 */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgOperationDeny;
|
||||
|
||||
/** 网络异常或没有网络 */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgNetwork;
|
||||
|
||||
/** URL格式或协议错误 */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgURL;
|
||||
|
||||
/** 解析数据出错 */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgDataParse;
|
||||
|
||||
/** 传入参数有误 */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgParam;
|
||||
|
||||
/** 连接超时 */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgTimeout;
|
||||
|
||||
/** 安全问题 */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgSecurity;
|
||||
|
||||
/** 文件读写错误 */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgIO;
|
||||
|
||||
/** 服务器端错误 */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgServer;
|
||||
|
||||
/** 页面错误 */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgWebPage;
|
||||
|
||||
/** 设置头像图片过大 */
|
||||
FOUNDATION_EXTERN NSString * const TCOpenSDKErrorMsgUserHeadPicLarge;
|
||||
|
||||
///@}
|
||||
|
||||
/**
|
||||
* \brief SDK新增详细错误常量
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
kOpenSDKInvalid = -1, ///< 无效的错误码
|
||||
kOpenSDKErrorUnsupportedAPI = -2, ///< 不支持的接口
|
||||
|
||||
/**
|
||||
* \name CommonErrorCode
|
||||
* 公共错误码
|
||||
*/
|
||||
///@{
|
||||
kOpenSDKErrorSuccess = 0, ///< 成功
|
||||
kOpenSDKErrorUnknown, ///< 未知错误
|
||||
kOpenSDKErrorUserCancel, ///< 用户取消
|
||||
kOpenSDKErrorReLogin, ///< token无效或用户未授权相应权限需要重新登录
|
||||
kOpenSDKErrorOperationDeny, ///< 第三方应用没有该api操作的权限
|
||||
///@}
|
||||
|
||||
/**
|
||||
* \name NetworkRelatedErrorCode
|
||||
* 网络相关错误码
|
||||
*/
|
||||
///@{
|
||||
kOpenSDKErrorNetwork, ///< 网络错误,网络不通或连接不到服务器
|
||||
kOpenSDKErrorURL, ///< URL格式或协议错误
|
||||
kOpenSDKErrorDataParse, ///< 数据解析错误,服务器返回的数据解析出错
|
||||
kOpenSDKErrorParam, ///< 传入参数错误
|
||||
kOpenSDKErrorConnTimeout, ///< http连接超时
|
||||
kOpenSDKErrorSecurity, ///< 安全问题
|
||||
kOpenSDKErrorIO, ///< 下载和文件IO错误
|
||||
kOpenSDKErrorServer, ///< 服务器端错误
|
||||
///@}
|
||||
|
||||
/**
|
||||
* \name WebViewRelatedError
|
||||
* webview特有错误
|
||||
*/
|
||||
///@{
|
||||
kOpenSDKErrorWebPage, ///< 页面错误
|
||||
///@}
|
||||
|
||||
/**
|
||||
* \name SetUserHeadRelatedErrorCode
|
||||
* 设置头像自定义错误码段
|
||||
*/
|
||||
///@{
|
||||
kOpenSDKErrorUserHeadPicLarge = 0x010000, ///< 图片过大 设置头像自定义错误码
|
||||
///@}
|
||||
} OpenSDKError;
|
||||
|
||||
/**
|
||||
* \name SDK版本(v1.3)支持的授权列表常量
|
||||
*/
|
||||
///@{
|
||||
|
||||
/** 发表一条说说到QQ空间(<b>需要申请权限</b>) */
|
||||
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_ADD_TOPIC;
|
||||
|
||||
/** 创建一个QQ空间相册(<b>需要申请权限</b>) */
|
||||
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_ADD_ALBUM;
|
||||
|
||||
/** 上传一张照片到QQ空间相册(<b>需要申请权限</b>) */
|
||||
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_UPLOAD_PIC;
|
||||
|
||||
/** 获取用户QQ空间相册列表(<b>需要申请权限</b>) */
|
||||
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_LIST_ALBUM;
|
||||
|
||||
/** 验证是否认证空间粉丝 */
|
||||
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_CHECK_PAGE_FANS;
|
||||
|
||||
/** 获取登录用户自己的详细信息 */
|
||||
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_GET_INFO;
|
||||
|
||||
/** 获取其他用户的详细信息 */
|
||||
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_GET_OTHER_INFO;
|
||||
|
||||
/** 获取会员用户基本信息 */
|
||||
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_GET_VIP_INFO;
|
||||
|
||||
/** 获取会员用户详细信息 */
|
||||
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_GET_VIP_RICH_INFO;
|
||||
|
||||
/** 获取用户信息 */
|
||||
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_GET_USER_INFO;
|
||||
|
||||
/** 移动端获取用户信息 */
|
||||
FOUNDATION_EXTERN NSString *const kOPEN_PERMISSION_GET_SIMPLE_USER_INFO;
|
||||
///@}
|
||||
|
||||
|
||||
/**
|
||||
* \name CGI接口相关参数类型定义
|
||||
*/
|
||||
|
||||
/** 必填的字符串类型参数 */
|
||||
typedef NSString *TCRequiredStr;
|
||||
|
||||
/** 必填的UIImage类型参数 */
|
||||
typedef UIImage *TCRequiredImage;
|
||||
|
||||
/** 必填的整型参数 */
|
||||
typedef NSInteger TCRequiredInt;
|
||||
|
||||
/** 必填的数字类型 */
|
||||
typedef NSNumber *TCRequiredNumber;
|
||||
|
||||
/** 必填的NSData参数 */
|
||||
typedef NSData *TCRequiredData;
|
||||
|
||||
/** 可选的字符串类型参数 */
|
||||
typedef NSString *TCOptionalStr;
|
||||
|
||||
/** 可选的UIImage类型参数 */
|
||||
typedef UIImage *TCOptionalImage;
|
||||
|
||||
/** 可选的整型参数 */
|
||||
typedef NSInteger TCOptionalInt;
|
||||
|
||||
/** 可选的数字类型 */
|
||||
typedef NSNumber *TCOptionalNumber;
|
||||
|
||||
/** 可选的不定类型参数 */
|
||||
typedef id TCRequiredId;
|
||||
///@}
|
||||
|
||||
|
||||
/**
|
||||
* \brief CGI请求的参数字典封装辅助基类
|
||||
*
|
||||
* 将相应属性的值以key-value的形式保存到参数字典中
|
||||
*/
|
||||
@interface TCAPIRequest : NSMutableDictionary
|
||||
|
||||
/** CGI请求的URL地址 */
|
||||
@property (nonatomic, readonly) NSURL *apiURL;
|
||||
|
||||
/** CGI请求方式:"GET","POST" */
|
||||
@property (nonatomic, readonly) NSString *method;
|
||||
|
||||
/**
|
||||
* API参数中的保留字段,可以塞入任意字典支持的类型,再调用完成后会带回给调用方
|
||||
*/
|
||||
@property (nonatomic, retain) TCRequiredId paramUserData;
|
||||
|
||||
/**
|
||||
* APIResponse,API的返回结果
|
||||
*/
|
||||
@property (nonatomic, readonly) APIResponse *response;
|
||||
|
||||
/** 取消相应的CGI请求任务 */
|
||||
- (void)cancel;
|
||||
|
||||
@end
|
||||
|
||||
@protocol TCAPIRequestDelegate <NSObject>
|
||||
@optional
|
||||
- (void)cgiRequest:(TCAPIRequest *)request didResponse:(APIResponse *)response;
|
||||
|
||||
@end
|
||||
|
BIN
ios/Libraries/TencentOpenAPI.framework/TencentOpenAPI
Normal file
BIN
ios/Libraries/TencentOpenAPI.framework/TencentOpenAPI
Normal file
Binary file not shown.
@ -2,11 +2,11 @@
|
||||
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
|
||||
#
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'fake_tencent'
|
||||
s.version = '0.0.1'
|
||||
s.summary = 'A new Flutter plugin.'
|
||||
s.name = 'tencent_kit'
|
||||
s.version = '1.0.0'
|
||||
s.summary = 'A powerful Flutter plugin allowing developers to share with natvie android & iOS Tencent SDKs.'
|
||||
s.description = <<-DESC
|
||||
A new Flutter plugin.
|
||||
A powerful Flutter plugin allowing developers to share with natvie android & iOS Tencent SDKs.
|
||||
DESC
|
||||
s.homepage = 'http://example.com'
|
||||
s.license = { :file => '../LICENSE' }
|
||||
@ -15,9 +15,10 @@ A new Flutter plugin.
|
||||
s.source_files = 'Classes/**/*'
|
||||
s.public_header_files = 'Classes/**/*.h'
|
||||
s.dependency 'Flutter'
|
||||
# 腾讯(QQ)
|
||||
s.static_framework = true
|
||||
s.dependency 'FakeTencent', '~> 3.3.3'
|
||||
s.vendored_frameworks = 'Libraries/*.framework'
|
||||
s.frameworks = 'SystemConfiguration', 'WebKit'
|
||||
# s.libraries = 'stdc++'
|
||||
# s.requires_arc = true
|
||||
|
||||
s.ios.deployment_target = '8.0'
|
||||
end
|
@ -1,11 +0,0 @@
|
||||
library fake_tencent;
|
||||
|
||||
export 'src/domain/tencent_login_resp.dart' hide TencentLoginRespSerializer;
|
||||
export 'src/domain/tencent_resp.dart';
|
||||
export 'src/domain/tencent_share_resp.dart' hide TencentShareRespSerializer;
|
||||
export 'src/domain/tencent_user_info_resp.dart'
|
||||
hide TencentUserInfoRespSerializer;
|
||||
export 'src/tencent.dart';
|
||||
export 'src/tencent_qzone_flag.dart';
|
||||
export 'src/tencent_scene.dart';
|
||||
export 'src/tencent_scope.dart';
|
@ -1,24 +0,0 @@
|
||||
import 'package:jaguar_serializer/jaguar_serializer.dart';
|
||||
import 'package:fake_tencent/src/domain/tencent_resp.dart';
|
||||
|
||||
part 'tencent_login_resp.jser.dart';
|
||||
|
||||
@GenSerializer(nameFormatter: toSnakeCase)
|
||||
class TencentLoginRespSerializer extends Serializer<TencentLoginResp>
|
||||
with _$TencentLoginRespSerializer {}
|
||||
|
||||
class TencentLoginResp extends TencentResp {
|
||||
TencentLoginResp({
|
||||
int ret,
|
||||
String msg,
|
||||
this.openid,
|
||||
this.accessToken,
|
||||
this.expiresIn,
|
||||
this.createAt,
|
||||
}) : super(ret: ret, msg: msg);
|
||||
|
||||
final String openid;
|
||||
final String accessToken;
|
||||
final int expiresIn;
|
||||
final int createAt;
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'tencent_login_resp.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JaguarSerializerGenerator
|
||||
// **************************************************************************
|
||||
|
||||
abstract class _$TencentLoginRespSerializer
|
||||
implements Serializer<TencentLoginResp> {
|
||||
@override
|
||||
Map<String, dynamic> toMap(TencentLoginResp model) {
|
||||
if (model == null) return null;
|
||||
Map<String, dynamic> ret = <String, dynamic>{};
|
||||
setMapValue(ret, 'openid', model.openid);
|
||||
setMapValue(ret, 'access_token', model.accessToken);
|
||||
setMapValue(ret, 'expires_in', model.expiresIn);
|
||||
setMapValue(ret, 'create_at', model.createAt);
|
||||
setMapValue(ret, 'ret', model.ret);
|
||||
setMapValue(ret, 'msg', model.msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@override
|
||||
TencentLoginResp fromMap(Map map) {
|
||||
if (map == null) return null;
|
||||
final obj = new TencentLoginResp(
|
||||
ret: map['ret'] as int ?? getJserDefault('ret'),
|
||||
msg: map['msg'] as String ?? getJserDefault('msg'),
|
||||
openid: map['openid'] as String ?? getJserDefault('openid'),
|
||||
accessToken:
|
||||
map['access_token'] as String ?? getJserDefault('accessToken'),
|
||||
expiresIn: map['expires_in'] as int ?? getJserDefault('expiresIn'),
|
||||
createAt: map['create_at'] as int ?? getJserDefault('createAt'));
|
||||
return obj;
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
import 'package:jaguar_serializer/jaguar_serializer.dart';
|
||||
import 'package:fake_tencent/src/domain/tencent_resp.dart';
|
||||
|
||||
part 'tencent_share_resp.jser.dart';
|
||||
|
||||
@GenSerializer()
|
||||
class TencentShareRespSerializer extends Serializer<TencentShareResp>
|
||||
with _$TencentShareRespSerializer {}
|
||||
|
||||
class TencentShareResp extends TencentResp {
|
||||
TencentShareResp({
|
||||
int ret,
|
||||
String msg,
|
||||
}) : super(ret: ret, msg: msg);
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'tencent_share_resp.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JaguarSerializerGenerator
|
||||
// **************************************************************************
|
||||
|
||||
abstract class _$TencentShareRespSerializer
|
||||
implements Serializer<TencentShareResp> {
|
||||
@override
|
||||
Map<String, dynamic> toMap(TencentShareResp model) {
|
||||
if (model == null) return null;
|
||||
Map<String, dynamic> ret = <String, dynamic>{};
|
||||
setMapValue(ret, 'ret', model.ret);
|
||||
setMapValue(ret, 'msg', model.msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@override
|
||||
TencentShareResp fromMap(Map map) {
|
||||
if (map == null) return null;
|
||||
final obj = new TencentShareResp(
|
||||
ret: map['ret'] as int ?? getJserDefault('ret'),
|
||||
msg: map['msg'] as String ?? getJserDefault('msg'));
|
||||
return obj;
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
import 'package:fake_tencent/src/domain/tencent_resp.dart';
|
||||
import 'package:jaguar_serializer/jaguar_serializer.dart';
|
||||
|
||||
part 'tencent_user_info_resp.jser.dart';
|
||||
|
||||
@GenSerializer(nameFormatter: toSnakeCase)
|
||||
class TencentUserInfoRespSerializer extends Serializer<TencentUserInfoResp>
|
||||
with _$TencentUserInfoRespSerializer {}
|
||||
|
||||
class TencentUserInfoResp extends TencentResp {
|
||||
TencentUserInfoResp({
|
||||
int ret,
|
||||
String msg,
|
||||
this.nickname,
|
||||
this.gender,
|
||||
this.figureurlQq1,
|
||||
this.figureurlQq2,
|
||||
this.figureurl1,
|
||||
this.figureurl2,
|
||||
this.figureurl,
|
||||
this.vip,
|
||||
this.level,
|
||||
this.isYellowVip,
|
||||
this.isYellowYearVip,
|
||||
this.yellowVipLevel,
|
||||
}) : super(ret: ret, msg: msg);
|
||||
|
||||
final String nickname;
|
||||
|
||||
/// 男/女
|
||||
final String gender;
|
||||
final String figureurlQq1;
|
||||
final String figureurlQq2;
|
||||
final String figureurl1;
|
||||
final String figureurl2;
|
||||
final String figureurl;
|
||||
final String vip;
|
||||
final String level;
|
||||
final String isYellowVip;
|
||||
final String isYellowYearVip;
|
||||
final String yellowVipLevel;
|
||||
|
||||
bool isMale() {
|
||||
return gender == '男';
|
||||
}
|
||||
|
||||
bool isFemale() {
|
||||
return gender == '女';
|
||||
}
|
||||
|
||||
String headImgUrl() {
|
||||
if (figureurlQq2 != null && figureurlQq2.isNotEmpty) {
|
||||
return figureurlQq2;
|
||||
}
|
||||
if (figureurlQq1 != null && figureurlQq1.isNotEmpty) {
|
||||
return figureurlQq1;
|
||||
}
|
||||
if (figureurl2 != null && figureurl2.isNotEmpty) {
|
||||
return figureurl2;
|
||||
}
|
||||
if (figureurl1 != null && figureurl1.isNotEmpty) {
|
||||
return figureurl1;
|
||||
}
|
||||
return figureurl;
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'tencent_user_info_resp.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JaguarSerializerGenerator
|
||||
// **************************************************************************
|
||||
|
||||
abstract class _$TencentUserInfoRespSerializer
|
||||
implements Serializer<TencentUserInfoResp> {
|
||||
@override
|
||||
Map<String, dynamic> toMap(TencentUserInfoResp model) {
|
||||
if (model == null) return null;
|
||||
Map<String, dynamic> ret = <String, dynamic>{};
|
||||
setMapValue(ret, 'nickname', model.nickname);
|
||||
setMapValue(ret, 'gender', model.gender);
|
||||
setMapValue(ret, 'figureurl_qq_1', model.figureurlQq1);
|
||||
setMapValue(ret, 'figureurl_qq_2', model.figureurlQq2);
|
||||
setMapValue(ret, 'figureurl_1', model.figureurl1);
|
||||
setMapValue(ret, 'figureurl_2', model.figureurl2);
|
||||
setMapValue(ret, 'figureurl', model.figureurl);
|
||||
setMapValue(ret, 'vip', model.vip);
|
||||
setMapValue(ret, 'level', model.level);
|
||||
setMapValue(ret, 'is_yellow_vip', model.isYellowVip);
|
||||
setMapValue(ret, 'is_yellow_year_vip', model.isYellowYearVip);
|
||||
setMapValue(ret, 'yellow_vip_level', model.yellowVipLevel);
|
||||
setMapValue(ret, 'ret', model.ret);
|
||||
setMapValue(ret, 'msg', model.msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@override
|
||||
TencentUserInfoResp fromMap(Map map) {
|
||||
if (map == null) return null;
|
||||
final obj = new TencentUserInfoResp(
|
||||
ret: map['ret'] as int ?? getJserDefault('ret'),
|
||||
msg: map['msg'] as String ?? getJserDefault('msg'),
|
||||
nickname: map['nickname'] as String ?? getJserDefault('nickname'),
|
||||
gender: map['gender'] as String ?? getJserDefault('gender'),
|
||||
figureurlQq1:
|
||||
map['figureurl_qq_1'] as String ?? getJserDefault('figureurlQq1'),
|
||||
figureurlQq2:
|
||||
map['figureurl_qq_2'] as String ?? getJserDefault('figureurlQq2'),
|
||||
figureurl1:
|
||||
map['figureurl_1'] as String ?? getJserDefault('figureurl1'),
|
||||
figureurl2:
|
||||
map['figureurl_2'] as String ?? getJserDefault('figureurl2'),
|
||||
figureurl: map['figureurl'] as String ?? getJserDefault('figureurl'),
|
||||
vip: map['vip'] as String ?? getJserDefault('vip'),
|
||||
level: map['level'] as String ?? getJserDefault('level'),
|
||||
isYellowVip:
|
||||
map['is_yellow_vip'] as String ?? getJserDefault('isYellowVip'),
|
||||
isYellowYearVip: map['is_yellow_year_vip'] as String ??
|
||||
getJserDefault('isYellowYearVip'),
|
||||
yellowVipLevel: map['yellow_vip_level'] as String ??
|
||||
getJserDefault('yellowVipLevel'));
|
||||
return obj;
|
||||
}
|
||||
}
|
20
lib/src/model/api/tencent_api_resp.dart
Normal file
20
lib/src/model/api/tencent_api_resp.dart
Normal file
@ -0,0 +1,20 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
abstract class TencentApiResp {
|
||||
TencentApiResp({
|
||||
this.ret,
|
||||
this.msg,
|
||||
});
|
||||
|
||||
/// 网络请求成功发送至服务器,并且服务器返回数据格式正确
|
||||
/// 这里包括所请求业务操作失败的情况,例如没有授权等原因导致
|
||||
static const int RET_SUCCESS = 0;
|
||||
|
||||
@JsonKey(
|
||||
defaultValue: RET_SUCCESS,
|
||||
)
|
||||
final int ret;
|
||||
final String msg;
|
||||
|
||||
bool isSuccessful() => ret == RET_SUCCESS;
|
||||
}
|
36
lib/src/model/api/tencent_unionid_resp.dart
Normal file
36
lib/src/model/api/tencent_unionid_resp.dart
Normal file
@ -0,0 +1,36 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'tencent_unionid_resp.g.dart';
|
||||
|
||||
@JsonSerializable(
|
||||
anyMap: true,
|
||||
explicitToJson: true,
|
||||
fieldRename: FieldRename.snake,
|
||||
)
|
||||
class TencentUnionidResp {
|
||||
TencentUnionidResp({
|
||||
this.error,
|
||||
this.errorDescription,
|
||||
this.clientId,
|
||||
this.openid,
|
||||
this.unionid,
|
||||
});
|
||||
|
||||
factory TencentUnionidResp.fromJson(Map<dynamic, dynamic> json) =>
|
||||
_$TencentUnionidRespFromJson(json);
|
||||
|
||||
@JsonKey(
|
||||
defaultValue: ERROR_SUCCESS,
|
||||
)
|
||||
final int error;
|
||||
final String errorDescription;
|
||||
final String clientId;
|
||||
final String openid;
|
||||
final String unionid;
|
||||
|
||||
static const int ERROR_SUCCESS = 0;
|
||||
|
||||
bool isSuccessful() => error == ERROR_SUCCESS;
|
||||
|
||||
Map<dynamic, dynamic> toJson() => _$TencentUnionidRespToJson(this);
|
||||
}
|
26
lib/src/model/api/tencent_unionid_resp.g.dart
Normal file
26
lib/src/model/api/tencent_unionid_resp.g.dart
Normal file
@ -0,0 +1,26 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'tencent_unionid_resp.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
TencentUnionidResp _$TencentUnionidRespFromJson(Map json) {
|
||||
return TencentUnionidResp(
|
||||
error: json['error'] as int ?? 0,
|
||||
errorDescription: json['error_description'] as String,
|
||||
clientId: json['client_id'] as String,
|
||||
openid: json['openid'] as String,
|
||||
unionid: json['unionid'] as String,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$TencentUnionidRespToJson(TencentUnionidResp instance) =>
|
||||
<String, dynamic>{
|
||||
'error': instance.error,
|
||||
'error_description': instance.errorDescription,
|
||||
'client_id': instance.clientId,
|
||||
'openid': instance.openid,
|
||||
'unionid': instance.unionid,
|
||||
};
|
99
lib/src/model/api/tencent_user_info_resp.dart
Normal file
99
lib/src/model/api/tencent_user_info_resp.dart
Normal file
@ -0,0 +1,99 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:tencent_kit/src/model/api/tencent_api_resp.dart';
|
||||
|
||||
part 'tencent_user_info_resp.g.dart';
|
||||
|
||||
@JsonSerializable(
|
||||
anyMap: true,
|
||||
explicitToJson: true,
|
||||
fieldRename: FieldRename.snake,
|
||||
)
|
||||
class TencentUserInfoResp extends TencentApiResp {
|
||||
TencentUserInfoResp({
|
||||
int ret,
|
||||
String msg,
|
||||
this.isLost,
|
||||
this.nickname,
|
||||
this.gender,
|
||||
this.genderType,
|
||||
this.province,
|
||||
this.city,
|
||||
this.year,
|
||||
this.constellation,
|
||||
this.figureurl,
|
||||
this.figureurl1,
|
||||
this.figureurl2,
|
||||
this.figureurlQq,
|
||||
this.figureurlQq1,
|
||||
this.figureurlQq2,
|
||||
this.figureurlType,
|
||||
this.isYellowVip,
|
||||
this.vip,
|
||||
this.yellowVipLevel,
|
||||
this.level,
|
||||
this.isYellowYearVip,
|
||||
}) : super(ret: ret, msg: msg);
|
||||
|
||||
factory TencentUserInfoResp.fromJson(Map<dynamic, dynamic> json) =>
|
||||
_$TencentUserInfoRespFromJson(json);
|
||||
|
||||
final int isLost;
|
||||
final String nickname;
|
||||
final String gender; // 男/女
|
||||
final int genderType; // 男/女 - 1
|
||||
final String province;
|
||||
final String city;
|
||||
final String year;
|
||||
final String constellation;
|
||||
final String figureurl;
|
||||
@JsonKey(
|
||||
name: 'figureurl_1',
|
||||
)
|
||||
final String figureurl1;
|
||||
@JsonKey(
|
||||
name: 'figureurl_2',
|
||||
)
|
||||
final String figureurl2;
|
||||
final String figureurlQq; // 140 * 140
|
||||
@JsonKey(
|
||||
name: 'figureurl_qq_1',
|
||||
)
|
||||
final String figureurlQq1; // 大小为40×40像素的QQ头像URL。
|
||||
@JsonKey(
|
||||
name: 'figureurl_qq_2',
|
||||
)
|
||||
final String
|
||||
figureurlQq2; // 大小为100×100像素的QQ头像URL。需要注意,不是所有的用户都拥有QQ的100x100的头像,但40x40像素则是一定会有。
|
||||
final String figureurlType;
|
||||
final String isYellowVip;
|
||||
final String vip;
|
||||
final String yellowVipLevel;
|
||||
final String level;
|
||||
final String isYellowYearVip;
|
||||
|
||||
bool isMale() {
|
||||
return gender == '男';
|
||||
}
|
||||
|
||||
bool isFemale() {
|
||||
return gender == '女';
|
||||
}
|
||||
|
||||
String headImgUrl() {
|
||||
if (figureurlQq2 != null && figureurlQq2.isNotEmpty) {
|
||||
return figureurlQq2;
|
||||
}
|
||||
if (figureurlQq1 != null && figureurlQq1.isNotEmpty) {
|
||||
return figureurlQq1;
|
||||
}
|
||||
if (figureurl2 != null && figureurl2.isNotEmpty) {
|
||||
return figureurl2;
|
||||
}
|
||||
if (figureurl1 != null && figureurl1.isNotEmpty) {
|
||||
return figureurl1;
|
||||
}
|
||||
return figureurl;
|
||||
}
|
||||
|
||||
Map<dynamic, dynamic> toJson() => _$TencentUserInfoRespToJson(this);
|
||||
}
|
61
lib/src/model/api/tencent_user_info_resp.g.dart
Normal file
61
lib/src/model/api/tencent_user_info_resp.g.dart
Normal file
@ -0,0 +1,61 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'tencent_user_info_resp.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
TencentUserInfoResp _$TencentUserInfoRespFromJson(Map json) {
|
||||
return TencentUserInfoResp(
|
||||
ret: json['ret'] as int ?? 0,
|
||||
msg: json['msg'] as String,
|
||||
isLost: json['is_lost'] as int,
|
||||
nickname: json['nickname'] as String,
|
||||
gender: json['gender'] as String,
|
||||
genderType: json['gender_type'] as int,
|
||||
province: json['province'] as String,
|
||||
city: json['city'] as String,
|
||||
year: json['year'] as String,
|
||||
constellation: json['constellation'] as String,
|
||||
figureurl: json['figureurl'] as String,
|
||||
figureurl1: json['figureurl_1'] as String,
|
||||
figureurl2: json['figureurl_2'] as String,
|
||||
figureurlQq: json['figureurl_qq'] as String,
|
||||
figureurlQq1: json['figureurl_qq_1'] as String,
|
||||
figureurlQq2: json['figureurl_qq_2'] as String,
|
||||
figureurlType: json['figureurl_type'] as String,
|
||||
isYellowVip: json['is_yellow_vip'] as String,
|
||||
vip: json['vip'] as String,
|
||||
yellowVipLevel: json['yellow_vip_level'] as String,
|
||||
level: json['level'] as String,
|
||||
isYellowYearVip: json['is_yellow_year_vip'] as String,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$TencentUserInfoRespToJson(
|
||||
TencentUserInfoResp instance) =>
|
||||
<String, dynamic>{
|
||||
'ret': instance.ret,
|
||||
'msg': instance.msg,
|
||||
'is_lost': instance.isLost,
|
||||
'nickname': instance.nickname,
|
||||
'gender': instance.gender,
|
||||
'gender_type': instance.genderType,
|
||||
'province': instance.province,
|
||||
'city': instance.city,
|
||||
'year': instance.year,
|
||||
'constellation': instance.constellation,
|
||||
'figureurl': instance.figureurl,
|
||||
'figureurl_1': instance.figureurl1,
|
||||
'figureurl_2': instance.figureurl2,
|
||||
'figureurl_qq': instance.figureurlQq,
|
||||
'figureurl_qq_1': instance.figureurlQq1,
|
||||
'figureurl_qq_2': instance.figureurlQq2,
|
||||
'figureurl_type': instance.figureurlType,
|
||||
'is_yellow_vip': instance.isYellowVip,
|
||||
'vip': instance.vip,
|
||||
'yellow_vip_level': instance.yellowVipLevel,
|
||||
'level': instance.level,
|
||||
'is_yellow_year_vip': instance.isYellowYearVip,
|
||||
};
|
34
lib/src/model/sdk/tencent_login_resp.dart
Normal file
34
lib/src/model/sdk/tencent_login_resp.dart
Normal file
@ -0,0 +1,34 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:tencent_kit/src/model/sdk/tencent_sdk_resp.dart';
|
||||
|
||||
part 'tencent_login_resp.g.dart';
|
||||
|
||||
@JsonSerializable(
|
||||
anyMap: true,
|
||||
explicitToJson: true,
|
||||
fieldRename: FieldRename.snake,
|
||||
)
|
||||
class TencentLoginResp extends TencentSdkResp {
|
||||
TencentLoginResp({
|
||||
int ret,
|
||||
String msg,
|
||||
this.openid,
|
||||
this.accessToken,
|
||||
this.expiresIn,
|
||||
this.createAt,
|
||||
}) : super(ret: ret, msg: msg);
|
||||
|
||||
factory TencentLoginResp.fromJson(Map<dynamic, dynamic> json) =>
|
||||
_$TencentLoginRespFromJson(json);
|
||||
|
||||
final String openid;
|
||||
final String accessToken;
|
||||
final int expiresIn;
|
||||
final int createAt;
|
||||
|
||||
bool isExpired() {
|
||||
return DateTime.now().millisecondsSinceEpoch - createAt >= expiresIn * 1000;
|
||||
}
|
||||
|
||||
Map<dynamic, dynamic> toJson() => _$TencentLoginRespToJson(this);
|
||||
}
|
28
lib/src/model/sdk/tencent_login_resp.g.dart
Normal file
28
lib/src/model/sdk/tencent_login_resp.g.dart
Normal file
@ -0,0 +1,28 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'tencent_login_resp.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
TencentLoginResp _$TencentLoginRespFromJson(Map json) {
|
||||
return TencentLoginResp(
|
||||
ret: json['ret'] as int ?? 0,
|
||||
msg: json['msg'] as String,
|
||||
openid: json['openid'] as String,
|
||||
accessToken: json['access_token'] as String,
|
||||
expiresIn: json['expires_in'] as int,
|
||||
createAt: json['create_at'] as int,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$TencentLoginRespToJson(TencentLoginResp instance) =>
|
||||
<String, dynamic>{
|
||||
'ret': instance.ret,
|
||||
'msg': instance.msg,
|
||||
'openid': instance.openid,
|
||||
'access_token': instance.accessToken,
|
||||
'expires_in': instance.expiresIn,
|
||||
'create_at': instance.createAt,
|
||||
};
|
@ -1,8 +1,10 @@
|
||||
abstract class TencentResp {
|
||||
TencentResp({
|
||||
int ret,
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
abstract class TencentSdkResp {
|
||||
TencentSdkResp({
|
||||
this.ret,
|
||||
this.msg,
|
||||
}) : ret = ret ?? RET_SUCCESS;
|
||||
});
|
||||
|
||||
/// 网络请求成功发送至服务器,并且服务器返回数据格式正确
|
||||
/// 这里包括所请求业务操作失败的情况,例如没有授权等原因导致
|
||||
@ -15,6 +17,11 @@ abstract class TencentResp {
|
||||
|
||||
static const int RET_USERCANCEL = -2;
|
||||
|
||||
@JsonKey(
|
||||
defaultValue: RET_SUCCESS,
|
||||
)
|
||||
final int ret;
|
||||
final String msg;
|
||||
|
||||
bool isSuccessful() => ret == RET_SUCCESS;
|
||||
}
|
21
lib/src/model/sdk/tencent_share_resp.dart
Normal file
21
lib/src/model/sdk/tencent_share_resp.dart
Normal file
@ -0,0 +1,21 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:tencent_kit/src/model/sdk/tencent_sdk_resp.dart';
|
||||
|
||||
part 'tencent_share_resp.g.dart';
|
||||
|
||||
@JsonSerializable(
|
||||
anyMap: true,
|
||||
explicitToJson: true,
|
||||
fieldRename: FieldRename.snake,
|
||||
)
|
||||
class TencentShareResp extends TencentSdkResp {
|
||||
TencentShareResp({
|
||||
int ret,
|
||||
String msg,
|
||||
}) : super(ret: ret, msg: msg);
|
||||
|
||||
factory TencentShareResp.fromJson(Map<dynamic, dynamic> json) =>
|
||||
_$TencentShareRespFromJson(json);
|
||||
|
||||
Map<dynamic, dynamic> toJson() => _$TencentShareRespToJson(this);
|
||||
}
|
20
lib/src/model/sdk/tencent_share_resp.g.dart
Normal file
20
lib/src/model/sdk/tencent_share_resp.g.dart
Normal file
@ -0,0 +1,20 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'tencent_share_resp.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
TencentShareResp _$TencentShareRespFromJson(Map json) {
|
||||
return TencentShareResp(
|
||||
ret: json['ret'] as int ?? 0,
|
||||
msg: json['msg'] as String,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$TencentShareRespToJson(TencentShareResp instance) =>
|
||||
<String, dynamic>{
|
||||
'ret': instance.ret,
|
||||
'msg': instance.msg,
|
||||
};
|
@ -1,39 +1,37 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:fake_tencent/src/domain/tencent_login_resp.dart';
|
||||
import 'package:fake_tencent/src/domain/tencent_share_resp.dart';
|
||||
import 'package:fake_tencent/src/domain/tencent_user_info_resp.dart';
|
||||
import 'package:fake_tencent/src/tencent_qzone_flag.dart';
|
||||
import 'package:fake_tencent/src/tencent_scene.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:tencent_kit/src/model/api/tencent_unionid_resp.dart';
|
||||
import 'package:tencent_kit/src/model/api/tencent_user_info_resp.dart';
|
||||
import 'package:tencent_kit/src/model/sdk/tencent_login_resp.dart';
|
||||
import 'package:tencent_kit/src/model/sdk/tencent_share_resp.dart';
|
||||
import 'package:tencent_kit/src/tencent_constant.dart';
|
||||
|
||||
///
|
||||
class Tencent {
|
||||
///
|
||||
Tencent() {
|
||||
_channel.setMethodCallHandler(_handleMethod);
|
||||
}
|
||||
|
||||
static const String _METHOD_REGISTERAPP = 'registerApp';
|
||||
static const String _METHOD_ISQQINSTALLED = 'isQQInstalled';
|
||||
static const String _METHOD_ISQQSUPPORTSSOLOGIN = 'isQQSupportSSOLogin';
|
||||
static const String _METHOD_ISINSTALLED = 'isInstalled';
|
||||
static const String _METHOD_LOGIN = 'login';
|
||||
static const String _METHOD_LOGOUT = 'logout';
|
||||
static const String _METHOD_GETUSERINFO = 'getUserInfo';
|
||||
static const String _METHOD_SHAREMOOD = 'shareMood';
|
||||
static const String _METHOD_SHAREIMAGE = 'shareImage';
|
||||
static const String _METHOD_SHAREMUSIC = 'shareMusic';
|
||||
static const String _METHOD_SHAREWEBPAGE = 'shareWebpage';
|
||||
|
||||
static const String _METHOD_ONLOGINRESP = 'onLoginResp';
|
||||
static const String _METHOD_ONGETUSERINFORESP = 'onGetUserInfoResp';
|
||||
static const String _METHOD_ONSHARERESP = "onShareResp";
|
||||
|
||||
static const String _ARGUMENT_KEY_APPID = 'appId';
|
||||
static const String _ARGUMENT_KEY_UNIVERSALLINK = 'universalLink';
|
||||
static const String _ARGUMENT_KEY_SCOPE = 'scope';
|
||||
static const String _ARGUMENT_KEY_OPENID = 'openId';
|
||||
static const String _ARGUMENT_KEY_ACCESSTOKEN = 'accessToken';
|
||||
static const String _ARGUMENT_KEY_EXPIRESIN = 'expiresIn';
|
||||
static const String _ARGUMENT_KEY_CREATEAT = 'createAt';
|
||||
static const String _ARGUMENT_KEY_SCENE = 'scene';
|
||||
static const String _ARGUMENT_KEY_TITLE = 'title';
|
||||
static const String _ARGUMENT_KEY_SUMMARY = 'summary';
|
||||
@ -48,67 +46,62 @@ class Tencent {
|
||||
static const String _SCHEME_FILE = 'file';
|
||||
|
||||
final MethodChannel _channel =
|
||||
const MethodChannel('v7lin.github.io/fake_tencent');
|
||||
const MethodChannel('v7lin.github.io/tencent_kit');
|
||||
|
||||
final StreamController<TencentLoginResp> _loginRespStreamController =
|
||||
StreamController<TencentLoginResp>.broadcast();
|
||||
|
||||
final StreamController<TencentUserInfoResp> _userInfoRespStreamController =
|
||||
StreamController<TencentUserInfoResp>.broadcast();
|
||||
|
||||
final StreamController<TencentShareResp> _shareRespStreamController =
|
||||
StreamController<TencentShareResp>.broadcast();
|
||||
|
||||
Future<void> registerApp({
|
||||
@required String appId,
|
||||
}) {
|
||||
assert(appId != null && appId.isNotEmpty);
|
||||
return _channel.invokeMethod(
|
||||
_METHOD_REGISTERAPP,
|
||||
<String, dynamic>{
|
||||
_ARGUMENT_KEY_APPID: appId,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<dynamic> _handleMethod(MethodCall call) async {
|
||||
switch (call.method) {
|
||||
case _METHOD_ONLOGINRESP:
|
||||
_loginRespStreamController.add(TencentLoginRespSerializer()
|
||||
.fromMap(call.arguments as Map<dynamic, dynamic>));
|
||||
break;
|
||||
case _METHOD_ONGETUSERINFORESP:
|
||||
_userInfoRespStreamController.add(TencentUserInfoRespSerializer()
|
||||
.fromMap(call.arguments as Map<dynamic, dynamic>));
|
||||
_loginRespStreamController.add(
|
||||
TencentLoginResp.fromJson(call.arguments as Map<dynamic, dynamic>));
|
||||
break;
|
||||
case _METHOD_ONSHARERESP:
|
||||
_shareRespStreamController.add(TencentShareRespSerializer()
|
||||
.fromMap(call.arguments as Map<dynamic, dynamic>));
|
||||
_shareRespStreamController.add(
|
||||
TencentShareResp.fromJson(call.arguments as Map<dynamic, dynamic>));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// 向 Open_SDK 注册
|
||||
Future<void> registerApp({
|
||||
@required String appId,
|
||||
String universalLink,
|
||||
}) {
|
||||
assert(appId != null && appId.isNotEmpty);
|
||||
assert(universalLink == null || universalLink.isNotEmpty);
|
||||
final Map<String, dynamic> map = <String, dynamic>{
|
||||
_ARGUMENT_KEY_APPID: appId,
|
||||
// _ARGUMENT_KEY_UNIVERSALLINK: universalLink,
|
||||
};
|
||||
if (universalLink != null) {
|
||||
map[_ARGUMENT_KEY_UNIVERSALLINK] = universalLink;
|
||||
}
|
||||
|
||||
/// 兼容 iOS 空安全 -> NSNull
|
||||
return _channel.invokeMethod(
|
||||
_METHOD_REGISTERAPP,
|
||||
map,
|
||||
);
|
||||
}
|
||||
|
||||
/// 登录
|
||||
Stream<TencentLoginResp> loginResp() {
|
||||
return _loginRespStreamController.stream;
|
||||
}
|
||||
|
||||
/// 用户信息
|
||||
Stream<TencentUserInfoResp> userInfoResp() {
|
||||
return _userInfoRespStreamController.stream;
|
||||
}
|
||||
|
||||
/// 分享
|
||||
Stream<TencentShareResp> shareResp() {
|
||||
return _shareRespStreamController.stream;
|
||||
}
|
||||
|
||||
Future<bool> isQQInstalled() async {
|
||||
return (await _channel.invokeMethod(_METHOD_ISQQINSTALLED)) as bool;
|
||||
}
|
||||
|
||||
Future<bool> isQQSupportSSOLogin() async {
|
||||
return (await _channel.invokeMethod(_METHOD_ISQQSUPPORTSSOLOGIN)) as bool;
|
||||
/// 检查QQ是否已安装
|
||||
Future<bool> isInstalled() async {
|
||||
return (await _channel.invokeMethod(_METHOD_ISINSTALLED)) as bool;
|
||||
}
|
||||
|
||||
/// 登录
|
||||
@ -130,24 +123,62 @@ class Tencent {
|
||||
}
|
||||
|
||||
/// 用户信息
|
||||
Future<void> getUserInfo({
|
||||
@required String openId,
|
||||
/// https://wiki.connect.qq.com/get_user_info
|
||||
Future<TencentUserInfoResp> getUserInfo({
|
||||
@required String appId,
|
||||
@required String openid,
|
||||
@required String accessToken,
|
||||
@required int expiresIn,
|
||||
@required int createAt,
|
||||
}) {
|
||||
assert(openId != null && openId.isNotEmpty);
|
||||
assert(appId != null && appId.isNotEmpty);
|
||||
assert(openid != null && openid.isNotEmpty);
|
||||
assert(accessToken != null && accessToken.isNotEmpty);
|
||||
assert(expiresIn != null && expiresIn > 0);
|
||||
return _channel.invokeMethod(
|
||||
_METHOD_GETUSERINFO,
|
||||
<String, dynamic>{
|
||||
_ARGUMENT_KEY_OPENID: openId,
|
||||
_ARGUMENT_KEY_ACCESSTOKEN: accessToken,
|
||||
_ARGUMENT_KEY_EXPIRESIN: expiresIn,
|
||||
_ARGUMENT_KEY_CREATEAT: createAt,
|
||||
},
|
||||
);
|
||||
return HttpClient()
|
||||
.getUrl(Uri.parse(
|
||||
'https://graph.qq.com/user/get_user_info?access_token=$accessToken&oauth_consumer_key=$appId&openid=$openid'))
|
||||
.then((HttpClientRequest request) {
|
||||
return request.close();
|
||||
}).then((HttpClientResponse response) async {
|
||||
if (response.statusCode == HttpStatus.ok) {
|
||||
ContentType contentType = response.headers.contentType;
|
||||
Encoding encoding = Encoding.getByName(contentType?.charset) ?? utf8;
|
||||
String content = await encoding.decodeStream(response);
|
||||
return TencentUserInfoResp.fromJson(
|
||||
json.decode(content) as Map<dynamic, dynamic>);
|
||||
}
|
||||
throw HttpException(
|
||||
'HttpResponse statusCode: ${response.statusCode}, reasonPhrase: ${response.reasonPhrase}.');
|
||||
});
|
||||
}
|
||||
|
||||
/// UnionID
|
||||
/// https://wiki.connect.qq.com/unionid%E4%BB%8B%E7%BB%8D
|
||||
Future<TencentUnionidResp> getUnionId({
|
||||
@required String accessToken,
|
||||
String unionid = '1',
|
||||
}) {
|
||||
assert(accessToken != null && accessToken.isNotEmpty);
|
||||
return HttpClient()
|
||||
.getUrl(Uri.parse(
|
||||
'https://graph.qq.com/oauth2.0/me?access_token=$accessToken&unionid=$unionid'))
|
||||
.then((HttpClientRequest request) {
|
||||
return request.close();
|
||||
}).then((HttpClientResponse response) async {
|
||||
if (response.statusCode == HttpStatus.ok) {
|
||||
ContentType contentType = response.headers.contentType;
|
||||
Encoding encoding = Encoding.getByName(contentType?.charset) ?? utf8;
|
||||
String callback = await encoding.decodeStream(response);
|
||||
// 腾讯有毒 callback( $json );
|
||||
RegExp exp = RegExp(r'callback\( (.*) \)\;');
|
||||
Match match = exp.firstMatch(callback);
|
||||
if (match.groupCount == 1) {
|
||||
String content = match.group(1);
|
||||
return TencentUnionidResp.fromJson(
|
||||
json.decode(content) as Map<dynamic, dynamic>);
|
||||
}
|
||||
}
|
||||
throw HttpException(
|
||||
'HttpResponse statusCode: ${response.statusCode}, reasonPhrase: ${response.reasonPhrase}.');
|
||||
});
|
||||
}
|
||||
|
||||
/// 分享 - 说说
|
||||
@ -166,7 +197,7 @@ class Tencent {
|
||||
assert(imageUri != null && imageUri.isScheme(_SCHEME_FILE));
|
||||
});
|
||||
}
|
||||
Map<String, dynamic> map = <String, dynamic>{
|
||||
final Map<String, dynamic> map = <String, dynamic>{
|
||||
_ARGUMENT_KEY_SCENE: scene,
|
||||
// _ARGUMENT_KEY_SUMMARY: summary,
|
||||
// _ARGUMENT_KEY_IMAGEURIS: imageUris != null ? new List.generate(imageUris.length, (int index) {
|
||||
@ -177,17 +208,14 @@ class Tencent {
|
||||
|
||||
/// 兼容 iOS 空安全 -> NSNull
|
||||
if (summary != null && summary.isNotEmpty) {
|
||||
map.putIfAbsent(_ARGUMENT_KEY_SUMMARY, () => summary);
|
||||
map[_ARGUMENT_KEY_SUMMARY] = summary;
|
||||
}
|
||||
if (imageUris != null && imageUris.isNotEmpty) {
|
||||
map.putIfAbsent(
|
||||
_ARGUMENT_KEY_IMAGEURIS,
|
||||
() => List<String>.generate(imageUris.length, (int index) {
|
||||
return imageUris[index].toString();
|
||||
}));
|
||||
map[_ARGUMENT_KEY_IMAGEURIS] =
|
||||
imageUris.map((Uri imageUri) => imageUri.toString()).toList();
|
||||
}
|
||||
if (videoUri != null) {
|
||||
map.putIfAbsent(_ARGUMENT_KEY_VIDEOURI, () => videoUri.toString());
|
||||
map[_ARGUMENT_KEY_VIDEOURI] = videoUri.toString();
|
||||
}
|
||||
return _channel.invokeMethod(_METHOD_SHAREMOOD, map);
|
||||
}
|
||||
@ -201,7 +229,7 @@ class Tencent {
|
||||
}) {
|
||||
assert(scene == TencentScene.SCENE_QQ);
|
||||
assert(imageUri != null && imageUri.isScheme(_SCHEME_FILE));
|
||||
Map<String, dynamic> map = <String, dynamic>{
|
||||
final Map<String, dynamic> map = <String, dynamic>{
|
||||
_ARGUMENT_KEY_SCENE: scene,
|
||||
_ARGUMENT_KEY_IMAGEURI: imageUri.toString(),
|
||||
// _ARGUMENT_KEY_APPNAME: appName,
|
||||
@ -210,7 +238,7 @@ class Tencent {
|
||||
|
||||
/// 兼容 iOS 空安全 -> NSNull
|
||||
if (appName != null && appName.isNotEmpty) {
|
||||
map.putIfAbsent(_ARGUMENT_KEY_APPNAME, () => appName);
|
||||
map[_ARGUMENT_KEY_APPNAME] = appName;
|
||||
}
|
||||
return _channel.invokeMethod(_METHOD_SHAREIMAGE, map);
|
||||
}
|
||||
@ -230,7 +258,7 @@ class Tencent {
|
||||
assert(title != null && title.isNotEmpty);
|
||||
assert(musicUrl != null && musicUrl.isNotEmpty);
|
||||
assert(targetUrl != null && targetUrl.isNotEmpty);
|
||||
Map<String, dynamic> map = <String, dynamic>{
|
||||
final Map<String, dynamic> map = <String, dynamic>{
|
||||
_ARGUMENT_KEY_SCENE: scene,
|
||||
_ARGUMENT_KEY_TITLE: title,
|
||||
// _ARGUMENT_KEY_SUMMARY: summary,
|
||||
@ -243,13 +271,13 @@ class Tencent {
|
||||
|
||||
/// 兼容 iOS 空安全 -> NSNull
|
||||
if (summary != null && summary.isNotEmpty) {
|
||||
map.putIfAbsent(_ARGUMENT_KEY_SUMMARY, () => summary);
|
||||
map[_ARGUMENT_KEY_SUMMARY] = summary;
|
||||
}
|
||||
if (imageUri != null) {
|
||||
map.putIfAbsent(_ARGUMENT_KEY_IMAGEURI, () => imageUri.toString());
|
||||
map[_ARGUMENT_KEY_IMAGEURI] = imageUri.toString();
|
||||
}
|
||||
if (appName != null && appName.isNotEmpty) {
|
||||
map.putIfAbsent(_ARGUMENT_KEY_APPNAME, () => appName);
|
||||
map[_ARGUMENT_KEY_APPNAME] = appName;
|
||||
}
|
||||
return _channel.invokeMethod(_METHOD_SHAREMUSIC, map);
|
||||
}
|
||||
@ -266,7 +294,7 @@ class Tencent {
|
||||
}) {
|
||||
assert(title != null && title.isNotEmpty);
|
||||
assert(targetUrl != null && targetUrl.isNotEmpty);
|
||||
Map<String, dynamic> map = <String, dynamic>{
|
||||
final Map<String, dynamic> map = <String, dynamic>{
|
||||
_ARGUMENT_KEY_SCENE: scene,
|
||||
_ARGUMENT_KEY_TITLE: title,
|
||||
// _ARGUMENT_KEY_SUMMARY: summary,
|
||||
@ -278,13 +306,13 @@ class Tencent {
|
||||
|
||||
/// 兼容 iOS 空安全 -> NSNull
|
||||
if (summary != null && summary.isNotEmpty) {
|
||||
map.putIfAbsent(_ARGUMENT_KEY_SUMMARY, () => summary);
|
||||
map[_ARGUMENT_KEY_SUMMARY] = summary;
|
||||
}
|
||||
if (imageUri != null) {
|
||||
map.putIfAbsent(_ARGUMENT_KEY_IMAGEURI, () => imageUri.toString());
|
||||
map[_ARGUMENT_KEY_IMAGEURI] = imageUri.toString();
|
||||
}
|
||||
if (appName != null && appName.isNotEmpty) {
|
||||
map.putIfAbsent(_ARGUMENT_KEY_APPNAME, () => appName);
|
||||
map[_ARGUMENT_KEY_APPNAME] = appName;
|
||||
}
|
||||
return _channel.invokeMethod(_METHOD_SHAREWEBPAGE, map);
|
||||
}
|
||||
|
@ -43,3 +43,26 @@ class TencentScope {
|
||||
/// 所有权限
|
||||
static const String ALL = 'all';
|
||||
}
|
||||
|
||||
class TencentScene {
|
||||
TencentScene._();
|
||||
|
||||
/// QQ
|
||||
static const int SCENE_QQ = 0;
|
||||
|
||||
/// QZone
|
||||
static const int SCENE_QZONE = 1;
|
||||
}
|
||||
|
||||
class TencentQZoneFlag {
|
||||
TencentQZoneFlag._();
|
||||
|
||||
/// 默认是不隐藏分享到QZone按钮且不自动打开分享到QZone的对话框
|
||||
static const int DEFAULT = 0;
|
||||
|
||||
/// 分享时自动打开分享到QZone的对话框
|
||||
static const int AUTO_OPEN = 1;
|
||||
|
||||
/// 分享时隐藏分享到QZone按钮
|
||||
static const int ITEM_HIDE = 2;
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
class TencentQZoneFlag {
|
||||
TencentQZoneFlag._();
|
||||
|
||||
/// 默认是不隐藏分享到QZone按钮且不自动打开分享到QZone的对话框
|
||||
static const int DEFAULT = 0;
|
||||
|
||||
/// 分享时自动打开分享到QZone的对话框
|
||||
static const int AUTO_OPEN = 1;
|
||||
|
||||
/// 分享时隐藏分享到QZone按钮
|
||||
static const int ITEM_HIDE = 2;
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
class TencentScene {
|
||||
TencentScene._();
|
||||
|
||||
/// QQ
|
||||
static const int SCENE_QQ = 0;
|
||||
|
||||
/// QZone
|
||||
static const int SCENE_QZONE = 1;
|
||||
}
|
10
lib/tencent_kit.dart
Normal file
10
lib/tencent_kit.dart
Normal file
@ -0,0 +1,10 @@
|
||||
library tencent_kit;
|
||||
|
||||
export 'src/model/api/tencent_api_resp.dart';
|
||||
export 'src/model/api/tencent_unionid_resp.dart';
|
||||
export 'src/model/api/tencent_user_info_resp.dart';
|
||||
export 'src/model/sdk/tencent_login_resp.dart';
|
||||
export 'src/model/sdk/tencent_sdk_resp.dart';
|
||||
export 'src/model/sdk/tencent_share_resp.dart';
|
||||
export 'src/tencent.dart';
|
||||
export 'src/tencent_constant.dart';
|
32
pubspec.yaml
32
pubspec.yaml
@ -1,6 +1,6 @@
|
||||
name: fake_tencent
|
||||
description: A powerful tencent plugin for Flutter.
|
||||
version: 0.3.4
|
||||
name: tencent_kit
|
||||
description: A powerful Flutter plugin allowing developers to share or authorize with natvie android & iOS Tencent SDKs.
|
||||
version: 1.0.0
|
||||
author: v7lin <v7lin@qq.com>
|
||||
homepage: https://github.com/v7lin/fake_tencent
|
||||
|
||||
@ -11,24 +11,24 @@ dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
meta: '>=1.1.6 <2.0.0'
|
||||
|
||||
jaguar_serializer: '>=2.2.12 <3.0.0'
|
||||
json_annotation: '>=2.0.0 <4.0.0'
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
pedantic: '>=1.4.0 <3.0.0'
|
||||
path: ^1.6.4
|
||||
path_provider: ^1.4.0
|
||||
|
||||
path: ^1.6.2
|
||||
fake_path_provider: ^0.0.1
|
||||
okhttp_kit: ^1.0.0
|
||||
|
||||
pedantic:
|
||||
|
||||
build_runner:
|
||||
jaguar_serializer_cli:
|
||||
json_serializable:
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://www.dartlang.org/tools/pub/pubspec
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
||||
# The following section is specific to Flutter.
|
||||
flutter:
|
||||
@ -37,8 +37,8 @@ flutter:
|
||||
# be modified. They are used by the tooling to maintain consistency when
|
||||
# adding or updating assets for this project.
|
||||
plugin:
|
||||
androidPackage: io.github.v7lin.faketencent
|
||||
pluginClass: FakeTencentPlugin
|
||||
androidPackage: io.github.v7lin.tencent_kit
|
||||
pluginClass: TencentKitPlugin
|
||||
|
||||
# To add assets to your plugin package, add an assets section, like this:
|
||||
# assets:
|
||||
@ -46,10 +46,10 @@ flutter:
|
||||
# - images/a_dot_ham.jpeg
|
||||
#
|
||||
# For details regarding assets in packages, see
|
||||
# https://flutter.io/assets-and-images/#from-packages
|
||||
# https://flutter.dev/assets-and-images/#from-packages
|
||||
#
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.io/assets-and-images/#resolution-aware.
|
||||
# https://flutter.dev/assets-and-images/#resolution-aware.
|
||||
|
||||
# To add custom fonts to your plugin package, add a fonts section here,
|
||||
# in this "flutter" section. Each entry in this list should have a
|
||||
@ -69,4 +69,4 @@ flutter:
|
||||
# weight: 700
|
||||
#
|
||||
# For details regarding fonts in packages, see
|
||||
# https://flutter.io/custom-fonts/#from-packages
|
||||
# https://flutter.dev/custom-fonts/#from-packages
|
||||
|
@ -1 +0,0 @@
|
||||
void main() {}
|
@ -1,33 +0,0 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:fake_tencent/src/domain/tencent_login_resp.dart';
|
||||
import 'package:fake_tencent/src/domain/tencent_share_resp.dart';
|
||||
import 'package:fake_tencent/src/domain/tencent_user_info_resp.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
test('smoke test - jaguar_serializer', () {
|
||||
TencentLoginResp loginResp = TencentLoginRespSerializer().fromMap(json.decode(
|
||||
'{"ret":0,"access_token":"D3A4D352A06D897D6FD4DED2B8BEEA46","openid":"A13514A5E6385A1D56E1D845303C5FDE","expires_in":7776000}')
|
||||
as Map<dynamic, dynamic>);
|
||||
expect(loginResp.ret, equals(0));
|
||||
expect(loginResp.openid, equals('A13514A5E6385A1D56E1D845303C5FDE'));
|
||||
expect(loginResp.accessToken, equals('D3A4D352A06D897D6FD4DED2B8BEEA46'));
|
||||
expect(loginResp.expiresIn, equals(7776000));
|
||||
|
||||
TencentUserInfoResp userInfoResp = TencentUserInfoRespSerializer().fromMap(
|
||||
json.decode(
|
||||
'{"ret":0,"msg":"","is_lost":1,"gender":"男","is_yellow_vip":"0","city":"福州","year":"1989","level":"0","figureurl_2":"http://qzapp.qlogo.cn/qzapp/222222/942FEA70050EEAFBD4DCE2C1FC775E56/100","figureurl_1":"http://qzapp.qlogo.cn/qzapp/222222/942FEA70050EEAFBD4DCE2C1FC775E56/50","is_yellow_year_vip":"0","province":"福建","constellation":"","figureurl":"http://qzapp.qlogo.cn/qzapp/222222/942FEA70050EEAFBD4DCE2C1FC775E56/30","figureurl_type":"1","figureurl_qq":"http://thirdqq.qlogo.cn/g?b=oidb&k=aicFesDxFa5P0dImvuYicSGw&s=140","nickname":"qquser","yellow_vip_level":"0","figureurl_qq_1":"http://thirdqq.qlogo.cn/g?b=oidb&k=aicFesDxFa5P0dImvuYicSGw&s=40","vip":"0","figureurl_qq_2":"http://thirdqq.qlogo.cn/g?b=oidb&k=aicFesDxFa5P0dImvuYicSGw&s=100"}')
|
||||
as Map<dynamic, dynamic>);
|
||||
expect(userInfoResp.ret, equals(0));
|
||||
expect(userInfoResp.nickname, equals('qquser'));
|
||||
expect(
|
||||
userInfoResp.figureurlQq1,
|
||||
equals(
|
||||
'http://thirdqq.qlogo.cn/g?b=oidb&k=aicFesDxFa5P0dImvuYicSGw&s=40'));
|
||||
|
||||
TencentShareResp shareResp = TencentShareRespSerializer()
|
||||
.fromMap(json.decode('{"msg":""}') as Map<dynamic, dynamic>);
|
||||
expect(shareResp.ret, equals(0));
|
||||
});
|
||||
}
|
18
test/tencent_kit_test.dart
Normal file
18
test/tencent_kit_test.dart
Normal file
@ -0,0 +1,18 @@
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
const MethodChannel channel = MethodChannel('v7lin.github.io/tencent_kit');
|
||||
|
||||
setUp(() {
|
||||
channel.setMockMethodCallHandler((MethodCall methodCall) async {});
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
channel.setMockMethodCallHandler(null);
|
||||
});
|
||||
|
||||
test('smoke test', () async {});
|
||||
}
|
Reference in New Issue
Block a user