mirror of
https://github.com/RxReader/tencent_kit.git
synced 2025-06-18 01:03:33 +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版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)
|
||||
* [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 打包混淆
|
||||
```
|
||||
|
||||
### ios
|
||||
|
||||
* 申明
|
||||
### iOS
|
||||
|
||||
```
|
||||
出于插件的基本需求,将 SDK 的 module.modulemap 内容修改
|
||||
# 不需要做任何额外接入工作
|
||||
# 配置已集成到脚本里
|
||||
```
|
||||
|
||||
改前
|
||||
module TencentOpenApi{
|
||||
umbrella header "TencentOpenApiUmbrellaHeader.h"
|
||||
export *
|
||||
}
|
||||
* Universal Links
|
||||
|
||||
改后
|
||||
framework module TencentOpenApi{
|
||||
umbrella header "TencentOpenApiUmbrellaHeader.h"
|
||||
export *
|
||||
apple-app-site-association - 通过 https://${your applinks domain}/.well-known/apple-app-site-association 链接可访问
|
||||
|
||||
示例:
|
||||
|
||||
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 以作区分
|
||||
|
||||
```
|
||||
在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
|
||||
### Flutter
|
||||
|
||||
|分享类型|说说(图/文/视频)|文本|图片|音乐|视频|网页|
|
||||
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||
|QQ|不支持|不支持|支持|支持|不支持|支持|
|
||||
|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
|
||||
* 4.0.0: 按标准插件书写重构
|
||||
* 3.1.0: 新增 setIsPermissionGranted 函数,设置是否已授权获取设备信息/是否同意隐私协议
|
||||
* 3.0.0: 重构
|
||||
* 2.1.0: nullsafety & 不再支持 Android embedding v1 & Tencent 单例
|
||||
⚠️⚠️⚠️ registerApp 前必须先调用 setIsPermissionGranted [issues/60](https://github.com/RxReader/tencent_kit/issues/60) [issues/79](https://github.com/RxReader/tencent_kit/issues/79)
|
||||
|
||||
* 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|
|
||||
installer.pods_project.targets.each do |target|
|
||||
@ -149,23 +104,21 @@ Capabilities -> Associated Domain -> Domain -> applinks:${your applinks}
|
||||
end
|
||||
```
|
||||
|
||||
* snapshot
|
||||
* 配置
|
||||
|
||||
```
|
||||
dependencies:
|
||||
tencent_kit:
|
||||
git:
|
||||
url: https://github.com/rxreader/tencent_kit.git
|
||||
```
|
||||
|
||||
* release
|
||||
|
||||
```
|
||||
```yaml
|
||||
dependencies:
|
||||
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)
|
||||
|
||||
|
@ -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/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() {
|
||||
runApp(MyApp());
|
||||
@ -85,7 +86,7 @@ class _HomeState extends State<Home> {
|
||||
ListTile(
|
||||
title: Text('注册APP'),
|
||||
onTap: () async {
|
||||
await TencentKitPlatform.instance.registerApp(appId: _TENCENT_APPID);
|
||||
await TencentKitPlatform.instance.registerApp(appId: _TENCENT_APPID, universalLink: _UNIVERSAL_LINK);
|
||||
_showTips('注册APP', '注册成功');
|
||||
},
|
||||
),
|
||||
|
@ -91,3 +91,7 @@ flutter:
|
||||
#
|
||||
# For details regarding fonts from package dependencies,
|
||||
# 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'))
|
||||
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|
|
||||
s.name = 'tencent_kit'
|
||||
s.version = library_version
|
||||
s.summary = 'A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Tencent SDKs.'
|
||||
s.description = <<-DESC
|
||||
A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Tencent SDKs.
|
||||
DESC
|
||||
s.homepage = 'http://example.com'
|
||||
s.summary = pubspec['description']
|
||||
s.description = pubspec['description']
|
||||
s.homepage = pubspec['homepage']
|
||||
s.license = { :file => '../LICENSE' }
|
||||
s.author = { 'Your Company' => 'email@example.com' }
|
||||
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