mirror of
https://github.com/RxReader/tencent_kit.git
synced 2025-06-18 17:29:32 +08:00
feature 5.0.0
This commit is contained in:
133
README.md
133
README.md
@ -14,9 +14,9 @@ flutter版腾讯(QQ)SDK
|
|||||||
* [Flutter版深度链接](https://github.com/RxReader/link_kit)
|
* [Flutter版深度链接](https://github.com/RxReader/link_kit)
|
||||||
* [Flutter版walle渠道打包工具](https://github.com/RxReader/walle_kit)
|
* [Flutter版walle渠道打包工具](https://github.com/RxReader/walle_kit)
|
||||||
|
|
||||||
## dart/flutter 私服
|
## Dart/Flutter Pub 私服
|
||||||
|
|
||||||
* [simple_pub_server](https://github.com/rxreader/simple_pub_server)
|
* [simple_pub_server](https://github.com/RxReader/simple_pub_server)
|
||||||
|
|
||||||
## 相关文档
|
## 相关文档
|
||||||
|
|
||||||
@ -25,13 +25,9 @@ flutter版腾讯(QQ)SDK
|
|||||||
* [QQ 创建、填写及校验UniversalLinks](https://wiki.connect.qq.com/%E5%A1%AB%E5%86%99%E5%8F%8A%E6%A0%A1%E9%AA%8Cuniversallinks)
|
* [QQ 创建、填写及校验UniversalLinks](https://wiki.connect.qq.com/%E5%A1%AB%E5%86%99%E5%8F%8A%E6%A0%A1%E9%AA%8Cuniversallinks)
|
||||||
* [Apple Universal Links](https://developer.apple.com/library/archive/documentation/General/Conceptual/AppSearch/UniversalLinks.html)
|
* [Apple Universal Links](https://developer.apple.com/library/archive/documentation/General/Conceptual/AppSearch/UniversalLinks.html)
|
||||||
|
|
||||||
## FEATURE
|
|
||||||
|
|
||||||
* 5.x.y 通过配置 pubspec.yaml 和 cli 抹平 Android/iOS 平台的复杂配置
|
|
||||||
|
|
||||||
## 开始使用
|
## 开始使用
|
||||||
|
|
||||||
### android
|
### Android
|
||||||
|
|
||||||
* 接入
|
* 接入
|
||||||
|
|
||||||
@ -49,93 +45,52 @@ android {
|
|||||||
# 混淆已打入 Library,随 Library 引用,自动添加到 apk 打包混淆
|
# 混淆已打入 Library,随 Library 引用,自动添加到 apk 打包混淆
|
||||||
```
|
```
|
||||||
|
|
||||||
### ios
|
### iOS
|
||||||
|
|
||||||
* 申明
|
|
||||||
|
|
||||||
```
|
```
|
||||||
出于插件的基本需求,将 SDK 的 module.modulemap 内容修改
|
# 不需要做任何额外接入工作
|
||||||
|
# 配置已集成到脚本里
|
||||||
|
```
|
||||||
|
|
||||||
改前
|
* Universal Links
|
||||||
module TencentOpenApi{
|
|
||||||
umbrella header "TencentOpenApiUmbrellaHeader.h"
|
|
||||||
export *
|
|
||||||
}
|
|
||||||
|
|
||||||
改后
|
apple-app-site-association - 通过 https://${your applinks domain}/.well-known/apple-app-site-association 链接可访问
|
||||||
framework module TencentOpenApi{
|
|
||||||
umbrella header "TencentOpenApiUmbrellaHeader.h"
|
示例:
|
||||||
export *
|
|
||||||
|
https://${your applinks domain}/universal_link/${example_app}/qq_conn/${appId}
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"applinks": {
|
||||||
|
"apps": [],
|
||||||
|
"details": [
|
||||||
|
{
|
||||||
|
"appID": "${your team id}.${your app bundle id}",
|
||||||
|
"paths": [
|
||||||
|
"/universal_link/${example_app}/qq_conn/${your tencent app id}/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
* 接入
|
> ⚠️ 很多 SDK 都会用到 universal_link,可为不同 SDK 分配不同的 path 以作区分
|
||||||
|
|
||||||
```
|
### Flutter
|
||||||
在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>
|
|
||||||
<array>
|
|
||||||
<string>tim</string>
|
|
||||||
<string>mqq</string>
|
|
||||||
<string>mqqapi</string>
|
|
||||||
<string>mqqbrowser</string>
|
|
||||||
<string>mttbrowser</string>
|
|
||||||
<string>mqqOpensdkSSoLogin</string>
|
|
||||||
<string>mqqopensdkapiV2</string>
|
|
||||||
<string>mqqopensdkapiV4</string>
|
|
||||||
<string>mqzone</string>
|
|
||||||
<string>mqzoneopensdk</string>
|
|
||||||
<string>mqzoneopensdkapi</string>
|
|
||||||
<string>mqzoneopensdkapi19</string>
|
|
||||||
<string>mqzoneopensdkapiV2</string>
|
|
||||||
<string>mqqapiwallet</string>
|
|
||||||
<string>mqqopensdkfriend</string>
|
|
||||||
<string>mqqopensdkavatar</string>
|
|
||||||
<string>mqqopensdkminiapp</string>
|
|
||||||
<string>mqqopensdkdataline</string>
|
|
||||||
<string>mqqgamebindinggroup</string>
|
|
||||||
<string>mqqopensdkgrouptribeshare</string>
|
|
||||||
<string>tencentapi.qq.reqContent</string>
|
|
||||||
<string>tencentapi.qzone.reqContent</string>
|
|
||||||
<string>mqqthirdappgroup</string>
|
|
||||||
<string>mqqopensdklaunchminiapp</string>
|
|
||||||
<string>mqqopensdkproxylogin</string>
|
|
||||||
<string>mqqopensdknopasteboard</string>
|
|
||||||
<string>mqqopensdkcheckauth</string>
|
|
||||||
</array>
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
Universal Links
|
|
||||||
|
|
||||||
Capabilities -> Associated Domain -> Domain -> applinks:${your applinks}
|
|
||||||
```
|
|
||||||
|
|
||||||
### flutter
|
|
||||||
|
|
||||||
|分享类型|说说(图/文/视频)|文本|图片|音乐|视频|网页|
|
|分享类型|说说(图/文/视频)|文本|图片|音乐|视频|网页|
|
||||||
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||||
|QQ|不支持|不支持|支持|支持|不支持|支持|
|
|QQ|不支持|不支持|支持|支持|不支持|支持|
|
||||||
|QZone|支持|不支持|不支持|不支持|不支持|支持|
|
|QZone|支持|不支持|不支持|不支持|不支持|支持|
|
||||||
|
|
||||||
* ⚠️⚠️⚠️ registerApp 前必须先调用 setIsPermissionGranted [issues/60](https://github.com/RxReader/tencent_kit/issues/60) [issues/79](https://github.com/RxReader/tencent_kit/issues/79)
|
* 注意
|
||||||
|
|
||||||
* break change
|
⚠️⚠️⚠️ registerApp 前必须先调用 setIsPermissionGranted [issues/60](https://github.com/RxReader/tencent_kit/issues/60) [issues/79](https://github.com/RxReader/tencent_kit/issues/79)
|
||||||
* 4.0.0: 按标准插件书写重构
|
|
||||||
* 3.1.0: 新增 setIsPermissionGranted 函数,设置是否已授权获取设备信息/是否同意隐私协议
|
|
||||||
* 3.0.0: 重构
|
|
||||||
* 2.1.0: nullsafety & 不再支持 Android embedding v1 & Tencent 单例
|
|
||||||
|
|
||||||
* compat
|
* 兼容
|
||||||
* flutter 2.5 兼容问题 [issues/54](https://github.com/RxReader/tencent_kit/issues/54)
|
flutter 2.5 兼容问题 [issues/54](https://github.com/RxReader/tencent_kit/issues/54)
|
||||||
```
|
```
|
||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
installer.pods_project.targets.each do |target|
|
installer.pods_project.targets.each do |target|
|
||||||
@ -149,23 +104,21 @@ Capabilities -> Associated Domain -> Domain -> applinks:${your applinks}
|
|||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
* snapshot
|
* 配置
|
||||||
|
|
||||||
```
|
```yaml
|
||||||
dependencies:
|
|
||||||
tencent_kit:
|
|
||||||
git:
|
|
||||||
url: https://github.com/rxreader/tencent_kit.git
|
|
||||||
```
|
|
||||||
|
|
||||||
* release
|
|
||||||
|
|
||||||
```
|
|
||||||
dependencies:
|
dependencies:
|
||||||
tencent_kit: ^${latestTag}
|
tencent_kit: ^${latestTag}
|
||||||
|
# tencent_kit:
|
||||||
|
# git:
|
||||||
|
# url: https://github.com/rxreader/tencent_kit.git
|
||||||
|
|
||||||
|
tencent_kit:
|
||||||
|
app_id: ${your tencent app id}
|
||||||
|
universal_link: https://${your applinks domain}/universal_link/${example_app}/qq_conn/${your tencent app id}/
|
||||||
```
|
```
|
||||||
|
|
||||||
* example
|
## 示例
|
||||||
|
|
||||||
[示例](./example/lib/main.dart)
|
[示例](./example/lib/main.dart)
|
||||||
|
|
||||||
|
@ -9,7 +9,8 @@ import 'package:tencent_kit_example/api/model/tencent_api_resp.dart';
|
|||||||
import 'package:tencent_kit_example/api/model/tencent_unionid_resp.dart';
|
import 'package:tencent_kit_example/api/model/tencent_unionid_resp.dart';
|
||||||
import 'package:tencent_kit_example/api/tencent_api.dart';
|
import 'package:tencent_kit_example/api/tencent_api.dart';
|
||||||
|
|
||||||
const String _TENCENT_APPID = 'your tencent appId';
|
const String _TENCENT_APPID = 'your tencent app id';
|
||||||
|
const String _UNIVERSAL_LINK = 'your tencent universal link';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(MyApp());
|
runApp(MyApp());
|
||||||
@ -85,7 +86,7 @@ class _HomeState extends State<Home> {
|
|||||||
ListTile(
|
ListTile(
|
||||||
title: Text('注册APP'),
|
title: Text('注册APP'),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await TencentKitPlatform.instance.registerApp(appId: _TENCENT_APPID);
|
await TencentKitPlatform.instance.registerApp(appId: _TENCENT_APPID, universalLink: _UNIVERSAL_LINK);
|
||||||
_showTips('注册APP', '注册成功');
|
_showTips('注册APP', '注册成功');
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -91,3 +91,7 @@ flutter:
|
|||||||
#
|
#
|
||||||
# For details regarding fonts from package dependencies,
|
# For details regarding fonts from package dependencies,
|
||||||
# see https://flutter.dev/custom-fonts/#from-packages
|
# see https://flutter.dev/custom-fonts/#from-packages
|
||||||
|
|
||||||
|
tencent_kit:
|
||||||
|
app_id: 123456789
|
||||||
|
universal_link: https://www.yourdomain.com/universal_link/example_app/qq_conn/123456789/
|
||||||
|
@ -6,14 +6,23 @@
|
|||||||
pubspec = YAML.load_file(File.join('..', 'pubspec.yaml'))
|
pubspec = YAML.load_file(File.join('..', 'pubspec.yaml'))
|
||||||
library_version = pubspec['version'].gsub('+', '-')
|
library_version = pubspec['version'].gsub('+', '-')
|
||||||
|
|
||||||
|
current_dir = Dir.pwd
|
||||||
|
calling_dir = File.dirname(__FILE__)
|
||||||
|
project_dir = calling_dir.slice(0..(calling_dir.index('/.symlinks')))
|
||||||
|
root_project_dir = calling_dir.slice(0..(calling_dir.index('/ios/.symlinks')))
|
||||||
|
cfg = YAML.load_file(File.join(root_project_dir, 'pubspec.yaml'))
|
||||||
|
if cfg['tencent_kit'] && (cfg['tencent_kit']['app_id'] && cfg['tencent_kit']['universal_link'])
|
||||||
|
app_id = cfg['tencent_kit']['app_id']
|
||||||
|
universal_link = cfg['tencent_kit']['universal_link']
|
||||||
|
system("ruby #{current_dir}/tencent_setup.rb -a #{app_id} -u #{universal_link} -p #{project_dir} -n Runner.xcodeproj")
|
||||||
|
end
|
||||||
|
|
||||||
Pod::Spec.new do |s|
|
Pod::Spec.new do |s|
|
||||||
s.name = 'tencent_kit'
|
s.name = 'tencent_kit'
|
||||||
s.version = library_version
|
s.version = library_version
|
||||||
s.summary = 'A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Tencent SDKs.'
|
s.summary = pubspec['description']
|
||||||
s.description = <<-DESC
|
s.description = pubspec['description']
|
||||||
A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Tencent SDKs.
|
s.homepage = pubspec['homepage']
|
||||||
DESC
|
|
||||||
s.homepage = 'http://example.com'
|
|
||||||
s.license = { :file => '../LICENSE' }
|
s.license = { :file => '../LICENSE' }
|
||||||
s.author = { 'Your Company' => 'email@example.com' }
|
s.author = { 'Your Company' => 'email@example.com' }
|
||||||
s.source = { :path => '.' }
|
s.source = { :path => '.' }
|
||||||
|
156
ios/tencent_setup.rb
Normal file
156
ios/tencent_setup.rb
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
#
|
||||||
|
# 参考文献
|
||||||
|
# https://github.com/firebase/flutterfire/blob/master/packages/firebase_crashlytics/firebase_crashlytics/ios/crashlytics_add_upload_symbols
|
||||||
|
# https://github.com/MagicalWater/Base-APP-Env/blob/master/fastlane/actions/xcode_parse.rb
|
||||||
|
#
|
||||||
|
|
||||||
|
require 'xcodeproj'
|
||||||
|
require 'plist'
|
||||||
|
require 'optparse'
|
||||||
|
|
||||||
|
# Dictionary to hold command line arguments
|
||||||
|
options_dict = {}
|
||||||
|
|
||||||
|
# Parse command line arguments into options_dict
|
||||||
|
OptionParser.new do |options|
|
||||||
|
options.banner = "Setup the QQ to an Xcode target."
|
||||||
|
|
||||||
|
options.on("-p", "--projectDirectory=DIRECTORY", String, "Directory of the Xcode project") do |dir|
|
||||||
|
options_dict[:project_dir] = dir
|
||||||
|
end
|
||||||
|
|
||||||
|
options.on("-n", "--projectName=NAME", String, "Name of the Xcode project (ex: Runner.xcodeproj)") do |name|
|
||||||
|
options_dict[:project_name] = name
|
||||||
|
end
|
||||||
|
|
||||||
|
options.on("-a", "--appId=APPID", String, "App ID for QQ") do |opts|
|
||||||
|
options_dict[:app_id] = opts
|
||||||
|
end
|
||||||
|
|
||||||
|
options.on("-u", "--universalLink=UNIVERSALLINK", String, "Universal Link for QQ") do |opts|
|
||||||
|
options_dict[:universal_link] = opts
|
||||||
|
end
|
||||||
|
end.parse!
|
||||||
|
|
||||||
|
# Minimum required arguments are a project directory and project name
|
||||||
|
unless (options_dict[:project_dir] and options_dict[:project_name])
|
||||||
|
abort("Must provide a project directory and project name.\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Path to the Xcode project to modify
|
||||||
|
project_path = File.join(options_dict[:project_dir], options_dict[:project_name])
|
||||||
|
|
||||||
|
unless (File.exist?(project_path))
|
||||||
|
abort("Project at #{project_path} does not exist. Please check paths manually.\n");
|
||||||
|
end
|
||||||
|
|
||||||
|
# Actually open and modify the project
|
||||||
|
project = Xcodeproj::Project.open(project_path)
|
||||||
|
project.targets.each do |target|
|
||||||
|
if (target.name == "Runner")
|
||||||
|
app_id = options_dict[:app_id]
|
||||||
|
universal_link = options_dict[:universal_link]
|
||||||
|
applinks = "applinks:#{URI.parse(universal_link).host}"
|
||||||
|
|
||||||
|
sectionObject = {}
|
||||||
|
project.objects.each do |object|
|
||||||
|
if object.uuid == target.uuid
|
||||||
|
sectionObject = object
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
sectionObject.build_configurations.each do |config|
|
||||||
|
infoplist = config.build_settings["INFOPLIST_FILE"]
|
||||||
|
if (!infoplist)
|
||||||
|
puts("INFOPLIST_FILE is not exist")
|
||||||
|
exit(0)
|
||||||
|
end
|
||||||
|
infoplistFile = File.join(options_dict[:project_dir], infoplist)
|
||||||
|
if !File.exist?(infoplistFile)
|
||||||
|
puts("#{infoplist} is not exist")
|
||||||
|
exit(0)
|
||||||
|
end
|
||||||
|
result = Plist.parse_xml(infoplistFile, marshal: false)
|
||||||
|
if (!result)
|
||||||
|
result = {}
|
||||||
|
end
|
||||||
|
urlTypes = result["CFBundleURLTypes"]
|
||||||
|
if (!urlTypes)
|
||||||
|
urlTypes = []
|
||||||
|
result["CFBundleURLTypes"] = urlTypes
|
||||||
|
end
|
||||||
|
isUrlTypeExist = urlTypes.any? { |urlType| urlType["CFBundleURLSchemes"] && (urlType["CFBundleURLSchemes"].include? "tencent#{app_id}") }
|
||||||
|
if (!isUrlTypeExist)
|
||||||
|
urlTypes << {
|
||||||
|
"CFBundleTypeRole": "Editor",
|
||||||
|
"CFBundleURLName": "tencent",
|
||||||
|
"CFBundleURLSchemes": [ "tencent#{app_id}" ]
|
||||||
|
}
|
||||||
|
File.write(infoplistFile, Plist::Emit.dump(result))
|
||||||
|
end
|
||||||
|
queriesSchemes = result["LSApplicationQueriesSchemes"]
|
||||||
|
if (!queriesSchemes)
|
||||||
|
queriesSchemes = []
|
||||||
|
result["LSApplicationQueriesSchemes"] = queriesSchemes
|
||||||
|
end
|
||||||
|
tencentSchemes = [
|
||||||
|
"mqq",
|
||||||
|
"mqqapi",
|
||||||
|
"tim",
|
||||||
|
"mqqopensdknopasteboard",
|
||||||
|
"mqqopensdknopasteboardios16",
|
||||||
|
"mqqopensdkapiV2",
|
||||||
|
"mqqgamebindinggroup",
|
||||||
|
"mqqopensdkavatar",
|
||||||
|
"mqqopensdkfriend",
|
||||||
|
"mqqopensdklaunchminiapp",
|
||||||
|
"mqzone",
|
||||||
|
"tencentapi.qq.reqContent",
|
||||||
|
"tencentapi.qzone.reqContent",
|
||||||
|
"mqqthirdappgroup",
|
||||||
|
"mqqopensdkminiapp",
|
||||||
|
]
|
||||||
|
if (tencentSchemes.any? { |scheme| !(queriesSchemes.include? scheme)} )
|
||||||
|
tencentSchemes.each do |scheme|
|
||||||
|
if (!(queriesSchemes.include? scheme))
|
||||||
|
queriesSchemes << scheme
|
||||||
|
end
|
||||||
|
end
|
||||||
|
File.write(infoplistFile, Plist::Emit.dump(result))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
sectionObject.build_configurations.each do |config|
|
||||||
|
codeSignEntitlements = config.build_settings["CODE_SIGN_ENTITLEMENTS"]
|
||||||
|
if (!codeSignEntitlements)
|
||||||
|
codeSignEntitlements = "Runner/Runner.entitlements"
|
||||||
|
config.build_settings["CODE_SIGN_ENTITLEMENTS"] = codeSignEntitlements
|
||||||
|
project.save()
|
||||||
|
end
|
||||||
|
codeSignEntitlementsFile = File.join(options_dict[:project_dir], codeSignEntitlements)
|
||||||
|
if !File.exist?(codeSignEntitlementsFile)
|
||||||
|
content = Plist::Emit.dump({})
|
||||||
|
File.write(codeSignEntitlementsFile, content)
|
||||||
|
end
|
||||||
|
runnerTargetMainGroup = project.main_group.find_subpath('Runner', false)
|
||||||
|
isRefExist = runnerTargetMainGroup.files.any? { |file| file.path.include? File.basename(codeSignEntitlementsFile) }
|
||||||
|
if !isRefExist
|
||||||
|
runnerTargetMainGroup.new_reference(File.basename(codeSignEntitlementsFile))
|
||||||
|
project.save()
|
||||||
|
end
|
||||||
|
result = Plist.parse_xml(codeSignEntitlementsFile, marshal: false)
|
||||||
|
if (!result)
|
||||||
|
result = {}
|
||||||
|
end
|
||||||
|
domains = result["com.apple.developer.associated-domains"]
|
||||||
|
if (!domains)
|
||||||
|
domains = []
|
||||||
|
result["com.apple.developer.associated-domains"] = domains
|
||||||
|
end
|
||||||
|
isApplinksExist = domains.include? applinks
|
||||||
|
if (!isApplinksExist)
|
||||||
|
domains << applinks
|
||||||
|
File.write(codeSignEntitlementsFile, Plist::Emit.dump(result))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Reference in New Issue
Block a user