接入微信分享 SDK 并配置 Universal Link。
集成 WechatOpenSDK、www.zhifly.cn/suixinkan/ 通用链接与邀请页分享能力,附带 AASA 部署文件与单元测试。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
28
Podfile
28
Podfile
@ -8,20 +8,26 @@ target 'suixinkan' do
|
|||||||
pod 'AMapSearch-NO-IDFA', '~> 9.7'
|
pod 'AMapSearch-NO-IDFA', '~> 9.7'
|
||||||
pod 'AMapLocation-NO-IDFA', '~> 2.11'
|
pod 'AMapLocation-NO-IDFA', '~> 2.11'
|
||||||
|
|
||||||
|
# 微信 Open SDK:分享能力(不调用支付 API)
|
||||||
|
pod 'WechatOpenSDK-XCFramework', '~> 2.0.4'
|
||||||
|
|
||||||
target 'suixinkanTests' do
|
target 'suixinkanTests' do
|
||||||
inherit! :search_paths
|
inherit! :search_paths
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# 模拟器可用的链接参数(不含高德 prebuilt framework)
|
# 模拟器可用的链接参数(不含高德 prebuilt framework,但保留微信 SDK)
|
||||||
SIMULATOR_OTHER_LDFLAGS = <<~FLAGS.squish
|
SIMULATOR_OTHER_LDFLAGS = <<~FLAGS.squish
|
||||||
-ObjC -l"c++" -l"z"
|
-ObjC -l"c++" -l"sqlite3.0" -l"z"
|
||||||
-framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony"
|
-framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony"
|
||||||
-framework "CoreText" -framework "ExternalAccessory" -framework "GLKit"
|
-framework "CoreText" -framework "ExternalAccessory" -framework "GLKit"
|
||||||
-framework "OpenGLES" -framework "QuartzCore" -framework "Security"
|
-framework "OpenGLES" -framework "QuartzCore" -framework "Security"
|
||||||
-framework "SystemConfiguration"
|
-framework "SystemConfiguration" -framework "UIKit" -framework "WebKit"
|
||||||
|
-framework "WechatOpenSDK"
|
||||||
FLAGS
|
FLAGS
|
||||||
|
|
||||||
|
SIMULATOR_FRAMEWORK_SEARCH_PATHS = '"${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework"'
|
||||||
|
|
||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
# 1. 修正 aggregate xcconfig:去掉 arm64 排除,模拟器单独链接(不链 AMap)
|
# 1. 修正 aggregate xcconfig:去掉 arm64 排除,模拟器单独链接(不链 AMap)
|
||||||
%w[Pods-suixinkan Pods-suixinkanTests].each do |target_name|
|
%w[Pods-suixinkan Pods-suixinkanTests].each do |target_name|
|
||||||
@ -30,9 +36,23 @@ post_install do |installer|
|
|||||||
content = File.read(path)
|
content = File.read(path)
|
||||||
content.gsub!("EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64\n", '')
|
content.gsub!("EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64\n", '')
|
||||||
|
|
||||||
|
# 模拟器链接微信 SDK,同时剥离高德 framework
|
||||||
|
content.gsub!(
|
||||||
|
/OTHER_LDFLAGS\[sdk=iphonesimulator\*\] = .*\n/,
|
||||||
|
"OTHER_LDFLAGS[sdk=iphonesimulator*] = #{SIMULATOR_OTHER_LDFLAGS}\n"
|
||||||
|
)
|
||||||
|
if content.include?('FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*]')
|
||||||
|
content.gsub!(
|
||||||
|
/FRAMEWORK_SEARCH_PATHS\[sdk=iphonesimulator\*\] = .*\n/,
|
||||||
|
"FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited) #{SIMULATOR_FRAMEWORK_SEARCH_PATHS}\n"
|
||||||
|
)
|
||||||
|
else
|
||||||
|
content << "FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited) #{SIMULATOR_FRAMEWORK_SEARCH_PATHS}\n"
|
||||||
|
end
|
||||||
|
|
||||||
unless content.include?('OTHER_LDFLAGS[sdk=iphonesimulator*]')
|
unless content.include?('OTHER_LDFLAGS[sdk=iphonesimulator*]')
|
||||||
content << "\nOTHER_LDFLAGS[sdk=iphonesimulator*] = #{SIMULATOR_OTHER_LDFLAGS}\n"
|
content << "\nOTHER_LDFLAGS[sdk=iphonesimulator*] = #{SIMULATOR_OTHER_LDFLAGS}\n"
|
||||||
content << "FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited)\n"
|
content << "FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited) #{SIMULATOR_FRAMEWORK_SEARCH_PATHS}\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
File.write(path, content)
|
File.write(path, content)
|
||||||
|
|||||||
@ -6,11 +6,13 @@ PODS:
|
|||||||
- AMapFoundation-NO-IDFA (>= 1.8.7)
|
- AMapFoundation-NO-IDFA (>= 1.8.7)
|
||||||
- AMapSearch-NO-IDFA (9.7.5):
|
- AMapSearch-NO-IDFA (9.7.5):
|
||||||
- AMapFoundation-NO-IDFA (>= 1.8.0)
|
- AMapFoundation-NO-IDFA (>= 1.8.0)
|
||||||
|
- WechatOpenSDK-XCFramework (2.0.5)
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- AMap3DMap-NO-IDFA (~> 11.1)
|
- AMap3DMap-NO-IDFA (~> 11.1)
|
||||||
- AMapLocation-NO-IDFA (~> 2.11)
|
- AMapLocation-NO-IDFA (~> 2.11)
|
||||||
- AMapSearch-NO-IDFA (~> 9.7)
|
- AMapSearch-NO-IDFA (~> 9.7)
|
||||||
|
- WechatOpenSDK-XCFramework (~> 2.0.4)
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
@ -18,13 +20,15 @@ SPEC REPOS:
|
|||||||
- AMapFoundation-NO-IDFA
|
- AMapFoundation-NO-IDFA
|
||||||
- AMapLocation-NO-IDFA
|
- AMapLocation-NO-IDFA
|
||||||
- AMapSearch-NO-IDFA
|
- AMapSearch-NO-IDFA
|
||||||
|
- WechatOpenSDK-XCFramework
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
AMap3DMap-NO-IDFA: 393a24abb0451fed2daa4316c8d3d356a395f2be
|
AMap3DMap-NO-IDFA: 393a24abb0451fed2daa4316c8d3d356a395f2be
|
||||||
AMapFoundation-NO-IDFA: f48acbf6e74913dc6744581053f7d984f2432850
|
AMapFoundation-NO-IDFA: f48acbf6e74913dc6744581053f7d984f2432850
|
||||||
AMapLocation-NO-IDFA: 0fa6e7d5e42e10253f4437424d98966f53760862
|
AMapLocation-NO-IDFA: 0fa6e7d5e42e10253f4437424d98966f53760862
|
||||||
AMapSearch-NO-IDFA: 8e9d104032990a3b0cab66afb535299887c61047
|
AMapSearch-NO-IDFA: 8e9d104032990a3b0cab66afb535299887c61047
|
||||||
|
WechatOpenSDK-XCFramework: ff342ae616bb86df3d236aca38059dfd4bc4a949
|
||||||
|
|
||||||
PODFILE CHECKSUM: baa972253fcebc312545f7592c48cbba632f1907
|
PODFILE CHECKSUM: e8cba7a3776cf5c925cda135f2774d8f243899c4
|
||||||
|
|
||||||
COCOAPODS: 1.16.2
|
COCOAPODS: 1.16.2
|
||||||
|
|||||||
6
Pods/Manifest.lock
generated
6
Pods/Manifest.lock
generated
@ -6,11 +6,13 @@ PODS:
|
|||||||
- AMapFoundation-NO-IDFA (>= 1.8.7)
|
- AMapFoundation-NO-IDFA (>= 1.8.7)
|
||||||
- AMapSearch-NO-IDFA (9.7.5):
|
- AMapSearch-NO-IDFA (9.7.5):
|
||||||
- AMapFoundation-NO-IDFA (>= 1.8.0)
|
- AMapFoundation-NO-IDFA (>= 1.8.0)
|
||||||
|
- WechatOpenSDK-XCFramework (2.0.5)
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- AMap3DMap-NO-IDFA (~> 11.1)
|
- AMap3DMap-NO-IDFA (~> 11.1)
|
||||||
- AMapLocation-NO-IDFA (~> 2.11)
|
- AMapLocation-NO-IDFA (~> 2.11)
|
||||||
- AMapSearch-NO-IDFA (~> 9.7)
|
- AMapSearch-NO-IDFA (~> 9.7)
|
||||||
|
- WechatOpenSDK-XCFramework (~> 2.0.4)
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
@ -18,13 +20,15 @@ SPEC REPOS:
|
|||||||
- AMapFoundation-NO-IDFA
|
- AMapFoundation-NO-IDFA
|
||||||
- AMapLocation-NO-IDFA
|
- AMapLocation-NO-IDFA
|
||||||
- AMapSearch-NO-IDFA
|
- AMapSearch-NO-IDFA
|
||||||
|
- WechatOpenSDK-XCFramework
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
AMap3DMap-NO-IDFA: 393a24abb0451fed2daa4316c8d3d356a395f2be
|
AMap3DMap-NO-IDFA: 393a24abb0451fed2daa4316c8d3d356a395f2be
|
||||||
AMapFoundation-NO-IDFA: f48acbf6e74913dc6744581053f7d984f2432850
|
AMapFoundation-NO-IDFA: f48acbf6e74913dc6744581053f7d984f2432850
|
||||||
AMapLocation-NO-IDFA: 0fa6e7d5e42e10253f4437424d98966f53760862
|
AMapLocation-NO-IDFA: 0fa6e7d5e42e10253f4437424d98966f53760862
|
||||||
AMapSearch-NO-IDFA: 8e9d104032990a3b0cab66afb535299887c61047
|
AMapSearch-NO-IDFA: 8e9d104032990a3b0cab66afb535299887c61047
|
||||||
|
WechatOpenSDK-XCFramework: ff342ae616bb86df3d236aca38059dfd4bc4a949
|
||||||
|
|
||||||
PODFILE CHECKSUM: baa972253fcebc312545f7592c48cbba632f1907
|
PODFILE CHECKSUM: e8cba7a3776cf5c925cda135f2774d8f243899c4
|
||||||
|
|
||||||
COCOAPODS: 1.16.2
|
COCOAPODS: 1.16.2
|
||||||
|
|||||||
1083
Pods/Pods.xcodeproj/project.pbxproj
generated
1083
Pods/Pods.xcodeproj/project.pbxproj
generated
File diff suppressed because it is too large
Load Diff
@ -20,4 +20,9 @@ Copyright © 2014 AutoNavi. All Rights Reserved.
|
|||||||
|
|
||||||
Copyright © 2014 AutoNavi. All Rights Reserved.
|
Copyright © 2014 AutoNavi. All Rights Reserved.
|
||||||
|
|
||||||
|
|
||||||
|
## WechatOpenSDK-XCFramework
|
||||||
|
|
||||||
|
Copyright 2020 tencent.com. All rights reserved.
|
||||||
|
|
||||||
Generated by CocoaPods - https://cocoapods.org
|
Generated by CocoaPods - https://cocoapods.org
|
||||||
|
|||||||
@ -56,6 +56,17 @@
|
|||||||
<key>Type</key>
|
<key>Type</key>
|
||||||
<string>PSGroupSpecifier</string>
|
<string>PSGroupSpecifier</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>FooterText</key>
|
||||||
|
<string>Copyright 2020 tencent.com. All rights reserved.
|
||||||
|
</string>
|
||||||
|
<key>License</key>
|
||||||
|
<string>Copyright</string>
|
||||||
|
<key>Title</key>
|
||||||
|
<string>WechatOpenSDK-XCFramework</string>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>PSGroupSpecifier</string>
|
||||||
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>FooterText</key>
|
<key>FooterText</key>
|
||||||
<string>Generated by CocoaPods - https://cocoapods.org</string>
|
<string>Generated by CocoaPods - https://cocoapods.org</string>
|
||||||
|
|||||||
@ -1,16 +1,18 @@
|
|||||||
ARCHS = $(ARCHS_STANDARD)
|
ARCHS = $(ARCHS_STANDARD)
|
||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/AMap3DMap-NO-IDFA" "${PODS_ROOT}/AMapFoundation-NO-IDFA" "${PODS_ROOT}/AMapLocation-NO-IDFA" "${PODS_ROOT}/AMapSearch-NO-IDFA"
|
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/AMap3DMap-NO-IDFA" "${PODS_ROOT}/AMapFoundation-NO-IDFA" "${PODS_ROOT}/AMapLocation-NO-IDFA" "${PODS_ROOT}/AMapSearch-NO-IDFA" "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework"
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
||||||
OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -l"z" -framework "AMapFoundationKit" -framework "AMapLocationKit" -framework "AMapSearchKit" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "GLKit" -framework "MAMapKit" -framework "OpenGLES" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration"
|
OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -l"sqlite3.0" -l"z" -framework "AMapFoundationKit" -framework "AMapLocationKit" -framework "AMapSearchKit" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "GLKit" -framework "MAMapKit" -framework "OpenGLES" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" -framework "WebKit" -framework "WechatOpenSDK"
|
||||||
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AMap3DMap-NO-IDFA" "-F${PODS_CONFIGURATION_BUILD_DIR}/AMapFoundation-NO-IDFA" "-F${PODS_CONFIGURATION_BUILD_DIR}/AMapLocation-NO-IDFA" "-F${PODS_CONFIGURATION_BUILD_DIR}/AMapSearch-NO-IDFA"
|
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AMap3DMap-NO-IDFA" "-F${PODS_CONFIGURATION_BUILD_DIR}/AMapFoundation-NO-IDFA" "-F${PODS_CONFIGURATION_BUILD_DIR}/AMapLocation-NO-IDFA" "-F${PODS_CONFIGURATION_BUILD_DIR}/AMapSearch-NO-IDFA" "-F${PODS_CONFIGURATION_BUILD_DIR}/WechatOpenSDK-XCFramework"
|
||||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||||
PODS_ROOT = ${SRCROOT}/Pods
|
PODS_ROOT = ${SRCROOT}/Pods
|
||||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||||
|
VALID_ARCHS = arm64 x86_64
|
||||||
|
FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited) "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework"
|
||||||
|
|
||||||
OTHER_LDFLAGS[sdk=iphonesimulator*] = -ObjC -l"c++" -l"z" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "GLKit" -framework "OpenGLES" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration"
|
OTHER_LDFLAGS[sdk=iphonesimulator*] = -ObjC -l"c++" -l"sqlite3.0" -l"z" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "GLKit" -framework "OpenGLES" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" -framework "WebKit" -framework "WechatOpenSDK"
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited)
|
FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited) "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework"
|
||||||
|
|||||||
@ -1,16 +1,18 @@
|
|||||||
ARCHS = $(ARCHS_STANDARD)
|
ARCHS = $(ARCHS_STANDARD)
|
||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/AMap3DMap-NO-IDFA" "${PODS_ROOT}/AMapFoundation-NO-IDFA" "${PODS_ROOT}/AMapLocation-NO-IDFA" "${PODS_ROOT}/AMapSearch-NO-IDFA"
|
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/AMap3DMap-NO-IDFA" "${PODS_ROOT}/AMapFoundation-NO-IDFA" "${PODS_ROOT}/AMapLocation-NO-IDFA" "${PODS_ROOT}/AMapSearch-NO-IDFA" "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework"
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
||||||
OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -l"z" -framework "AMapFoundationKit" -framework "AMapLocationKit" -framework "AMapSearchKit" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "GLKit" -framework "MAMapKit" -framework "OpenGLES" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration"
|
OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -l"sqlite3.0" -l"z" -framework "AMapFoundationKit" -framework "AMapLocationKit" -framework "AMapSearchKit" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "GLKit" -framework "MAMapKit" -framework "OpenGLES" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" -framework "WebKit" -framework "WechatOpenSDK"
|
||||||
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AMap3DMap-NO-IDFA" "-F${PODS_CONFIGURATION_BUILD_DIR}/AMapFoundation-NO-IDFA" "-F${PODS_CONFIGURATION_BUILD_DIR}/AMapLocation-NO-IDFA" "-F${PODS_CONFIGURATION_BUILD_DIR}/AMapSearch-NO-IDFA"
|
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AMap3DMap-NO-IDFA" "-F${PODS_CONFIGURATION_BUILD_DIR}/AMapFoundation-NO-IDFA" "-F${PODS_CONFIGURATION_BUILD_DIR}/AMapLocation-NO-IDFA" "-F${PODS_CONFIGURATION_BUILD_DIR}/AMapSearch-NO-IDFA" "-F${PODS_CONFIGURATION_BUILD_DIR}/WechatOpenSDK-XCFramework"
|
||||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||||
PODS_ROOT = ${SRCROOT}/Pods
|
PODS_ROOT = ${SRCROOT}/Pods
|
||||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||||
|
VALID_ARCHS = arm64 x86_64
|
||||||
|
FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited) "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework"
|
||||||
|
|
||||||
OTHER_LDFLAGS[sdk=iphonesimulator*] = -ObjC -l"c++" -l"z" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "GLKit" -framework "OpenGLES" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration"
|
OTHER_LDFLAGS[sdk=iphonesimulator*] = -ObjC -l"c++" -l"sqlite3.0" -l"z" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "GLKit" -framework "OpenGLES" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" -framework "WebKit" -framework "WechatOpenSDK"
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited)
|
FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited) "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework"
|
||||||
|
|||||||
@ -1,14 +1,16 @@
|
|||||||
ARCHS = $(ARCHS_STANDARD)
|
ARCHS = $(ARCHS_STANDARD)
|
||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/AMap3DMap-NO-IDFA" "${PODS_ROOT}/AMapFoundation-NO-IDFA" "${PODS_ROOT}/AMapLocation-NO-IDFA" "${PODS_ROOT}/AMapSearch-NO-IDFA"
|
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/AMap3DMap-NO-IDFA" "${PODS_ROOT}/AMapFoundation-NO-IDFA" "${PODS_ROOT}/AMapLocation-NO-IDFA" "${PODS_ROOT}/AMapSearch-NO-IDFA" "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework"
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
OTHER_LDFLAGS = $(inherited) -l"c++" -l"z" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "GLKit" -framework "OpenGLES" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration"
|
OTHER_LDFLAGS = $(inherited) -l"c++" -l"sqlite3.0" -l"z" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "GLKit" -framework "OpenGLES" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" -framework "WebKit"
|
||||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||||
PODS_ROOT = ${SRCROOT}/Pods
|
PODS_ROOT = ${SRCROOT}/Pods
|
||||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||||
|
VALID_ARCHS = arm64 x86_64
|
||||||
|
FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited) "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework"
|
||||||
|
|
||||||
OTHER_LDFLAGS[sdk=iphonesimulator*] = -ObjC -l"c++" -l"z" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "GLKit" -framework "OpenGLES" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration"
|
OTHER_LDFLAGS[sdk=iphonesimulator*] = -ObjC -l"c++" -l"sqlite3.0" -l"z" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "GLKit" -framework "OpenGLES" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" -framework "WebKit" -framework "WechatOpenSDK"
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited)
|
FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited) "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework"
|
||||||
|
|||||||
@ -1,14 +1,16 @@
|
|||||||
ARCHS = $(ARCHS_STANDARD)
|
ARCHS = $(ARCHS_STANDARD)
|
||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/AMap3DMap-NO-IDFA" "${PODS_ROOT}/AMapFoundation-NO-IDFA" "${PODS_ROOT}/AMapLocation-NO-IDFA" "${PODS_ROOT}/AMapSearch-NO-IDFA"
|
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/AMap3DMap-NO-IDFA" "${PODS_ROOT}/AMapFoundation-NO-IDFA" "${PODS_ROOT}/AMapLocation-NO-IDFA" "${PODS_ROOT}/AMapSearch-NO-IDFA" "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework"
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
OTHER_LDFLAGS = $(inherited) -l"c++" -l"z" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "GLKit" -framework "OpenGLES" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration"
|
OTHER_LDFLAGS = $(inherited) -l"c++" -l"sqlite3.0" -l"z" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "GLKit" -framework "OpenGLES" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" -framework "WebKit"
|
||||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||||
PODS_ROOT = ${SRCROOT}/Pods
|
PODS_ROOT = ${SRCROOT}/Pods
|
||||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||||
|
VALID_ARCHS = arm64 x86_64
|
||||||
|
FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited) "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework"
|
||||||
|
|
||||||
OTHER_LDFLAGS[sdk=iphonesimulator*] = -ObjC -l"c++" -l"z" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "GLKit" -framework "OpenGLES" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration"
|
OTHER_LDFLAGS[sdk=iphonesimulator*] = -ObjC -l"c++" -l"sqlite3.0" -l"z" -framework "CoreGraphics" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "GLKit" -framework "OpenGLES" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" -framework "WebKit" -framework "WechatOpenSDK"
|
||||||
FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited)
|
FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited) "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework"
|
||||||
|
|||||||
@ -0,0 +1,2 @@
|
|||||||
|
${PODS_ROOT}/Target Support Files/WechatOpenSDK-XCFramework/WechatOpenSDK-XCFramework-xcframeworks.sh
|
||||||
|
${PODS_ROOT}/WechatOpenSDK-XCFramework/WechatOpenSDK.xcframework
|
||||||
@ -0,0 +1 @@
|
|||||||
|
${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework/WechatOpenSDK.framework
|
||||||
121
Pods/Target Support Files/WechatOpenSDK-XCFramework/WechatOpenSDK-XCFramework-xcframeworks.sh
generated
Executable file
121
Pods/Target Support Files/WechatOpenSDK-XCFramework/WechatOpenSDK-XCFramework-xcframeworks.sh
generated
Executable file
@ -0,0 +1,121 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
set -u
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
function on_error {
|
||||||
|
echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
|
||||||
|
}
|
||||||
|
trap 'on_error $LINENO' ERR
|
||||||
|
|
||||||
|
|
||||||
|
# This protects against multiple targets copying the same framework dependency at the same time. The solution
|
||||||
|
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
|
||||||
|
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
|
||||||
|
|
||||||
|
|
||||||
|
variant_for_slice()
|
||||||
|
{
|
||||||
|
case "$1" in
|
||||||
|
"WechatOpenSDK.xcframework/ios-arm64")
|
||||||
|
echo ""
|
||||||
|
;;
|
||||||
|
"WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator")
|
||||||
|
echo "simulator"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
archs_for_slice()
|
||||||
|
{
|
||||||
|
case "$1" in
|
||||||
|
"WechatOpenSDK.xcframework/ios-arm64")
|
||||||
|
echo "arm64"
|
||||||
|
;;
|
||||||
|
"WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator")
|
||||||
|
echo "arm64 x86_64"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_dir()
|
||||||
|
{
|
||||||
|
local source="$1"
|
||||||
|
local destination="$2"
|
||||||
|
|
||||||
|
# Use filter instead of exclude so missing patterns don't throw errors.
|
||||||
|
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" \"${source}*\" \"${destination}\""
|
||||||
|
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" "${source}"/* "${destination}"
|
||||||
|
}
|
||||||
|
|
||||||
|
SELECT_SLICE_RETVAL=""
|
||||||
|
|
||||||
|
select_slice() {
|
||||||
|
local xcframework_name="$1"
|
||||||
|
xcframework_name="${xcframework_name##*/}"
|
||||||
|
local paths=("${@:2}")
|
||||||
|
# Locate the correct slice of the .xcframework for the current architectures
|
||||||
|
local target_path=""
|
||||||
|
|
||||||
|
# Split archs on space so we can find a slice that has all the needed archs
|
||||||
|
local target_archs=$(echo $ARCHS | tr " " "\n")
|
||||||
|
|
||||||
|
local target_variant=""
|
||||||
|
if [[ "$PLATFORM_NAME" == *"simulator" ]]; then
|
||||||
|
target_variant="simulator"
|
||||||
|
fi
|
||||||
|
if [[ ! -z ${EFFECTIVE_PLATFORM_NAME+x} && "$EFFECTIVE_PLATFORM_NAME" == *"maccatalyst" ]]; then
|
||||||
|
target_variant="maccatalyst"
|
||||||
|
fi
|
||||||
|
for i in ${!paths[@]}; do
|
||||||
|
local matched_all_archs="1"
|
||||||
|
local slice_archs="$(archs_for_slice "${xcframework_name}/${paths[$i]}")"
|
||||||
|
local slice_variant="$(variant_for_slice "${xcframework_name}/${paths[$i]}")"
|
||||||
|
for target_arch in $target_archs; do
|
||||||
|
if ! [[ "${slice_variant}" == "$target_variant" ]]; then
|
||||||
|
matched_all_archs="0"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! echo "${slice_archs}" | tr " " "\n" | grep -F -q -x "$target_arch"; then
|
||||||
|
matched_all_archs="0"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$matched_all_archs" == "1" ]]; then
|
||||||
|
# Found a matching slice
|
||||||
|
echo "Selected xcframework slice ${paths[$i]}"
|
||||||
|
SELECT_SLICE_RETVAL=${paths[$i]}
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
install_xcframework() {
|
||||||
|
local basepath="$1"
|
||||||
|
local name="$2"
|
||||||
|
local package_type="$3"
|
||||||
|
local paths=("${@:4}")
|
||||||
|
|
||||||
|
# Locate the correct slice of the .xcframework for the current architectures
|
||||||
|
select_slice "${basepath}" "${paths[@]}"
|
||||||
|
local target_path="$SELECT_SLICE_RETVAL"
|
||||||
|
if [[ -z "$target_path" ]]; then
|
||||||
|
echo "warning: [CP] $(basename ${basepath}): Unable to find matching slice in '${paths[@]}' for the current build architectures ($ARCHS) and platform (${EFFECTIVE_PLATFORM_NAME-${PLATFORM_NAME}})."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local source="$basepath/$target_path"
|
||||||
|
|
||||||
|
local destination="${PODS_XCFRAMEWORKS_BUILD_DIR}/${name}"
|
||||||
|
|
||||||
|
if [ ! -d "$destination" ]; then
|
||||||
|
mkdir -p "$destination"
|
||||||
|
fi
|
||||||
|
|
||||||
|
copy_dir "$source/" "$destination"
|
||||||
|
echo "Copied $source to $destination"
|
||||||
|
}
|
||||||
|
|
||||||
|
install_xcframework "${PODS_ROOT}/WechatOpenSDK-XCFramework/WechatOpenSDK.xcframework" "WechatOpenSDK-XCFramework" "framework" "ios-arm64" "ios-arm64_x86_64-simulator"
|
||||||
|
|
||||||
15
Pods/Target Support Files/WechatOpenSDK-XCFramework/WechatOpenSDK-XCFramework.debug.xcconfig
generated
Normal file
15
Pods/Target Support Files/WechatOpenSDK-XCFramework/WechatOpenSDK-XCFramework.debug.xcconfig
generated
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
|
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/WechatOpenSDK-XCFramework
|
||||||
|
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework"
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
|
OTHER_LDFLAGS = $(inherited) -l"c++" -l"sqlite3.0" -l"z" -framework "CoreGraphics" -framework "Security" -framework "UIKit" -framework "WebKit"
|
||||||
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
|
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||||
|
PODS_ROOT = ${SRCROOT}
|
||||||
|
PODS_TARGET_SRCROOT = ${PODS_ROOT}/WechatOpenSDK-XCFramework
|
||||||
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||||
|
SKIP_INSTALL = YES
|
||||||
|
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||||
|
VALID_ARCHS = arm64 x86_64
|
||||||
15
Pods/Target Support Files/WechatOpenSDK-XCFramework/WechatOpenSDK-XCFramework.release.xcconfig
generated
Normal file
15
Pods/Target Support Files/WechatOpenSDK-XCFramework/WechatOpenSDK-XCFramework.release.xcconfig
generated
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
|
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/WechatOpenSDK-XCFramework
|
||||||
|
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/WechatOpenSDK-XCFramework" "${PODS_XCFRAMEWORKS_BUILD_DIR}/WechatOpenSDK-XCFramework"
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
|
OTHER_LDFLAGS = $(inherited) -l"c++" -l"sqlite3.0" -l"z" -framework "CoreGraphics" -framework "Security" -framework "UIKit" -framework "WebKit"
|
||||||
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
|
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||||
|
PODS_ROOT = ${SRCROOT}
|
||||||
|
PODS_TARGET_SRCROOT = ${PODS_ROOT}/WechatOpenSDK-XCFramework
|
||||||
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||||
|
SKIP_INSTALL = YES
|
||||||
|
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||||
|
VALID_ARCHS = arm64 x86_64
|
||||||
44
Pods/WechatOpenSDK-XCFramework/WechatOpenSDK.xcframework/Info.plist
generated
Normal file
44
Pods/WechatOpenSDK-XCFramework/WechatOpenSDK.xcframework/Info.plist
generated
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>AvailableLibraries</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>BinaryPath</key>
|
||||||
|
<string>WechatOpenSDK.framework/WechatOpenSDK</string>
|
||||||
|
<key>LibraryIdentifier</key>
|
||||||
|
<string>ios-arm64_x86_64-simulator</string>
|
||||||
|
<key>LibraryPath</key>
|
||||||
|
<string>WechatOpenSDK.framework</string>
|
||||||
|
<key>SupportedArchitectures</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
<string>x86_64</string>
|
||||||
|
</array>
|
||||||
|
<key>SupportedPlatform</key>
|
||||||
|
<string>ios</string>
|
||||||
|
<key>SupportedPlatformVariant</key>
|
||||||
|
<string>simulator</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>BinaryPath</key>
|
||||||
|
<string>WechatOpenSDK.framework/WechatOpenSDK</string>
|
||||||
|
<key>LibraryIdentifier</key>
|
||||||
|
<string>ios-arm64</string>
|
||||||
|
<key>LibraryPath</key>
|
||||||
|
<string>WechatOpenSDK.framework</string>
|
||||||
|
<key>SupportedArchitectures</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
</array>
|
||||||
|
<key>SupportedPlatform</key>
|
||||||
|
<string>ios</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>XFWK</string>
|
||||||
|
<key>XCFrameworkFormatVersion</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
17
Pods/WechatOpenSDK-XCFramework/WechatOpenSDK.xcframework/PrivacyInfo.xcprivacy
generated
Normal file
17
Pods/WechatOpenSDK-XCFramework/WechatOpenSDK.xcframework/PrivacyInfo.xcprivacy
generated
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>NSPrivacyAccessedAPITypes</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>NSPrivacyAccessedAPIType</key>
|
||||||
|
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||||
|
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||||
|
<array>
|
||||||
|
<string>CA92.1</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
167
Pods/WechatOpenSDK-XCFramework/WechatOpenSDK.xcframework/README.txt
generated
Normal file
167
Pods/WechatOpenSDK-XCFramework/WechatOpenSDK.xcframework/README.txt
generated
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
重要!
|
||||||
|
SDK2.0.5
|
||||||
|
1. 支持模块化集成:XCFramework 头文件引用改为标准化格式 #import <WechatOpenSDK/WXApi.h>,解决路径冲突并支持 Swift/ObjC 混合开发
|
||||||
|
2. 修复openWXApp偶现失败的问题
|
||||||
|
|
||||||
|
SDK2.0.4
|
||||||
|
1.增加privacy manifest文件
|
||||||
|
2.修复跳微信时可能卡顿的问题
|
||||||
|
|
||||||
|
SDK2.0.2
|
||||||
|
1. 优化XCFramework打包方式
|
||||||
|
|
||||||
|
SDK2.0.1
|
||||||
|
1. SDK支持XCFramework
|
||||||
|
|
||||||
|
SDK2.0.0
|
||||||
|
1. 分享能力支持内容防篡改校验
|
||||||
|
|
||||||
|
SDK1.9.9
|
||||||
|
1. 授权登录支持关闭自动授权
|
||||||
|
2. 分享支持添加签名,防止篡改
|
||||||
|
|
||||||
|
SDK1.9.7
|
||||||
|
1. 适配CocoaPods
|
||||||
|
|
||||||
|
SDK1.9.6
|
||||||
|
1. 适配iOS 16,减少读写剪切板
|
||||||
|
|
||||||
|
SDK1.9.4
|
||||||
|
1. 修复授权登录取消/拒绝时state字段没有带回
|
||||||
|
|
||||||
|
SDK1.9.3
|
||||||
|
1. 新增发起二维码支付能力
|
||||||
|
|
||||||
|
SDK1.9.2
|
||||||
|
1. 新增发起企微客服会话能力
|
||||||
|
|
||||||
|
SDK1.9.1
|
||||||
|
1. 音乐视频分享类型增加运营H5字段
|
||||||
|
|
||||||
|
SDK1.8.9
|
||||||
|
1. 增加音乐视频分享类型
|
||||||
|
|
||||||
|
SDK1.8.8
|
||||||
|
1. 增加游戏直播消息类型
|
||||||
|
|
||||||
|
SDK1.8.7.1
|
||||||
|
1. 修复Xcode11以下编译不通过
|
||||||
|
|
||||||
|
SDK1.8.7
|
||||||
|
1. 修复iPadOS,未安装微信的情况下,因为UA问题无法授权登录
|
||||||
|
2. 修复未安装微信的情况下, 适配了UIScene的App因为UIAlertView Crash
|
||||||
|
3. 增加Universal Link检测函数
|
||||||
|
|
||||||
|
SDK1.8.6.2
|
||||||
|
1. 修改包含"UIWebView"字符的类名
|
||||||
|
|
||||||
|
SDK1.8.6.1
|
||||||
|
1.短信授权登录使用的UIWebview切换成WKWebview
|
||||||
|
|
||||||
|
SDK1.8.6
|
||||||
|
1. 支持Universal Link拉起微信以及返回App
|
||||||
|
2. SDK移除MTA库
|
||||||
|
|
||||||
|
SDK1.8.5
|
||||||
|
1. 更换MTA库:取消对剪切板的访问, 防止和其他SDK竞争导致crash
|
||||||
|
2. NSMutableArray的MTA分类方法改名,减少命名冲突
|
||||||
|
3. 不含支付功能版本移除非税支付和医保支付接口
|
||||||
|
4. 分享音乐支持填写歌词和高清封面图
|
||||||
|
|
||||||
|
SDK1.8.4
|
||||||
|
1. 调整分享图片大小限制
|
||||||
|
2. 新增openBusinessView接口
|
||||||
|
|
||||||
|
SDK1.8.3
|
||||||
|
1. SDK增加调起微信刷卡支付接口
|
||||||
|
2. SDK增加小程序订阅消息接口
|
||||||
|
3. 修复小程序订阅消息接口没有resp的问题
|
||||||
|
|
||||||
|
SDK1.8.2
|
||||||
|
1. SDK增加开发票授权 WXInvoiceAuthInsert
|
||||||
|
2. SDK增加非税接口 WXNontaxPay
|
||||||
|
3. SDK增加医保接口 WXPayInsurance
|
||||||
|
4. 更换MTA库
|
||||||
|
|
||||||
|
SDK1.8.1
|
||||||
|
1. SDK打开小程序支持指定版本(体验,开发,正式版)
|
||||||
|
2. SDK分享小程序支持指定版本(体验,开发,正式版)
|
||||||
|
3. SDK支持输出log日志
|
||||||
|
|
||||||
|
SDK1.8.0
|
||||||
|
1. SDK支持打开小程序
|
||||||
|
2. SDK分享小程序支持shareTicket
|
||||||
|
|
||||||
|
SDK1.7.9
|
||||||
|
1. SDK订阅一次性消息
|
||||||
|
|
||||||
|
SDK1.7.8
|
||||||
|
1 SDK分享小程序支持大图
|
||||||
|
|
||||||
|
SDK1.7.7
|
||||||
|
1 增加SDK分享小程序
|
||||||
|
2 增加选择发票接口
|
||||||
|
|
||||||
|
SDK1.7.6
|
||||||
|
1. 提高稳定性
|
||||||
|
1 修复mta崩溃
|
||||||
|
2 新增接口支持开发者关闭mta数据统计上报
|
||||||
|
|
||||||
|
SDK1.7.5
|
||||||
|
1. 提高稳定性
|
||||||
|
2. 加快registerApp接口启动速度
|
||||||
|
|
||||||
|
SDK1.7.4
|
||||||
|
1. 更新支持iOS启用 ATS(App Transport Security)
|
||||||
|
2. 需要在工程中链接CFNetwork.framework
|
||||||
|
3. 在工程配置中的”Other Linker Flags”中加入”-Objc -all_load”
|
||||||
|
|
||||||
|
SDK1.7.3
|
||||||
|
1. 增强稳定性,适配iOS10
|
||||||
|
2. 修复小于32K的jpg格式缩略图设置失败的问题
|
||||||
|
|
||||||
|
SDK1.7.2
|
||||||
|
1. 修复因CTTeleponyNetworkInfo引起的崩溃问题
|
||||||
|
|
||||||
|
SDK1.7.1
|
||||||
|
1. 支持兼容ipv6(提升稳定性)
|
||||||
|
2. xCode Version 7.3.1 (7D1014) 编译
|
||||||
|
|
||||||
|
SDK1.7
|
||||||
|
1. 支持兼容ipv6
|
||||||
|
2. 修复若干问题增强稳定性
|
||||||
|
|
||||||
|
SDK1.6.3
|
||||||
|
1. xCode7.2 构建的sdk包。
|
||||||
|
2. 请使用xCode7.2进行编译。
|
||||||
|
3. 需要在Build Phases中Link Security.framework
|
||||||
|
4. 修复若干小问题。
|
||||||
|
|
||||||
|
SDK1.6.2
|
||||||
|
1、xCode7.1 构建的sdk包
|
||||||
|
2、请使用xCode7.1进行编译
|
||||||
|
|
||||||
|
SDK1.6.1
|
||||||
|
1、修复armv7s下,bitcode可能编译不过
|
||||||
|
2、解决warning
|
||||||
|
|
||||||
|
SDK1.6
|
||||||
|
1、iOS 9系统策略更新,限制了http协议的访问,此外应用需要在“Info.plist”中将要使用的URL Schemes列为白名单,才可正常检查其他应用是否安装。
|
||||||
|
受此影响,当你的应用在iOS 9中需要使用微信SDK的相关能力(分享、收藏、支付、登录等)时,需要在“Info.plist”里增加如下代码:
|
||||||
|
<key>LSApplicationQueriesSchemes</key>
|
||||||
|
<array>
|
||||||
|
<string>weixin</string>
|
||||||
|
</array>
|
||||||
|
<key>NSAppTransportSecurity</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
2、开发者需要在工程中链接上 CoreTelephony.framework
|
||||||
|
3、解决bitcode编译不过问题
|
||||||
|
|
||||||
|
SDK1.5
|
||||||
|
1、废弃safeSendReq:接口,使用sendReq:即可。
|
||||||
|
2、新增+(BOOL) sendAuthReq:(SendAuthReq*) req viewController : (UIViewController*) viewController delegate:(id<WXApiDelegate>) delegate;
|
||||||
|
支持未安装微信情况下Auth,具体见WXApi.h接口描述
|
||||||
|
3、微信开放平台新增了微信模块用户统计功能,便于开发者统计微信功能模块的用户使用和活跃情况。开发者需要在工程中链接上:SystemConfiguration.framework,libz.dylib,libsqlite3.0.dylib。
|
||||||
@ -0,0 +1,231 @@
|
|||||||
|
//
|
||||||
|
// WXApi.h
|
||||||
|
// 所有Api接口
|
||||||
|
//
|
||||||
|
// Created by Wechat on 12-2-28.
|
||||||
|
// Copyright (c) 2012年 Tencent. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "WXApiObject.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
|
||||||
|
typedef BOOL(^WXGrantReadPasteBoardPermissionCompletion)(void);
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - WXApiDelegate
|
||||||
|
/*! @brief 接收并处理来自微信终端程序的事件消息
|
||||||
|
*
|
||||||
|
* 接收并处理来自微信终端程序的事件消息,期间微信界面会切换到第三方应用程序。
|
||||||
|
* WXApiDelegate 会在handleOpenURL:delegate:中使用并触发。
|
||||||
|
*/
|
||||||
|
@protocol WXApiDelegate <NSObject>
|
||||||
|
@optional
|
||||||
|
|
||||||
|
/*! @brief 收到一个来自微信的请求,第三方应用程序处理完后调用sendResp向微信发送结果
|
||||||
|
*
|
||||||
|
* 收到一个来自微信的请求,异步处理完成后必须调用sendResp发送处理结果给微信。
|
||||||
|
* 可能收到的请求有GetMessageFromWXReq、ShowMessageFromWXReq等。
|
||||||
|
* @param req 具体请求内容,是自动释放的
|
||||||
|
*/
|
||||||
|
- (void)onReq:(BaseReq*)req;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 发送一个sendReq后,收到微信的回应
|
||||||
|
*
|
||||||
|
* 收到一个来自微信的处理结果。调用一次sendReq后会收到onResp。
|
||||||
|
* 可能收到的处理结果有SendMessageToWXResp、SendAuthResp等。
|
||||||
|
* @param resp具体的回应内容,是自动释放的
|
||||||
|
*/
|
||||||
|
- (void)onResp:(BaseResp*)resp;
|
||||||
|
|
||||||
|
/* ! @brief 用于在iOS16以及以上系统上,控制OpenSDK是否读取剪切板中微信传递的数据以及读取的时机
|
||||||
|
* 在iOS16以及以上系统,在SDK需要读取剪切板中微信写入的数据时,会回调该方法。没有实现默认会直接读取微信通过剪切板传递过来的数据
|
||||||
|
* 注意:
|
||||||
|
* 1. 只在iOS16以及以上的系统版本上回调;
|
||||||
|
* 2. 不实现时,OpenSDK会直接调用读取剪切板接口,读取微信传递过来的数据;
|
||||||
|
* 3. 若实现该方法:开发者需要通过调用completion(), 支持异步,通知SDK允许读取剪切板中微信传递的数据,
|
||||||
|
* 不调用completion()则代表不授权OpenSDK读取剪切板,会导致收不到onReq:, onResp:回调,无法后续业务流程。请谨慎使用
|
||||||
|
* 4. 不要长时间持有completion不释放,可能会导致内存泄漏。
|
||||||
|
*/
|
||||||
|
- (void)onNeedGrantReadPasteBoardPermissionWithURL:(nonnull NSURL *)openURL completion:(nonnull WXGrantReadPasteBoardPermissionCompletion)completion;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark - WXApiLogDelegate
|
||||||
|
|
||||||
|
@protocol WXApiLogDelegate <NSObject>
|
||||||
|
|
||||||
|
- (void)onLog:(NSString*)log logLevel:(WXLogLevel)level;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - WXApi
|
||||||
|
|
||||||
|
/*! @brief 微信Api接口函数类
|
||||||
|
*
|
||||||
|
* 该类封装了微信终端SDK的所有接口
|
||||||
|
*/
|
||||||
|
@interface WXApi : NSObject
|
||||||
|
|
||||||
|
/*! @brief WXApi的成员函数,向微信终端程序注册第三方应用。
|
||||||
|
*
|
||||||
|
* 需要在每次启动第三方应用程序时调用。
|
||||||
|
* @attention 请保证在主线程中调用此函数
|
||||||
|
* @param appid 微信开发者ID
|
||||||
|
* @param universalLink 微信开发者Universal Link
|
||||||
|
* @return 成功返回YES,失败返回NO。
|
||||||
|
*/
|
||||||
|
+ (BOOL)registerApp:(NSString *)appid universalLink:(NSString *)universalLink;
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 处理旧版微信通过URL启动App时传递的数据
|
||||||
|
*
|
||||||
|
* 需要在 application:openURL:sourceApplication:annotation:或者application:handleOpenURL中调用。
|
||||||
|
* @param url 微信启动第三方应用时传递过来的URL
|
||||||
|
* @param delegate WXApiDelegate对象,用来接收微信触发的消息。
|
||||||
|
* @return 成功返回YES,失败返回NO。
|
||||||
|
*/
|
||||||
|
+ (BOOL)handleOpenURL:(NSURL *)url delegate:(nullable id<WXApiDelegate>)delegate;
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 处理微信通过Universal Link启动App时传递的数据
|
||||||
|
*
|
||||||
|
* 需要在 application:continueUserActivity:restorationHandler:中调用。
|
||||||
|
* @param userActivity 微信启动第三方应用时系统API传递过来的userActivity
|
||||||
|
* @param delegate WXApiDelegate对象,用来接收微信触发的消息。
|
||||||
|
* @return 成功返回YES,失败返回NO。
|
||||||
|
*/
|
||||||
|
+ (BOOL)handleOpenUniversalLink:(NSUserActivity *)userActivity delegate:(nullable id<WXApiDelegate>)delegate;
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 检查微信是否已被用户安装
|
||||||
|
*
|
||||||
|
* @return 微信已安装返回YES,未安装返回NO。
|
||||||
|
*/
|
||||||
|
+ (BOOL)isWXAppInstalled;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 判断当前微信的版本是否支持OpenApi
|
||||||
|
*
|
||||||
|
* @return 支持返回YES,不支持返回NO。
|
||||||
|
*/
|
||||||
|
+ (BOOL)isWXAppSupportApi;
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 判断当前微信的版本是否支持分享微信状态功能
|
||||||
|
*
|
||||||
|
* @attention 需在工程LSApplicationQueriesSchemes配置中添加weixinStateAPI
|
||||||
|
* @return 支持返回YES,不支持返回NO。
|
||||||
|
*/
|
||||||
|
+ (BOOL)isWXAppSupportStateAPI;
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef BUILD_WITHOUT_PAY
|
||||||
|
/*! @brief 判断当前微信的版本是否支持二维码拉起微信支付
|
||||||
|
*
|
||||||
|
* @attention 需在工程LSApplicationQueriesSchemes配置中添加weixinQRCodePayAPI
|
||||||
|
* @return 支持返回YES,不支持返回NO。
|
||||||
|
*/
|
||||||
|
+ (BOOL)isWXAppSupportQRCodePayAPI;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 获取微信的itunes安装地址
|
||||||
|
*
|
||||||
|
* @return 微信的安装地址字符串。
|
||||||
|
*/
|
||||||
|
+ (NSString *)getWXAppInstallUrl;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 获取当前微信SDK的版本号
|
||||||
|
*
|
||||||
|
* @return 返回当前微信SDK的版本号
|
||||||
|
*/
|
||||||
|
+ (NSString *)getApiVersion;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 打开微信
|
||||||
|
*
|
||||||
|
* @return 成功返回YES,失败返回NO。
|
||||||
|
*/
|
||||||
|
+ (BOOL)openWXApp;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 发送请求到微信,等待微信返回onResp
|
||||||
|
*
|
||||||
|
* 函数调用后,会切换到微信的界面。第三方应用程序等待微信返回onResp。微信在异步处理完成后一定会调用onResp。支持以下类型
|
||||||
|
* SendAuthReq、SendMessageToWXReq、PayReq等。
|
||||||
|
* @param req 具体的发送请求。
|
||||||
|
* @param completion 调用结果回调block
|
||||||
|
*/
|
||||||
|
+ (void)sendReq:(BaseReq *)req completion:(void (^ __nullable)(BOOL success))completion;
|
||||||
|
|
||||||
|
/*! @brief 收到微信onReq的请求,发送对应的应答给微信,并切换到微信界面
|
||||||
|
*
|
||||||
|
* 函数调用后,会切换到微信的界面。第三方应用程序收到微信onReq的请求,异步处理该请求,完成后必须调用该函数。可能发送的相应有
|
||||||
|
* GetMessageFromWXResp、ShowMessageFromWXResp等。
|
||||||
|
* @param resp 具体的应答内容
|
||||||
|
* @param completion 调用结果回调block
|
||||||
|
*/
|
||||||
|
+ (void)sendResp:(BaseResp*)resp completion:(void (^ __nullable)(BOOL success))completion;
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 发送Auth请求到微信,支持用户没安装微信,等待微信返回onResp
|
||||||
|
*
|
||||||
|
* 函数调用后,会切换到微信的界面。第三方应用程序等待微信返回onResp。微信在异步处理完成后一定会调用onResp。支持SendAuthReq类型。
|
||||||
|
* @param req 具体的发送请求。
|
||||||
|
* @param viewController 当前界面对象。
|
||||||
|
* @param delegate WXApiDelegate对象,用来接收微信触发的消息。
|
||||||
|
* @param completion 调用结果回调block
|
||||||
|
*/
|
||||||
|
+ (void)sendAuthReq:(SendAuthReq *)req viewController:(UIViewController*)viewController delegate:(nullable id<WXApiDelegate>)delegate completion:(void (^ __nullable)(BOOL success))completion;
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 测试函数,用于排查当前App通过Universal Link方式分享到微信的流程
|
||||||
|
注意1: 调用自检函数之前必须要先调用registerApp:universalLink接口, 并确认调用成功
|
||||||
|
注意2: 自检过程中会有Log产生,可以先调用startLogByLevel函数,根据Log排查问题
|
||||||
|
注意3: 会多次回调block
|
||||||
|
注意4: 仅用于新接入SDK时调试使用,请勿在正式环境的调用
|
||||||
|
*
|
||||||
|
* 当completion回调的step为WXULCheckStepFinal时,表示检测通过,Universal Link接入成功
|
||||||
|
* @param completion 回调Block
|
||||||
|
*/
|
||||||
|
+ (void)checkUniversalLinkReady:(nonnull WXCheckULCompletion)completion;
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief WXApi的成员函数,接受微信的log信息。byBlock
|
||||||
|
注意1:SDK会强引用这个block,注意不要导致内存泄漏,注意不要导致内存泄漏
|
||||||
|
注意2:调用过一次startLog by block之后,如果再调用一次任意方式的startLoad,会释放上一次logBlock,不再回调上一个logBlock
|
||||||
|
*
|
||||||
|
* @param level 打印log的级别
|
||||||
|
* @param logBlock 打印log的回调block
|
||||||
|
*/
|
||||||
|
|
||||||
|
+ (void)startLogByLevel:(WXLogLevel)level logBlock:(WXLogBolock)logBlock;
|
||||||
|
|
||||||
|
/*! @brief WXApi的成员函数,接受微信的log信息。byDelegate
|
||||||
|
注意1:sdk会弱引用这个delegate,这里可加任意对象为代理,不需要与WXApiDelegate同一个对象
|
||||||
|
注意2:调用过一次startLog by delegate之后,再调用一次任意方式的startLoad,不会再回调上一个logDelegate对象
|
||||||
|
* @param level 打印log的级别
|
||||||
|
* @param logDelegate 打印log的回调代理,
|
||||||
|
*/
|
||||||
|
+ (void)startLogByLevel:(WXLogLevel)level logDelegate:(id<WXApiLogDelegate>)logDelegate;
|
||||||
|
|
||||||
|
/*! @brief 停止打印log,会清理block或者delegate为空,释放block
|
||||||
|
* @param
|
||||||
|
*/
|
||||||
|
+ (void)stopLog;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,68 @@
|
|||||||
|
//
|
||||||
|
// WechatAuthSDK.h
|
||||||
|
// WechatAuthSDK
|
||||||
|
//
|
||||||
|
// Created by 李凯 on 13-11-29.
|
||||||
|
// Copyright (c) 2013年 Tencent. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
enum AuthErrCode {
|
||||||
|
WechatAuth_Err_Ok = 0, //Auth成功
|
||||||
|
WechatAuth_Err_NormalErr = -1, //普通错误
|
||||||
|
WechatAuth_Err_NetworkErr = -2, //网络错误
|
||||||
|
WechatAuth_Err_GetQrcodeFailed = -3, //获取二维码失败
|
||||||
|
WechatAuth_Err_Cancel = -4, //用户取消授权
|
||||||
|
WechatAuth_Err_Timeout = -5, //超时
|
||||||
|
};
|
||||||
|
|
||||||
|
@protocol WechatAuthAPIDelegate<NSObject>
|
||||||
|
@optional
|
||||||
|
|
||||||
|
- (void)onAuthGotQrcode:(UIImage *)image; //得到二维码
|
||||||
|
- (void)onQrcodeScanned; //二维码被扫描
|
||||||
|
- (void)onAuthFinish:(int)errCode AuthCode:(nullable NSString *)authCode; //成功登录
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface WechatAuthSDK : NSObject{
|
||||||
|
NSString *_sdkVersion;
|
||||||
|
__weak id<WechatAuthAPIDelegate> _delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@property(nonatomic, weak, nullable) id<WechatAuthAPIDelegate> delegate;
|
||||||
|
@property(nonatomic, readonly) NSString *sdkVersion; //authSDK版本号
|
||||||
|
|
||||||
|
/*! @brief 发送登录请求,等待WechatAuthAPIDelegate回调
|
||||||
|
*
|
||||||
|
* @param appId 微信开发者ID
|
||||||
|
* @param nonceStr 一个随机的尽量不重复的字符串,用来使得每次的signature不同
|
||||||
|
* @param timeStamp 时间戳
|
||||||
|
* @param scope 应用授权作用域,拥有多个作用域用逗号(,)分隔
|
||||||
|
* @param signature 签名
|
||||||
|
* @param schemeData 会在扫码后拼在scheme后
|
||||||
|
* @return 成功返回YES,失败返回NO
|
||||||
|
注:该实现只保证同时只有一个Auth在运行,Auth未完成或未Stop再次调用Auth接口时会返回NO。
|
||||||
|
*/
|
||||||
|
|
||||||
|
- (BOOL)Auth:(NSString *)appId
|
||||||
|
nonceStr:(NSString *)nonceStr
|
||||||
|
timeStamp:(NSString *)timeStamp
|
||||||
|
scope:(NSString *)scope
|
||||||
|
signature:(NSString *)signature
|
||||||
|
schemeData:(nullable NSString *)schemeData;
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 暂停登录请求
|
||||||
|
*
|
||||||
|
* @return 成功返回YES,失败返回NO。
|
||||||
|
*/
|
||||||
|
- (BOOL)StopAuth;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
// WechatOpenSDK.h
|
||||||
|
//
|
||||||
|
// Created by Wechat.
|
||||||
|
// Copyright (c) 2012年 Tencent. All rights reserved.
|
||||||
|
//
|
||||||
|
#import <WechatOpenSDK/WXApi.h>
|
||||||
|
#import <WechatOpenSDK/WXApiObject.h>
|
||||||
|
#import <WechatOpenSDK/WechatAuthSDK.h>
|
||||||
|
|
||||||
15
Pods/WechatOpenSDK-XCFramework/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Info.plist
generated
Executable file
15
Pods/WechatOpenSDK-XCFramework/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Info.plist
generated
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>com.tencent.WechatOpenSDK</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1.0.0</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>MinimumOSVersion</key>
|
||||||
|
<string>12.0</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>WechatOpenSDK</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
framework module WechatOpenSDK {
|
||||||
|
umbrella header "WechatOpenSDK.h"
|
||||||
|
export *
|
||||||
|
link "WechatOpenSDK"
|
||||||
|
}
|
||||||
BIN
Pods/WechatOpenSDK-XCFramework/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/WechatOpenSDK
generated
Normal file
BIN
Pods/WechatOpenSDK-XCFramework/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/WechatOpenSDK
generated
Normal file
Binary file not shown.
@ -0,0 +1,231 @@
|
|||||||
|
//
|
||||||
|
// WXApi.h
|
||||||
|
// 所有Api接口
|
||||||
|
//
|
||||||
|
// Created by Wechat on 12-2-28.
|
||||||
|
// Copyright (c) 2012年 Tencent. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "WXApiObject.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
|
||||||
|
typedef BOOL(^WXGrantReadPasteBoardPermissionCompletion)(void);
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - WXApiDelegate
|
||||||
|
/*! @brief 接收并处理来自微信终端程序的事件消息
|
||||||
|
*
|
||||||
|
* 接收并处理来自微信终端程序的事件消息,期间微信界面会切换到第三方应用程序。
|
||||||
|
* WXApiDelegate 会在handleOpenURL:delegate:中使用并触发。
|
||||||
|
*/
|
||||||
|
@protocol WXApiDelegate <NSObject>
|
||||||
|
@optional
|
||||||
|
|
||||||
|
/*! @brief 收到一个来自微信的请求,第三方应用程序处理完后调用sendResp向微信发送结果
|
||||||
|
*
|
||||||
|
* 收到一个来自微信的请求,异步处理完成后必须调用sendResp发送处理结果给微信。
|
||||||
|
* 可能收到的请求有GetMessageFromWXReq、ShowMessageFromWXReq等。
|
||||||
|
* @param req 具体请求内容,是自动释放的
|
||||||
|
*/
|
||||||
|
- (void)onReq:(BaseReq*)req;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 发送一个sendReq后,收到微信的回应
|
||||||
|
*
|
||||||
|
* 收到一个来自微信的处理结果。调用一次sendReq后会收到onResp。
|
||||||
|
* 可能收到的处理结果有SendMessageToWXResp、SendAuthResp等。
|
||||||
|
* @param resp具体的回应内容,是自动释放的
|
||||||
|
*/
|
||||||
|
- (void)onResp:(BaseResp*)resp;
|
||||||
|
|
||||||
|
/* ! @brief 用于在iOS16以及以上系统上,控制OpenSDK是否读取剪切板中微信传递的数据以及读取的时机
|
||||||
|
* 在iOS16以及以上系统,在SDK需要读取剪切板中微信写入的数据时,会回调该方法。没有实现默认会直接读取微信通过剪切板传递过来的数据
|
||||||
|
* 注意:
|
||||||
|
* 1. 只在iOS16以及以上的系统版本上回调;
|
||||||
|
* 2. 不实现时,OpenSDK会直接调用读取剪切板接口,读取微信传递过来的数据;
|
||||||
|
* 3. 若实现该方法:开发者需要通过调用completion(), 支持异步,通知SDK允许读取剪切板中微信传递的数据,
|
||||||
|
* 不调用completion()则代表不授权OpenSDK读取剪切板,会导致收不到onReq:, onResp:回调,无法后续业务流程。请谨慎使用
|
||||||
|
* 4. 不要长时间持有completion不释放,可能会导致内存泄漏。
|
||||||
|
*/
|
||||||
|
- (void)onNeedGrantReadPasteBoardPermissionWithURL:(nonnull NSURL *)openURL completion:(nonnull WXGrantReadPasteBoardPermissionCompletion)completion;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark - WXApiLogDelegate
|
||||||
|
|
||||||
|
@protocol WXApiLogDelegate <NSObject>
|
||||||
|
|
||||||
|
- (void)onLog:(NSString*)log logLevel:(WXLogLevel)level;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - WXApi
|
||||||
|
|
||||||
|
/*! @brief 微信Api接口函数类
|
||||||
|
*
|
||||||
|
* 该类封装了微信终端SDK的所有接口
|
||||||
|
*/
|
||||||
|
@interface WXApi : NSObject
|
||||||
|
|
||||||
|
/*! @brief WXApi的成员函数,向微信终端程序注册第三方应用。
|
||||||
|
*
|
||||||
|
* 需要在每次启动第三方应用程序时调用。
|
||||||
|
* @attention 请保证在主线程中调用此函数
|
||||||
|
* @param appid 微信开发者ID
|
||||||
|
* @param universalLink 微信开发者Universal Link
|
||||||
|
* @return 成功返回YES,失败返回NO。
|
||||||
|
*/
|
||||||
|
+ (BOOL)registerApp:(NSString *)appid universalLink:(NSString *)universalLink;
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 处理旧版微信通过URL启动App时传递的数据
|
||||||
|
*
|
||||||
|
* 需要在 application:openURL:sourceApplication:annotation:或者application:handleOpenURL中调用。
|
||||||
|
* @param url 微信启动第三方应用时传递过来的URL
|
||||||
|
* @param delegate WXApiDelegate对象,用来接收微信触发的消息。
|
||||||
|
* @return 成功返回YES,失败返回NO。
|
||||||
|
*/
|
||||||
|
+ (BOOL)handleOpenURL:(NSURL *)url delegate:(nullable id<WXApiDelegate>)delegate;
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 处理微信通过Universal Link启动App时传递的数据
|
||||||
|
*
|
||||||
|
* 需要在 application:continueUserActivity:restorationHandler:中调用。
|
||||||
|
* @param userActivity 微信启动第三方应用时系统API传递过来的userActivity
|
||||||
|
* @param delegate WXApiDelegate对象,用来接收微信触发的消息。
|
||||||
|
* @return 成功返回YES,失败返回NO。
|
||||||
|
*/
|
||||||
|
+ (BOOL)handleOpenUniversalLink:(NSUserActivity *)userActivity delegate:(nullable id<WXApiDelegate>)delegate;
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 检查微信是否已被用户安装
|
||||||
|
*
|
||||||
|
* @return 微信已安装返回YES,未安装返回NO。
|
||||||
|
*/
|
||||||
|
+ (BOOL)isWXAppInstalled;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 判断当前微信的版本是否支持OpenApi
|
||||||
|
*
|
||||||
|
* @return 支持返回YES,不支持返回NO。
|
||||||
|
*/
|
||||||
|
+ (BOOL)isWXAppSupportApi;
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 判断当前微信的版本是否支持分享微信状态功能
|
||||||
|
*
|
||||||
|
* @attention 需在工程LSApplicationQueriesSchemes配置中添加weixinStateAPI
|
||||||
|
* @return 支持返回YES,不支持返回NO。
|
||||||
|
*/
|
||||||
|
+ (BOOL)isWXAppSupportStateAPI;
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef BUILD_WITHOUT_PAY
|
||||||
|
/*! @brief 判断当前微信的版本是否支持二维码拉起微信支付
|
||||||
|
*
|
||||||
|
* @attention 需在工程LSApplicationQueriesSchemes配置中添加weixinQRCodePayAPI
|
||||||
|
* @return 支持返回YES,不支持返回NO。
|
||||||
|
*/
|
||||||
|
+ (BOOL)isWXAppSupportQRCodePayAPI;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 获取微信的itunes安装地址
|
||||||
|
*
|
||||||
|
* @return 微信的安装地址字符串。
|
||||||
|
*/
|
||||||
|
+ (NSString *)getWXAppInstallUrl;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 获取当前微信SDK的版本号
|
||||||
|
*
|
||||||
|
* @return 返回当前微信SDK的版本号
|
||||||
|
*/
|
||||||
|
+ (NSString *)getApiVersion;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 打开微信
|
||||||
|
*
|
||||||
|
* @return 成功返回YES,失败返回NO。
|
||||||
|
*/
|
||||||
|
+ (BOOL)openWXApp;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 发送请求到微信,等待微信返回onResp
|
||||||
|
*
|
||||||
|
* 函数调用后,会切换到微信的界面。第三方应用程序等待微信返回onResp。微信在异步处理完成后一定会调用onResp。支持以下类型
|
||||||
|
* SendAuthReq、SendMessageToWXReq、PayReq等。
|
||||||
|
* @param req 具体的发送请求。
|
||||||
|
* @param completion 调用结果回调block
|
||||||
|
*/
|
||||||
|
+ (void)sendReq:(BaseReq *)req completion:(void (^ __nullable)(BOOL success))completion;
|
||||||
|
|
||||||
|
/*! @brief 收到微信onReq的请求,发送对应的应答给微信,并切换到微信界面
|
||||||
|
*
|
||||||
|
* 函数调用后,会切换到微信的界面。第三方应用程序收到微信onReq的请求,异步处理该请求,完成后必须调用该函数。可能发送的相应有
|
||||||
|
* GetMessageFromWXResp、ShowMessageFromWXResp等。
|
||||||
|
* @param resp 具体的应答内容
|
||||||
|
* @param completion 调用结果回调block
|
||||||
|
*/
|
||||||
|
+ (void)sendResp:(BaseResp*)resp completion:(void (^ __nullable)(BOOL success))completion;
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 发送Auth请求到微信,支持用户没安装微信,等待微信返回onResp
|
||||||
|
*
|
||||||
|
* 函数调用后,会切换到微信的界面。第三方应用程序等待微信返回onResp。微信在异步处理完成后一定会调用onResp。支持SendAuthReq类型。
|
||||||
|
* @param req 具体的发送请求。
|
||||||
|
* @param viewController 当前界面对象。
|
||||||
|
* @param delegate WXApiDelegate对象,用来接收微信触发的消息。
|
||||||
|
* @param completion 调用结果回调block
|
||||||
|
*/
|
||||||
|
+ (void)sendAuthReq:(SendAuthReq *)req viewController:(UIViewController*)viewController delegate:(nullable id<WXApiDelegate>)delegate completion:(void (^ __nullable)(BOOL success))completion;
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 测试函数,用于排查当前App通过Universal Link方式分享到微信的流程
|
||||||
|
注意1: 调用自检函数之前必须要先调用registerApp:universalLink接口, 并确认调用成功
|
||||||
|
注意2: 自检过程中会有Log产生,可以先调用startLogByLevel函数,根据Log排查问题
|
||||||
|
注意3: 会多次回调block
|
||||||
|
注意4: 仅用于新接入SDK时调试使用,请勿在正式环境的调用
|
||||||
|
*
|
||||||
|
* 当completion回调的step为WXULCheckStepFinal时,表示检测通过,Universal Link接入成功
|
||||||
|
* @param completion 回调Block
|
||||||
|
*/
|
||||||
|
+ (void)checkUniversalLinkReady:(nonnull WXCheckULCompletion)completion;
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief WXApi的成员函数,接受微信的log信息。byBlock
|
||||||
|
注意1:SDK会强引用这个block,注意不要导致内存泄漏,注意不要导致内存泄漏
|
||||||
|
注意2:调用过一次startLog by block之后,如果再调用一次任意方式的startLoad,会释放上一次logBlock,不再回调上一个logBlock
|
||||||
|
*
|
||||||
|
* @param level 打印log的级别
|
||||||
|
* @param logBlock 打印log的回调block
|
||||||
|
*/
|
||||||
|
|
||||||
|
+ (void)startLogByLevel:(WXLogLevel)level logBlock:(WXLogBolock)logBlock;
|
||||||
|
|
||||||
|
/*! @brief WXApi的成员函数,接受微信的log信息。byDelegate
|
||||||
|
注意1:sdk会弱引用这个delegate,这里可加任意对象为代理,不需要与WXApiDelegate同一个对象
|
||||||
|
注意2:调用过一次startLog by delegate之后,再调用一次任意方式的startLoad,不会再回调上一个logDelegate对象
|
||||||
|
* @param level 打印log的级别
|
||||||
|
* @param logDelegate 打印log的回调代理,
|
||||||
|
*/
|
||||||
|
+ (void)startLogByLevel:(WXLogLevel)level logDelegate:(id<WXApiLogDelegate>)logDelegate;
|
||||||
|
|
||||||
|
/*! @brief 停止打印log,会清理block或者delegate为空,释放block
|
||||||
|
* @param
|
||||||
|
*/
|
||||||
|
+ (void)stopLog;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,68 @@
|
|||||||
|
//
|
||||||
|
// WechatAuthSDK.h
|
||||||
|
// WechatAuthSDK
|
||||||
|
//
|
||||||
|
// Created by 李凯 on 13-11-29.
|
||||||
|
// Copyright (c) 2013年 Tencent. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
enum AuthErrCode {
|
||||||
|
WechatAuth_Err_Ok = 0, //Auth成功
|
||||||
|
WechatAuth_Err_NormalErr = -1, //普通错误
|
||||||
|
WechatAuth_Err_NetworkErr = -2, //网络错误
|
||||||
|
WechatAuth_Err_GetQrcodeFailed = -3, //获取二维码失败
|
||||||
|
WechatAuth_Err_Cancel = -4, //用户取消授权
|
||||||
|
WechatAuth_Err_Timeout = -5, //超时
|
||||||
|
};
|
||||||
|
|
||||||
|
@protocol WechatAuthAPIDelegate<NSObject>
|
||||||
|
@optional
|
||||||
|
|
||||||
|
- (void)onAuthGotQrcode:(UIImage *)image; //得到二维码
|
||||||
|
- (void)onQrcodeScanned; //二维码被扫描
|
||||||
|
- (void)onAuthFinish:(int)errCode AuthCode:(nullable NSString *)authCode; //成功登录
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface WechatAuthSDK : NSObject{
|
||||||
|
NSString *_sdkVersion;
|
||||||
|
__weak id<WechatAuthAPIDelegate> _delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@property(nonatomic, weak, nullable) id<WechatAuthAPIDelegate> delegate;
|
||||||
|
@property(nonatomic, readonly) NSString *sdkVersion; //authSDK版本号
|
||||||
|
|
||||||
|
/*! @brief 发送登录请求,等待WechatAuthAPIDelegate回调
|
||||||
|
*
|
||||||
|
* @param appId 微信开发者ID
|
||||||
|
* @param nonceStr 一个随机的尽量不重复的字符串,用来使得每次的signature不同
|
||||||
|
* @param timeStamp 时间戳
|
||||||
|
* @param scope 应用授权作用域,拥有多个作用域用逗号(,)分隔
|
||||||
|
* @param signature 签名
|
||||||
|
* @param schemeData 会在扫码后拼在scheme后
|
||||||
|
* @return 成功返回YES,失败返回NO
|
||||||
|
注:该实现只保证同时只有一个Auth在运行,Auth未完成或未Stop再次调用Auth接口时会返回NO。
|
||||||
|
*/
|
||||||
|
|
||||||
|
- (BOOL)Auth:(NSString *)appId
|
||||||
|
nonceStr:(NSString *)nonceStr
|
||||||
|
timeStamp:(NSString *)timeStamp
|
||||||
|
scope:(NSString *)scope
|
||||||
|
signature:(NSString *)signature
|
||||||
|
schemeData:(nullable NSString *)schemeData;
|
||||||
|
|
||||||
|
|
||||||
|
/*! @brief 暂停登录请求
|
||||||
|
*
|
||||||
|
* @return 成功返回YES,失败返回NO。
|
||||||
|
*/
|
||||||
|
- (BOOL)StopAuth;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
// WechatOpenSDK.h
|
||||||
|
//
|
||||||
|
// Created by Wechat.
|
||||||
|
// Copyright (c) 2012年 Tencent. All rights reserved.
|
||||||
|
//
|
||||||
|
#import <WechatOpenSDK/WXApi.h>
|
||||||
|
#import <WechatOpenSDK/WXApiObject.h>
|
||||||
|
#import <WechatOpenSDK/WechatAuthSDK.h>
|
||||||
|
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>com.tencent.WechatOpenSDK</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1.0.0</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>MinimumOSVersion</key>
|
||||||
|
<string>12.0</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>WechatOpenSDK</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
framework module WechatOpenSDK {
|
||||||
|
umbrella header "WechatOpenSDK.h"
|
||||||
|
export *
|
||||||
|
link "WechatOpenSDK"
|
||||||
|
}
|
||||||
Binary file not shown.
13
docs/apple-app-site-association
Normal file
13
docs/apple-app-site-association
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"applinks": {
|
||||||
|
"apps": [],
|
||||||
|
"details": [
|
||||||
|
{
|
||||||
|
"appID": "56GVN5RNVN.com.yuanzhixiang.suixinkan",
|
||||||
|
"paths": [
|
||||||
|
"/suixinkan/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
11
docs/apple-app-site-association.example.json
Normal file
11
docs/apple-app-site-association.example.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"applinks": {
|
||||||
|
"apps": [],
|
||||||
|
"details": [
|
||||||
|
{
|
||||||
|
"appID": "56GVN5RNVN.com.yuanzhixiang.suixinkan",
|
||||||
|
"paths": ["/suixinkan/*"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,8 +7,38 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
/// AppDelegate 承接 APNs 系统回调,SwiftUI App 入口通过 adaptor 注入。
|
/// AppDelegate 承接 APNs 与微信 SDK 系统回调,SwiftUI App 入口通过 adaptor 注入。
|
||||||
final class AppDelegate: NSObject, UIApplicationDelegate {
|
final class AppDelegate: NSObject, UIApplicationDelegate {
|
||||||
|
func application(
|
||||||
|
_ application: UIApplication,
|
||||||
|
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
|
||||||
|
) -> Bool {
|
||||||
|
Task { @MainActor in
|
||||||
|
WeChatManager.shared.registerIfNeeded()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func application(
|
||||||
|
_ app: UIApplication,
|
||||||
|
open url: URL,
|
||||||
|
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
|
||||||
|
) -> Bool {
|
||||||
|
MainActor.assumeIsolated {
|
||||||
|
WeChatManager.shared.handleOpenURL(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func application(
|
||||||
|
_ application: UIApplication,
|
||||||
|
continue userActivity: NSUserActivity,
|
||||||
|
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
|
||||||
|
) -> Bool {
|
||||||
|
MainActor.assumeIsolated {
|
||||||
|
WeChatManager.shared.handleContinueUserActivity(userActivity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func application(
|
func application(
|
||||||
_ application: UIApplication,
|
_ application: UIApplication,
|
||||||
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
|
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
|
||||||
|
|||||||
36
suixinkan/App/WeChatConfig.swift
Normal file
36
suixinkan/App/WeChatConfig.swift
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// WeChatConfig.swift
|
||||||
|
// suixinkan
|
||||||
|
//
|
||||||
|
// 微信 Open SDK 配置。上线前请替换为开放平台真实 AppID,并同步 Info.plist URL Scheme。
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// 微信开放平台接入配置,集中管理 AppID 与 Universal Link。
|
||||||
|
enum WeChatConfig {
|
||||||
|
/// 占位 AppID,上线前替换为微信开放平台移动应用 AppID。
|
||||||
|
static let appID = "wxdd80ec12c4fee322"
|
||||||
|
|
||||||
|
/// Universal Link,必须以 `/` 结尾,且与开放平台填写完全一致。
|
||||||
|
static let universalLink = "https://www.zhifly.cn/suixinkan/"
|
||||||
|
|
||||||
|
/// Associated Domains 域名(不含 `applinks:` 前缀)。
|
||||||
|
static let associatedDomain = "www.zhifly.cn"
|
||||||
|
|
||||||
|
/// AASA 文件 paths 通配规则,需与运维部署的 apple-app-site-association 一致。
|
||||||
|
static let aasaPathPattern = "/suixinkan/*"
|
||||||
|
|
||||||
|
/// Apple Team ID + Bundle ID,供运维部署 AASA 使用。
|
||||||
|
static let aasaAppID = "56GVN5RNVN.com.yuanzhixiang.suixinkan"
|
||||||
|
|
||||||
|
/// 校验 Universal Link 格式是否符合微信要求。
|
||||||
|
static func validateUniversalLink(_ link: String) -> Bool {
|
||||||
|
guard let url = URL(string: link),
|
||||||
|
url.scheme?.lowercased() == "https",
|
||||||
|
link.hasSuffix("/") else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -20,6 +20,12 @@ struct suixinkanApp: App {
|
|||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
WindowGroup {
|
WindowGroup {
|
||||||
RootView()
|
RootView()
|
||||||
|
.onOpenURL { url in
|
||||||
|
WeChatManager.shared.handleOpenURL(url)
|
||||||
|
}
|
||||||
|
.onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { userActivity in
|
||||||
|
_ = WeChatManager.shared.handleContinueUserActivity(userActivity)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
59
suixinkan/Core/WeChat/WeChat.md
Normal file
59
suixinkan/Core/WeChat/WeChat.md
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# WeChat 模块业务逻辑
|
||||||
|
|
||||||
|
## 模块职责
|
||||||
|
|
||||||
|
WeChat 模块封装微信 Open SDK 的注册、Universal Link 回跳与分享能力。当前仅接入分享(文本、网页、图片),不调用微信支付 API。
|
||||||
|
|
||||||
|
## 配置
|
||||||
|
|
||||||
|
- `WeChatConfig`:AppID、Universal Link、AASA 部署参考信息
|
||||||
|
- `Info.plist`:URL Scheme(AppID)、`LSApplicationQueriesSchemes`
|
||||||
|
- `suixinkan.entitlements`:`applinks:www.zhifly.cn`
|
||||||
|
|
||||||
|
### Universal Link
|
||||||
|
|
||||||
|
- 地址:`https://www.zhifly.cn/suixinkan/`(必须以 `/` 结尾)
|
||||||
|
- 运维需在 `https://www.zhifly.cn/.well-known/apple-app-site-association` 部署 AASA 文件
|
||||||
|
- 示例见 [`docs/apple-app-site-association.example.json`](../../docs/apple-app-site-association.example.json)
|
||||||
|
|
||||||
|
### 微信开放平台
|
||||||
|
|
||||||
|
移动应用开发信息需填写:
|
||||||
|
|
||||||
|
| 字段 | 值 |
|
||||||
|
|------|-----|
|
||||||
|
| iOS Bundle ID | `com.yuanzhixiang.suixinkan` |
|
||||||
|
| Universal Links | `https://www.zhifly.cn/suixinkan/` |
|
||||||
|
|
||||||
|
## 核心类型
|
||||||
|
|
||||||
|
| 类型 | 职责 |
|
||||||
|
|------|------|
|
||||||
|
| `WeChatManager` | SDK 注册、URL/UL 回调、`WXApiDelegate` 分享结果 |
|
||||||
|
| `WeChatShareService` | 对外分享 API:`shareText` / `shareWebPage` / `shareImage` |
|
||||||
|
| `WeChatShareSheet` | SwiftUI 分享面板(好友/朋友圈/系统兜底) |
|
||||||
|
| `WeChatThumbImageProcessor` | 缩略图压缩至 32KB 以内 |
|
||||||
|
|
||||||
|
## 回调链路
|
||||||
|
|
||||||
|
1. 启动:`AppDelegate.didFinishLaunching` → `WeChatManager.registerIfNeeded()`
|
||||||
|
2. URL Scheme:`AppDelegate.openURL` + `suixinkanApp.onOpenURL`
|
||||||
|
3. Universal Link:`AppDelegate.continueUserActivity` + `suixinkanApp.onContinueUserActivity`
|
||||||
|
|
||||||
|
## 业务接入
|
||||||
|
|
||||||
|
邀请页 `PhotographerInviteView` 通过 `WeChatShareSheet` 分享邀请链接。
|
||||||
|
|
||||||
|
后续举报、排队二维码等入口可复用 `WeChatShareService`。
|
||||||
|
|
||||||
|
## 真机验收
|
||||||
|
|
||||||
|
1. Safari 访问 `https://www.zhifly.cn/suixinkan/test`,下拉应出现打开 App 入口
|
||||||
|
2. 邀请页点击「分享」→ 微信好友/朋友圈,首次可能出现「正在连接」属正常
|
||||||
|
3. 未安装微信时走系统分享兜底
|
||||||
|
|
||||||
|
## 上线前
|
||||||
|
|
||||||
|
- 替换 `WeChatConfig.appID` 与 Info.plist URL Scheme
|
||||||
|
- 确认开放平台 Universal Link 与代码一致
|
||||||
|
- 确认 AASA 文件可公网 HTTPS 访问
|
||||||
119
suixinkan/Core/WeChat/WeChatManager.swift
Normal file
119
suixinkan/Core/WeChat/WeChatManager.swift
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
//
|
||||||
|
// WeChatManager.swift
|
||||||
|
// suixinkan
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import WechatOpenSDK
|
||||||
|
|
||||||
|
/// 微信 SDK 生命周期与回调管理,负责注册、URL/Universal Link 回跳及分享结果分发。
|
||||||
|
@MainActor
|
||||||
|
final class WeChatManager: NSObject {
|
||||||
|
static let shared = WeChatManager()
|
||||||
|
|
||||||
|
/// 最近一次分享结果,供 UI 监听。
|
||||||
|
private(set) var lastShareResult: WeChatShareResult?
|
||||||
|
|
||||||
|
private var shareCompletion: ((WeChatShareResult) -> Void)?
|
||||||
|
private var isRegistered = false
|
||||||
|
|
||||||
|
private override init() {
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 向微信注册 AppID 与 Universal Link,应用启动时调用。
|
||||||
|
func registerIfNeeded() {
|
||||||
|
guard !isRegistered else { return }
|
||||||
|
guard WeChatConfig.validateUniversalLink(WeChatConfig.universalLink) else {
|
||||||
|
assertionFailure("WeChat Universal Link 必须以 https 开头并以 / 结尾")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
WXApi.startLog(by: WXLogLevel.detail) { log in
|
||||||
|
print("WeChatSDK: \(log)")
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
let success = WXApi.registerApp(WeChatConfig.appID, universalLink: WeChatConfig.universalLink)
|
||||||
|
isRegistered = success
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
if success {
|
||||||
|
checkUniversalLinkReady()
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 处理 URL Scheme 回调。
|
||||||
|
@discardableResult
|
||||||
|
func handleOpenURL(_ url: URL) -> Bool {
|
||||||
|
WXApi.handleOpen(url, delegate: self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 处理 Universal Link 回调。
|
||||||
|
@discardableResult
|
||||||
|
func handleContinueUserActivity(_ userActivity: NSUserActivity) -> Bool {
|
||||||
|
WXApi.handleOpenUniversalLink(userActivity, delegate: self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 注册单次分享完成回调。
|
||||||
|
func setShareCompletion(_ completion: ((WeChatShareResult) -> Void)?) {
|
||||||
|
shareCompletion = completion
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 发送分享请求到微信。
|
||||||
|
func sendShareRequest(_ request: SendMessageToWXReq, completion: ((WeChatShareResult) -> Void)? = nil) {
|
||||||
|
guard WXApi.isWXAppInstalled() else {
|
||||||
|
let result = WeChatShareResult.notInstalled
|
||||||
|
completion?(result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard WXApi.isWXAppSupport() else {
|
||||||
|
let result = WeChatShareResult.unsupported
|
||||||
|
completion?(result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if let completion {
|
||||||
|
shareCompletion = completion
|
||||||
|
}
|
||||||
|
|
||||||
|
WXApi.send(request) { success in
|
||||||
|
if !success {
|
||||||
|
Task { @MainActor in
|
||||||
|
self.finishShare(with: .sendFailed(-1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
/// 调试 Universal Link 配置,仅 DEBUG 环境调用。
|
||||||
|
private func checkUniversalLinkReady() {
|
||||||
|
WXApi.checkUniversalLinkReady { step, result in
|
||||||
|
print("WeChat UL check step=\(step.rawValue) success=\(result.success) info=\(result.errorInfo ?? "") suggestion=\(result.suggestion ?? "")")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private func finishShare(with result: WeChatShareResult) {
|
||||||
|
lastShareResult = result
|
||||||
|
shareCompletion?(result)
|
||||||
|
shareCompletion = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension WeChatManager: WXApiDelegate {
|
||||||
|
nonisolated func onReq(_ req: BaseReq) {
|
||||||
|
// 分享模块暂不处理来自微信的主动请求。
|
||||||
|
}
|
||||||
|
|
||||||
|
nonisolated func onResp(_ resp: BaseResp) {
|
||||||
|
guard let shareResp = resp as? SendMessageToWXResp else { return }
|
||||||
|
let result = WeChatShareResult.fromWXErrorCode(shareResp.errCode)
|
||||||
|
Task { @MainActor in
|
||||||
|
self.finishShare(with: result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
70
suixinkan/Core/WeChat/WeChatShareModels.swift
Normal file
70
suixinkan/Core/WeChat/WeChatShareModels.swift
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
//
|
||||||
|
// WeChatShareModels.swift
|
||||||
|
// suixinkan
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// 微信分享目标场景。
|
||||||
|
enum WeChatShareScene: Int, CaseIterable, Sendable {
|
||||||
|
/// 微信好友会话。
|
||||||
|
case session = 0
|
||||||
|
/// 朋友圈。
|
||||||
|
case timeline = 1
|
||||||
|
/// 微信收藏。
|
||||||
|
case favorite = 2
|
||||||
|
|
||||||
|
/// 展示用标题。
|
||||||
|
var title: String {
|
||||||
|
switch self {
|
||||||
|
case .session: "微信好友"
|
||||||
|
case .timeline: "朋友圈"
|
||||||
|
case .favorite: "收藏"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 映射到微信 SDK 的 scene 常量。
|
||||||
|
var wxSceneValue: Int32 {
|
||||||
|
Int32(rawValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 微信分享请求结果。
|
||||||
|
enum WeChatShareResult: Equatable, Sendable {
|
||||||
|
case success
|
||||||
|
case cancelled
|
||||||
|
case notInstalled
|
||||||
|
case unsupported
|
||||||
|
case invalidPayload(String)
|
||||||
|
case sendFailed(Int)
|
||||||
|
case unknown(Int)
|
||||||
|
|
||||||
|
/// 根据微信 SDK 错误码解析分享结果。
|
||||||
|
static func fromWXErrorCode(_ code: Int32) -> WeChatShareResult {
|
||||||
|
switch code {
|
||||||
|
case 0:
|
||||||
|
.success
|
||||||
|
case -2:
|
||||||
|
.cancelled
|
||||||
|
default:
|
||||||
|
.unknown(Int(code))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 网页分享载荷,供业务层与分享服务之间传递。
|
||||||
|
struct WeChatWebPageSharePayload: Equatable, Sendable {
|
||||||
|
let title: String
|
||||||
|
let description: String
|
||||||
|
let url: String
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 文本分享载荷。
|
||||||
|
struct WeChatTextSharePayload: Equatable, Sendable {
|
||||||
|
let text: String
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 图片分享载荷。
|
||||||
|
struct WeChatImageSharePayload: Equatable, Sendable {
|
||||||
|
let imageData: Data
|
||||||
|
}
|
||||||
115
suixinkan/Core/WeChat/WeChatShareService.swift
Normal file
115
suixinkan/Core/WeChat/WeChatShareService.swift
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
//
|
||||||
|
// WeChatShareService.swift
|
||||||
|
// suixinkan
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import WechatOpenSDK
|
||||||
|
|
||||||
|
/// 微信分享服务,封装文本、网页、图片分享能力(不含支付)。
|
||||||
|
enum WeChatShareService {
|
||||||
|
/// 是否已安装微信且支持 Open SDK。
|
||||||
|
static var isWeChatAvailable: Bool {
|
||||||
|
WXApi.isWXAppInstalled() && WXApi.isWXAppSupport()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 分享纯文本到微信。
|
||||||
|
@MainActor
|
||||||
|
static func shareText(
|
||||||
|
_ payload: WeChatTextSharePayload,
|
||||||
|
scene: WeChatShareScene,
|
||||||
|
completion: ((WeChatShareResult) -> Void)? = nil
|
||||||
|
) {
|
||||||
|
let trimmed = payload.text.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
guard !trimmed.isEmpty else {
|
||||||
|
completion?(.invalidPayload("分享文本不能为空"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let request = SendMessageToWXReq()
|
||||||
|
request.bText = true
|
||||||
|
request.text = trimmed
|
||||||
|
request.scene = scene.wxSceneValue
|
||||||
|
WeChatManager.shared.sendShareRequest(request, completion: completion)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 分享网页链接到微信。
|
||||||
|
@MainActor
|
||||||
|
static func shareWebPage(
|
||||||
|
_ payload: WeChatWebPageSharePayload,
|
||||||
|
scene: WeChatShareScene,
|
||||||
|
thumbImage: UIImage? = nil,
|
||||||
|
completion: ((WeChatShareResult) -> Void)? = nil
|
||||||
|
) {
|
||||||
|
let title = payload.title.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
let url = payload.url.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
guard !title.isEmpty else {
|
||||||
|
completion?(.invalidPayload("分享标题不能为空"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard !url.isEmpty else {
|
||||||
|
completion?(.invalidPayload("分享链接不能为空"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let webpageObject = WXWebpageObject()
|
||||||
|
webpageObject.webpageUrl = url
|
||||||
|
|
||||||
|
let message = WXMediaMessage()
|
||||||
|
message.title = title
|
||||||
|
message.description = payload.description
|
||||||
|
message.mediaObject = webpageObject
|
||||||
|
if let thumbImage, let thumbData = WeChatThumbImageProcessor.makeThumbData(from: thumbImage) {
|
||||||
|
message.thumbData = thumbData
|
||||||
|
}
|
||||||
|
|
||||||
|
let request = SendMessageToWXReq()
|
||||||
|
request.bText = false
|
||||||
|
request.message = message
|
||||||
|
request.scene = scene.wxSceneValue
|
||||||
|
WeChatManager.shared.sendShareRequest(request, completion: completion)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 分享图片到微信。
|
||||||
|
@MainActor
|
||||||
|
static func shareImage(
|
||||||
|
_ payload: WeChatImageSharePayload,
|
||||||
|
scene: WeChatShareScene,
|
||||||
|
thumbImage: UIImage? = nil,
|
||||||
|
completion: ((WeChatShareResult) -> Void)? = nil
|
||||||
|
) {
|
||||||
|
guard !payload.imageData.isEmpty else {
|
||||||
|
completion?(.invalidPayload("分享图片不能为空"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let imageObject = WXImageObject()
|
||||||
|
imageObject.imageData = payload.imageData
|
||||||
|
|
||||||
|
let message = WXMediaMessage()
|
||||||
|
message.mediaObject = imageObject
|
||||||
|
if let thumbImage, let thumbData = WeChatThumbImageProcessor.makeThumbData(from: thumbImage) {
|
||||||
|
message.thumbData = thumbData
|
||||||
|
} else if let image = UIImage(data: payload.imageData),
|
||||||
|
let thumbData = WeChatThumbImageProcessor.makeThumbData(from: image) {
|
||||||
|
message.thumbData = thumbData
|
||||||
|
}
|
||||||
|
|
||||||
|
let request = SendMessageToWXReq()
|
||||||
|
request.bText = false
|
||||||
|
request.message = message
|
||||||
|
request.scene = scene.wxSceneValue
|
||||||
|
WeChatManager.shared.sendShareRequest(request, completion: completion)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 获取 App 图标,用作分享缩略图兜底。
|
||||||
|
static func defaultThumbImage() -> UIImage? {
|
||||||
|
guard let icons = Bundle.main.infoDictionary?["CFBundleIcons"] as? [String: Any],
|
||||||
|
let primary = icons["CFBundlePrimaryIcon"] as? [String: Any],
|
||||||
|
let iconFiles = primary["CFBundleIconFiles"] as? [String],
|
||||||
|
let iconName = iconFiles.last else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return UIImage(named: iconName)
|
||||||
|
}
|
||||||
|
}
|
||||||
105
suixinkan/Core/WeChat/WeChatShareSheet.swift
Normal file
105
suixinkan/Core/WeChat/WeChatShareSheet.swift
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
//
|
||||||
|
// WeChatShareSheet.swift
|
||||||
|
// suixinkan
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
/// 微信分享选项面板,支持好友/朋友圈及系统分享兜底。
|
||||||
|
struct WeChatShareSheet: View {
|
||||||
|
let title: String
|
||||||
|
let description: String
|
||||||
|
let url: String
|
||||||
|
let thumbImage: UIImage?
|
||||||
|
let onResult: (String) -> Void
|
||||||
|
|
||||||
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
@State private var isPresentingSystemShare = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
NavigationStack {
|
||||||
|
List {
|
||||||
|
if WeChatShareService.isWeChatAvailable {
|
||||||
|
shareButton("微信好友", systemImage: "message.fill") {
|
||||||
|
share(scene: .session)
|
||||||
|
}
|
||||||
|
shareButton("朋友圈", systemImage: "person.2.fill") {
|
||||||
|
share(scene: .timeline)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shareButton("更多分享", systemImage: "square.and.arrow.up") {
|
||||||
|
isPresentingSystemShare = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.navigationTitle("分享")
|
||||||
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItem(placement: .cancellationAction) {
|
||||||
|
Button("取消") { dismiss() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.sheet(isPresented: $isPresentingSystemShare) {
|
||||||
|
let text = shareText
|
||||||
|
ActivityShareView(activityItems: [text]) {
|
||||||
|
onResult("已打开系统分享")
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var shareText: String {
|
||||||
|
let trimmedURL = url.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
guard !trimmedURL.isEmpty else { return title }
|
||||||
|
return "\(title)\n\(trimmedURL)"
|
||||||
|
}
|
||||||
|
|
||||||
|
private func shareButton(_ label: String, systemImage: String, action: @escaping () -> Void) -> some View {
|
||||||
|
Button(action: action) {
|
||||||
|
Label(label, systemImage: systemImage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func share(scene: WeChatShareScene) {
|
||||||
|
let payload = WeChatWebPageSharePayload(
|
||||||
|
title: title,
|
||||||
|
description: description,
|
||||||
|
url: url
|
||||||
|
)
|
||||||
|
let thumb = thumbImage ?? WeChatShareService.defaultThumbImage()
|
||||||
|
WeChatShareService.shareWebPage(payload, scene: scene, thumbImage: thumb) { result in
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
|
onResult("已分享到\(scene.title)")
|
||||||
|
case .cancelled:
|
||||||
|
onResult("已取消分享")
|
||||||
|
case .notInstalled:
|
||||||
|
isPresentingSystemShare = true
|
||||||
|
case .unsupported:
|
||||||
|
onResult("当前微信版本不支持分享")
|
||||||
|
case .invalidPayload(let message):
|
||||||
|
onResult(message)
|
||||||
|
case .sendFailed, .unknown:
|
||||||
|
onResult("分享失败,请稍后重试")
|
||||||
|
}
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 系统分享面板封装。
|
||||||
|
private struct ActivityShareView: UIViewControllerRepresentable {
|
||||||
|
let activityItems: [Any]
|
||||||
|
let onComplete: () -> Void
|
||||||
|
|
||||||
|
func makeUIViewController(context: Context) -> UIActivityViewController {
|
||||||
|
let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
|
||||||
|
controller.completionWithItemsHandler = { _, _, _, _ in
|
||||||
|
onComplete()
|
||||||
|
}
|
||||||
|
return controller
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {}
|
||||||
|
}
|
||||||
47
suixinkan/Core/WeChat/WeChatThumbImageProcessor.swift
Normal file
47
suixinkan/Core/WeChat/WeChatThumbImageProcessor.swift
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// WeChatThumbImageProcessor.swift
|
||||||
|
// suixinkan
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
/// 微信分享缩略图处理器,将图片压缩到微信限制(32KB)以内。
|
||||||
|
enum WeChatThumbImageProcessor {
|
||||||
|
/// 微信缩略图最大字节数。
|
||||||
|
static let maxThumbBytes = 32 * 1024
|
||||||
|
|
||||||
|
/// 将图片压缩为符合微信要求的缩略图数据。
|
||||||
|
static func makeThumbData(from image: UIImage, maxBytes: Int = maxThumbBytes) -> Data? {
|
||||||
|
guard maxBytes > 0 else { return nil }
|
||||||
|
|
||||||
|
let resized = resize(image, maxPixel: 120)
|
||||||
|
var quality: CGFloat = 0.8
|
||||||
|
var data = resized.jpegData(compressionQuality: quality)
|
||||||
|
|
||||||
|
while let current = data, current.count > maxBytes, quality > 0.1 {
|
||||||
|
quality -= 0.1
|
||||||
|
data = resized.jpegData(compressionQuality: quality)
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let result = data, result.count <= maxBytes else { return nil }
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 等比缩放图片,使最长边不超过指定像素。
|
||||||
|
static func resize(_ image: UIImage, maxPixel: CGFloat) -> UIImage {
|
||||||
|
let size = image.size
|
||||||
|
guard size.width > 0, size.height > 0 else { return image }
|
||||||
|
|
||||||
|
let maxSide = max(size.width, size.height)
|
||||||
|
guard maxSide > maxPixel else { return image }
|
||||||
|
|
||||||
|
let scale = maxPixel / maxSide
|
||||||
|
let targetSize = CGSize(width: size.width * scale, height: size.height * scale)
|
||||||
|
let format = UIGraphicsImageRendererFormat.default()
|
||||||
|
format.scale = 1
|
||||||
|
let renderer = UIGraphicsImageRenderer(size: targetSize, format: format)
|
||||||
|
return renderer.image { _ in
|
||||||
|
image.draw(in: CGRect(origin: .zero, size: targetSize))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,6 +12,8 @@ Invite 模块负责首页 `registration_invitation`、`photographer_invite` 和
|
|||||||
|
|
||||||
复制邀请链接时只由 View 层写入剪贴板,ViewModel 不关心系统剪贴板状态。
|
复制邀请链接时只由 View 层写入剪贴板,ViewModel 不关心系统剪贴板状态。
|
||||||
|
|
||||||
|
点击「分享」弹出 `WeChatShareSheet`,支持分享到微信好友、朋友圈;未安装微信时走系统分享兜底。分享网页使用 `WeChatShareService.shareWebPage`,缩略图优先使用邀请二维码。
|
||||||
|
|
||||||
## 邀请记录
|
## 邀请记录
|
||||||
|
|
||||||
`InviteRecordViewModel` 提供“邀请记录 / 奖励记录”分段:
|
`InviteRecordViewModel` 提供“邀请记录 / 奖励记录”分段:
|
||||||
|
|||||||
@ -13,6 +13,7 @@ struct PhotographerInviteView: View {
|
|||||||
@EnvironmentObject private var toastCenter: ToastCenter
|
@EnvironmentObject private var toastCenter: ToastCenter
|
||||||
@Environment(\.globalLoading) private var globalLoading
|
@Environment(\.globalLoading) private var globalLoading
|
||||||
@StateObject private var viewModel = PhotographerInviteViewModel()
|
@StateObject private var viewModel = PhotographerInviteViewModel()
|
||||||
|
@State private var isPresentingShareSheet = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
@ -37,6 +38,17 @@ struct PhotographerInviteView: View {
|
|||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
.task { await reload(showLoading: true) }
|
.task { await reload(showLoading: true) }
|
||||||
.refreshable { await reload(showLoading: false) }
|
.refreshable { await reload(showLoading: false) }
|
||||||
|
.sheet(isPresented: $isPresentingShareSheet) {
|
||||||
|
WeChatShareSheet(
|
||||||
|
title: "邀请你加入随心瞰商家版",
|
||||||
|
description: viewModel.inviteCode.isEmpty ? "摄影师邀请" : "邀请码:\(viewModel.inviteCode)",
|
||||||
|
url: viewModel.inviteUrl,
|
||||||
|
thumbImage: viewModel.qrImage
|
||||||
|
) { message in
|
||||||
|
toastCenter.show(message)
|
||||||
|
}
|
||||||
|
.presentationDetents([.medium])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var inviteCard: some View {
|
private var inviteCard: some View {
|
||||||
@ -77,8 +89,11 @@ struct PhotographerInviteView: View {
|
|||||||
.frame(height: 44)
|
.frame(height: 44)
|
||||||
}
|
}
|
||||||
Button {
|
Button {
|
||||||
viewModel.copyInviteUrl()
|
guard !viewModel.inviteUrl.isEmpty else {
|
||||||
toastCenter.show("链接已复制,可粘贴分享")
|
toastCenter.show("邀请链接加载中,请稍后重试")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isPresentingShareSheet = true
|
||||||
} label: {
|
} label: {
|
||||||
Label("分享", systemImage: "square.and.arrow.up")
|
Label("分享", systemImage: "square.and.arrow.up")
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
|
|||||||
@ -20,6 +20,25 @@
|
|||||||
<string>$(MARKETING_VERSION)</string>
|
<string>$(MARKETING_VERSION)</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||||
|
<key>CFBundleURLTypes</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleTypeRole</key>
|
||||||
|
<string>Editor</string>
|
||||||
|
<key>CFBundleURLName</key>
|
||||||
|
<string>weixin</string>
|
||||||
|
<key>CFBundleURLSchemes</key>
|
||||||
|
<array>
|
||||||
|
<string>wxdd80ec12c4fee322</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>LSApplicationQueriesSchemes</key>
|
||||||
|
<array>
|
||||||
|
<string>weixin</string>
|
||||||
|
<string>weixinULAPI</string>
|
||||||
|
<string>weixinURLParamsAPI</string>
|
||||||
|
</array>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>NSCameraUsageDescription</key>
|
<key>NSCameraUsageDescription</key>
|
||||||
|
|||||||
@ -4,5 +4,9 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>aps-environment</key>
|
<key>aps-environment</key>
|
||||||
<string>development</string>
|
<string>development</string>
|
||||||
|
<key>com.apple.developer.associated-domains</key>
|
||||||
|
<array>
|
||||||
|
<string>applinks:www.zhifly.cn</string>
|
||||||
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
68
suixinkanTests/WeChatShareServiceTests.swift
Normal file
68
suixinkanTests/WeChatShareServiceTests.swift
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
//
|
||||||
|
// WeChatShareServiceTests.swift
|
||||||
|
// suixinkanTests
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import XCTest
|
||||||
|
@testable import suixinkan
|
||||||
|
|
||||||
|
final class WeChatShareServiceTests: XCTestCase {
|
||||||
|
func testUniversalLinkMustEndWithSlash() {
|
||||||
|
XCTAssertTrue(WeChatConfig.validateUniversalLink(WeChatConfig.universalLink))
|
||||||
|
XCTAssertFalse(WeChatConfig.validateUniversalLink("https://www.zhifly.cn/suixinkan"))
|
||||||
|
XCTAssertFalse(WeChatConfig.validateUniversalLink("http://www.zhifly.cn/suixinkan/"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testShareSceneMapsToWXValues() {
|
||||||
|
XCTAssertEqual(WeChatShareScene.session.wxSceneValue, 0)
|
||||||
|
XCTAssertEqual(WeChatShareScene.timeline.wxSceneValue, 1)
|
||||||
|
XCTAssertEqual(WeChatShareScene.favorite.wxSceneValue, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testShareResultFromWXErrorCode() {
|
||||||
|
XCTAssertEqual(WeChatShareResult.fromWXErrorCode(0), .success)
|
||||||
|
XCTAssertEqual(WeChatShareResult.fromWXErrorCode(-2), .cancelled)
|
||||||
|
XCTAssertEqual(WeChatShareResult.fromWXErrorCode(99), .unknown(99))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testThumbImageCompressionStaysWithinLimit() throws {
|
||||||
|
let size = CGSize(width: 512, height: 512)
|
||||||
|
let format = UIGraphicsImageRendererFormat.default()
|
||||||
|
format.scale = 1
|
||||||
|
let renderer = UIGraphicsImageRenderer(size: size, format: format)
|
||||||
|
let image = renderer.image { context in
|
||||||
|
UIColor.systemBlue.setFill()
|
||||||
|
context.fill(CGRect(origin: .zero, size: size))
|
||||||
|
}
|
||||||
|
|
||||||
|
let thumbData = try XCTUnwrap(WeChatThumbImageProcessor.makeThumbData(from: image))
|
||||||
|
XCTAssertLessThanOrEqual(thumbData.count, WeChatThumbImageProcessor.maxThumbBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testThumbImageResizeReducesLargeImage() {
|
||||||
|
let size = CGSize(width: 800, height: 600)
|
||||||
|
let format = UIGraphicsImageRendererFormat.default()
|
||||||
|
format.scale = 1
|
||||||
|
let renderer = UIGraphicsImageRenderer(size: size, format: format)
|
||||||
|
let image = renderer.image { _ in }
|
||||||
|
|
||||||
|
let resized = WeChatThumbImageProcessor.resize(image, maxPixel: 120)
|
||||||
|
XCTAssertLessThanOrEqual(max(resized.size.width, resized.size.height), 120)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testWebPagePayloadValidationRequiresNonEmptyFields() async {
|
||||||
|
await MainActor.run {
|
||||||
|
let expectation = expectation(description: "invalid title")
|
||||||
|
WeChatShareService.shareWebPage(
|
||||||
|
WeChatWebPageSharePayload(title: " ", description: "desc", url: "https://example.com"),
|
||||||
|
scene: .session
|
||||||
|
) { result in
|
||||||
|
if case .invalidPayload = result {
|
||||||
|
expectation.fulfill()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wait(for: [expectation], timeout: 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user