diff --git a/.github/workflows/release-android-apk.yml b/.github/workflows/release-android-apk.yml
index f576d008..6b486a86 100644
--- a/.github/workflows/release-android-apk.yml
+++ b/.github/workflows/release-android-apk.yml
@@ -56,7 +56,7 @@ jobs:
#创建签名需要的信息
- name: Create secrets.properties
run: |
- echo "storeFile=sign_keystore.jks" > key.properties
+ echo "storeFile=sign_keystore.jks" >> key.properties
echo "storePassword=${{ secrets.APK_SIGN_KEYSTORE_PASSWORD }}" >> key.properties
echo "keyAlias=${{ secrets.APK_SIGN_ALIAS }}" >> key.properties
echo "keyPassword=${{ secrets.APK_SIGN_PASSWORD }}" >> key.properties
diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts
index 6c1aeaab..db60fd60 100644
--- a/androidApp/build.gradle.kts
+++ b/androidApp/build.gradle.kts
@@ -67,8 +67,8 @@ android {
applicationId = "com.smjcco.wxpusher"
minSdk = libs.versions.android.minSdk.get().toInt()
targetSdk = libs.versions.android.targetSdk.get().toInt()
- versionCode = 10751
- versionName = "1.7.51"
+ versionCode = 10811
+ versionName = "1.8.11"
//指定产物名称
setProperty("archivesBaseName", "wxpusher-app-v$versionName")
diff --git a/androidApp/src/androidMain/AndroidManifest.xml b/androidApp/src/androidMain/AndroidManifest.xml
index 8cdbd479..365cf8f6 100644
--- a/androidApp/src/androidMain/AndroidManifest.xml
+++ b/androidApp/src/androidMain/AndroidManifest.xml
@@ -21,6 +21,7 @@
+
= emptyList()
+ //已应用的 tab 配置快照,用于返回主界面时 diff,仅变化才重建
+ private var appliedTabConfig: WxpTabConfig? = null
+ private var tabMediator: TabLayoutMediator? = null
+ //KV 变更监听 id(保存即广播机制)
+ private var kvListenerId: Int = -1
+
private var permissionRequester: PermissionRequester? = null
companion object {
@@ -67,8 +80,11 @@ class WxpMainActivity : WxpBaseActivity(), CurrentTabProvider {
return
}
title = "消息列表"
- // 设置ViewPager和TabLayout
- setupViewPager()
+ // 设置ViewPager和TabLayout(按 tab 显隐配置动态构建)
+ setupTabListeners()
+ rebuildTabs(WxpTabConfigStore.read())
+ // 注册 KV 变更监听(保存即广播),tab 配置变化即重建
+ setupKvListener()
//检查是否有权限
setUpPermissionRequester()
@@ -165,38 +181,41 @@ class WxpMainActivity : WxpBaseActivity(), CurrentTabProvider {
}
- private fun setupViewPager() {
- pagerAdapter = MainPagerAdapter(this)
- viewPager.adapter = pagerAdapter
- viewPager.isUserInputEnabled = false
-
- // 连接TabLayout和ViewPager2
- TabLayoutMediator(tabLayout, viewPager) { tab, position ->
- when (position) {
- 0 -> {
- tab.text = "消息列表"
- tab.setIcon(R.drawable.ic_paperplane)
- }
+ //根据配置构建有序 tab 列表:消息列表(必) → 消息市场(可配) → 扩展功能(可配) → 我的(必)
+ private fun buildTabs(config: WxpTabConfig): List {
+ val list = mutableListOf(MainTab.MESSAGE_LIST)
+ if (config.market) {
+ list.add(MainTab.MARKET)
+ }
+ if (config.extFunc) {
+ list.add(MainTab.EXT_FUNC)
+ }
+ list.add(MainTab.PROFILE)
+ return list
+ }
- 1 -> {
- tab.text = "消息市场"
- tab.setIcon(R.drawable.ic_cloud)
- }
+ //tab 的标题与图标
+ private fun tabTitle(tab: MainTab): String = when (tab) {
+ MainTab.MESSAGE_LIST -> "消息列表"
+ MainTab.MARKET -> "消息市场"
+ MainTab.EXT_FUNC -> "扩展功能"
+ MainTab.PROFILE -> "我的"
+ }
- 2 -> {
- tab.text = "我的"
- tab.setIcon(R.drawable.ic_person)
- }
- }
- }.attach()
+ private fun tabIcon(tab: MainTab): Int = when (tab) {
+ MainTab.MESSAGE_LIST -> R.drawable.ic_paperplane
+ MainTab.MARKET -> R.drawable.ic_cloud
+ MainTab.EXT_FUNC -> R.drawable.ic_ext_func
+ MainTab.PROFILE -> R.drawable.ic_person
+ }
- // 监听Tab切换,更新Toolbar标题和菜单
- tabLayout.addOnTabSelectedListener(object :
- TabLayout.OnTabSelectedListener {
+ //监听只注册一次(tab 重建时不重复注册)
+ private fun setupTabListeners() {
+ viewPager.isUserInputEnabled = false
+ tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
tab?.let {
title = it.text
- // 更新菜单
updateMenuForCurrentTab(tab.position)
}
}
@@ -210,20 +229,34 @@ class WxpMainActivity : WxpBaseActivity(), CurrentTabProvider {
}
})
- // 监听ViewPager页面切换(处理手势滑动切换)
viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
- // 延迟更新菜单,确保Fragment已经加载完成
viewPager.post {
updateMenuForCurrentTab(position)
}
}
})
+ }
- // 延迟初始化第一个tab的菜单,确保Fragment已创建
+ //(重新)按配置构建 tab 列表与 ViewPager
+ private fun rebuildTabs(config: WxpTabConfig) {
+ appliedTabConfig = config
+ tabs = buildTabs(config)
+ pagerAdapter = MainPagerAdapter(this)
+ viewPager.adapter = pagerAdapter
+
+ tabMediator?.detach()
+ tabMediator = TabLayoutMediator(tabLayout, viewPager) { tab, position ->
+ val mainTab = tabs[position]
+ tab.text = tabTitle(mainTab)
+ tab.setIcon(tabIcon(mainTab))
+ }
+ tabMediator?.attach()
+
+ // 延迟初始化当前tab的菜单,确保Fragment已创建
viewPager.post {
- updateMenuForCurrentTab(0)
+ updateMenuForCurrentTab(viewPager.currentItem)
}
}
@@ -277,11 +310,45 @@ class WxpMainActivity : WxpBaseActivity(), CurrentTabProvider {
WxpVersionCheckManager.onAppForeground()
}
+ //注册 KV 变更监听(保存即广播):tab_config 变化即重建,未变不动。
+ //回调已由共享层 runAtMainSuspend 切到主线程。
+ private fun setupKvListener() {
+ kvListenerId = WxpSaveService.addListener { key ->
+ if (key == WxpTabConfigStore.TAB_CONFIG_KEY) {
+ refreshTabsIfConfigChanged()
+ }
+ }
+ }
+
+ private fun refreshTabsIfConfigChanged() {
+ //未完成初始化(如未登录直接 finish)时跳过
+ val applied = appliedTabConfig ?: return
+ val latest = WxpTabConfigStore.read()
+ if (applied == latest) {
+ return
+ }
+ val currentTab = tabs.getOrNull(viewPager.currentItem)
+ rebuildTabs(latest)
+ //恢复到原来所在 tab;若该 tab 已被隐藏,回落到消息列表
+ val targetIndex = currentTab?.let { tabs.indexOf(it) }?.takeIf { it >= 0 } ?: 0
+ viewPager.setCurrentItem(targetIndex, false)
+ title = tabTitle(tabs[targetIndex])
+ viewPager.post { updateMenuForCurrentTab(targetIndex) }
+ }
+
override fun onPause() {
super.onPause()
WxpLogUtils.flush()
}
+ override fun onDestroy() {
+ if (kvListenerId >= 0) {
+ WxpSaveService.removeListener(kvListenerId)
+ kvListenerId = -1
+ }
+ super.onDestroy()
+ }
+
/**
* ViewPager2适配器
* 让FragmentStateAdapter来管理Fragment的创建和状态保存/恢复
@@ -291,14 +358,14 @@ class WxpMainActivity : WxpBaseActivity(), CurrentTabProvider {
) :
FragmentStateAdapter(activity) {
- override fun getItemCount(): Int = 3
+ override fun getItemCount(): Int = tabs.size
override fun createFragment(position: Int): Fragment {
- return when (position) {
- 0 -> MessageListFragment()
- 1 -> WxpProviderListFragment()
- 2 -> ProfileFragment()
- else -> throw IllegalArgumentException("Invalid position: $position")
+ return when (tabs[position]) {
+ MainTab.MESSAGE_LIST -> MessageListFragment()
+ MainTab.MARKET -> WxpProviderListFragment()
+ MainTab.EXT_FUNC -> WxpExtFuncFragment()
+ MainTab.PROFILE -> ProfileFragment()
}
}
diff --git a/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/main/fragment/ProfileFragment.kt b/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/main/fragment/ProfileFragment.kt
index 1d9a4bf8..7d7ba4f4 100644
--- a/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/main/fragment/ProfileFragment.kt
+++ b/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/main/fragment/ProfileFragment.kt
@@ -221,6 +221,16 @@ class ProfileFragment : WxpBaseFragment() {
ProfileSection(
title = "通用",
items = listOf(
+ ProfileItem(
+ title = "底部标签设置",
+ subtitle = "自定义底部导航标签的显示",
+ hasArrow = true
+ ) {
+ WxpJumpPageUtils.jumpToWebUrl(
+ "${WxpConfig.appFeUrl}/app/#/tab-setting",
+ activity
+ )
+ },
ProfileItem(
title = "反馈建议",
subtitle = "欢迎你指导我们进步",
diff --git a/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/main/fragment/WxpExtFuncFragment.kt b/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/main/fragment/WxpExtFuncFragment.kt
new file mode 100644
index 00000000..df099e10
--- /dev/null
+++ b/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/main/fragment/WxpExtFuncFragment.kt
@@ -0,0 +1,39 @@
+package com.smjcco.wxpusher.page.main.fragment
+
+import android.os.Bundle
+import android.view.View
+import android.widget.ImageButton
+import com.smjcco.wxpusher.R
+import com.smjcco.wxpusher.WxpConfig
+import com.smjcco.wxpusher.page.web.WxpWebViewFragment
+
+/**
+ * 扩展功能 tab —— 原生 WebView 容器加载 app-fe 的九宫格入口页。
+ * 与消息市场 tab(WxpProviderListFragment)结构一致:隐藏返回按钮、关闭按钮改为回到本页。
+ */
+class WxpExtFuncFragment : WxpWebViewFragment() {
+
+ private val pageUrl: String
+ get() = "${WxpConfig.appFeUrl}/app/#/ext-func"
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ loadWebContent(pageUrl)
+ }
+
+ override fun setupUI(view: View) {
+ super.setupUI(view)
+ //默认隐藏底部操作栏:布局默认 VISIBLE,避免打开瞬间闪一下再隐藏(UI 线程调用会同步生效)
+ setBottomBarVisibleOverride(false)
+ //隐藏左上角的返回按钮
+ getActivityHost()?.supportActionBar?.setDisplayHomeAsUpEnabled(false)
+ //覆盖webview默认的关闭按钮,改成home按钮
+ val closeButton: ImageButton = view.findViewById(R.id.closeButton)
+ closeButton.setImageResource(R.drawable.ic_home)
+ }
+
+ //覆盖关闭按钮为回到扩展功能首页
+ override fun onCloseButtonClicked() {
+ loadWebContent(pageUrl)
+ }
+}
diff --git a/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/main/fragment/WxpProviderListFragment.kt b/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/main/fragment/WxpProviderListFragment.kt
index 5a5d7de5..f0f7c440 100644
--- a/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/main/fragment/WxpProviderListFragment.kt
+++ b/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/main/fragment/WxpProviderListFragment.kt
@@ -20,6 +20,8 @@ class WxpProviderListFragment : WxpWebViewFragment(), IWxpProviderListView {
override fun setupUI(view: View) {
super.setupUI(view)
+ //默认隐藏底部操作栏:布局默认 VISIBLE,避免打开瞬间闪一下再隐藏(UI 线程调用会同步生效)
+ setBottomBarVisibleOverride(false)
//隐藏左上角的返回按钮
getActivityHost()?.supportActionBar?.setDisplayHomeAsUpEnabled(false)
//覆盖webview默认的关闭按钮,改成home按钮
diff --git a/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/web/bridge/WxpWebBridgeManager.kt b/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/web/bridge/WxpWebBridgeManager.kt
index e4ca3bcd..d3caf0d6 100644
--- a/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/web/bridge/WxpWebBridgeManager.kt
+++ b/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/web/bridge/WxpWebBridgeManager.kt
@@ -2,10 +2,12 @@ package com.smjcco.wxpusher.page.web.bridge
import com.smjcco.wxpusher.base.common.WxpLogUtils
import com.smjcco.wxpusher.page.web.bridge.handlers.CloseWebPageBridgeHandler
+import com.smjcco.wxpusher.page.web.bridge.handlers.GetByKeyBridgeHandler
import com.smjcco.wxpusher.page.web.bridge.handlers.GetLoginInfoBridgeHandler
import com.smjcco.wxpusher.page.web.bridge.handlers.OpenSystemBrowserBridgeHandler
import com.smjcco.wxpusher.page.web.bridge.handlers.OpenUrlBridgeHandler
import com.smjcco.wxpusher.page.web.bridge.handlers.PayRequestBridgeHandler
+import com.smjcco.wxpusher.page.web.bridge.handlers.SetKeyValueBridgeHandler
import com.smjcco.wxpusher.page.web.bridge.handlers.SetWebBottomBarBridgeHandler
import com.smjcco.wxpusher.page.web.bridge.handlers.SetWebOptionMenuBridgeHandler
import com.smjcco.wxpusher.page.web.bridge.handlers.ShowToastBridgeHandler
@@ -40,6 +42,8 @@ class WxpWebBridgeManager(
registerHandler("setWebOptionMenu", requiresWhitelist = true, handler = SetWebOptionMenuBridgeHandler)
registerHandler("setWebBottomBar", requiresWhitelist = true, handler = SetWebBottomBarBridgeHandler)
registerHandler("closeWebPage", requiresWhitelist = true, handler = CloseWebPageBridgeHandler)
+ registerHandler("getByKey", requiresWhitelist = true, handler = GetByKeyBridgeHandler)
+ registerHandler("setKeyValue", requiresWhitelist = true, handler = SetKeyValueBridgeHandler)
}
fun onMessage(messageJson: String) {
diff --git a/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/web/bridge/handlers/GetByKeyBridgeHandler.kt b/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/web/bridge/handlers/GetByKeyBridgeHandler.kt
new file mode 100644
index 00000000..f364a561
--- /dev/null
+++ b/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/web/bridge/handlers/GetByKeyBridgeHandler.kt
@@ -0,0 +1,31 @@
+package com.smjcco.wxpusher.page.web.bridge.handlers
+
+import com.smjcco.wxpusher.base.common.WxpSaveService
+import com.smjcco.wxpusher.page.web.bridge.BridgeActionHandler
+import com.smjcco.wxpusher.page.web.bridge.BridgeContext
+import com.smjcco.wxpusher.page.web.bridge.BridgeRequest
+import com.smjcco.wxpusher.page.web.bridge.WxpBridgeEmitter
+
+/**
+ * 通用存储读取。直接读 WxpSaveService(原生与 H5 同一 key 空间,无前缀),空值视为不存在返回空 data。
+ */
+object GetByKeyBridgeHandler : BridgeActionHandler {
+ override fun handle(request: BridgeRequest, context: BridgeContext, emitter: WxpBridgeEmitter) {
+ val key = request.data["key"] as? String
+ if (key.isNullOrBlank()) {
+ emitter.sendBridgeCallback(
+ callbackId = request.callbackId,
+ success = false,
+ error = "key is empty"
+ )
+ return
+ }
+ val value = WxpSaveService.get(key, "")
+ val data: Map = if (value.isEmpty()) emptyMap() else mapOf("value" to value)
+ emitter.sendBridgeCallback(
+ callbackId = request.callbackId,
+ success = true,
+ data = data
+ )
+ }
+}
diff --git a/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/web/bridge/handlers/SetKeyValueBridgeHandler.kt b/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/web/bridge/handlers/SetKeyValueBridgeHandler.kt
new file mode 100644
index 00000000..47eaf6c2
--- /dev/null
+++ b/androidApp/src/androidMain/kotlin/com/smjcco/wxpusher/page/web/bridge/handlers/SetKeyValueBridgeHandler.kt
@@ -0,0 +1,31 @@
+package com.smjcco.wxpusher.page.web.bridge.handlers
+
+import com.smjcco.wxpusher.base.common.WxpSaveService
+import com.smjcco.wxpusher.page.web.bridge.BridgeActionHandler
+import com.smjcco.wxpusher.page.web.bridge.BridgeContext
+import com.smjcco.wxpusher.page.web.bridge.BridgeRequest
+import com.smjcco.wxpusher.page.web.bridge.WxpBridgeEmitter
+
+/**
+ * 通用存储写入。直接写 WxpSaveService(原生与 H5 同一 key 空间,无前缀)。
+ * 安全由桥的 requiresWhitelist 保证(仅白名单域可调)。
+ */
+object SetKeyValueBridgeHandler : BridgeActionHandler {
+ override fun handle(request: BridgeRequest, context: BridgeContext, emitter: WxpBridgeEmitter) {
+ val key = request.data["key"] as? String
+ if (key.isNullOrBlank()) {
+ emitter.sendBridgeCallback(
+ callbackId = request.callbackId,
+ success = false,
+ error = "key is empty"
+ )
+ return
+ }
+ val value = request.data["value"] as? String ?: ""
+ WxpSaveService.set(key, value)
+ emitter.sendBridgeCallback(
+ callbackId = request.callbackId,
+ success = true
+ )
+ }
+}
diff --git a/androidApp/src/androidMain/res/drawable/ic_ext_func.xml b/androidApp/src/androidMain/res/drawable/ic_ext_func.xml
new file mode 100644
index 00000000..6f364c06
--- /dev/null
+++ b/androidApp/src/androidMain/res/drawable/ic_ext_func.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/iosApp/Podfile b/iosApp/Podfile
index e0bf3bea..162c0ddd 100644
--- a/iosApp/Podfile
+++ b/iosApp/Podfile
@@ -14,7 +14,7 @@ target 'WxPusher-iOS' do
project "wxpusher/wxpusher.xcodeproj"
pod 'Toaster', '2.3.0'
pod 'MJRefresh', '3.7.9'
- pod 'WechatOpenSDK-XCFramework', '2.0.5'
+ pod 'WechatOpenSDK-XCFramework', :path => 'Vendor/WechatOpenSDK-XCFramework/2.0.5'
# 穿山甲(CSJ/Pangle)国内广告 SDK,用于消息详情页底部 Banner 广告
pod 'Ads-CN', '7.6.0.4'
# 穿山甲测量/预览工具(开发测试用)。调用代码全部包在 #if DEBUG 中,Release 不会触达。
diff --git a/iosApp/Podfile.lock b/iosApp/Podfile.lock
index 5739de16..52d46026 100644
--- a/iosApp/Podfile.lock
+++ b/iosApp/Podfile.lock
@@ -51,7 +51,7 @@ DEPENDENCIES:
- MJRefresh (= 3.7.9)
- shared (from `../shared`)
- Toaster (= 2.3.0)
- - WechatOpenSDK-XCFramework (= 2.0.5)
+ - WechatOpenSDK-XCFramework (from `Vendor/WechatOpenSDK-XCFramework/2.0.5`)
SPEC REPOS:
trunk:
@@ -59,11 +59,12 @@ SPEC REPOS:
- BUTTSDKFramework
- MJRefresh
- Toaster
- - WechatOpenSDK-XCFramework
EXTERNAL SOURCES:
shared:
:path: "../shared"
+ WechatOpenSDK-XCFramework:
+ :path: Vendor/WechatOpenSDK-XCFramework/2.0.5
SPEC CHECKSUMS:
Ads-CN: 6bfc5a80f72a8fa723bb8d0941c84bcc03a5c088
@@ -71,8 +72,8 @@ SPEC CHECKSUMS:
MJRefresh: ff9e531227924c84ce459338414550a05d2aea78
shared: f70abb4412b47a88dd39768078ea98270a675a5a
Toaster: c3473963c78e8cabbf6ea6f11ad0fdaae6f54987
- WechatOpenSDK-XCFramework: b072030c9eeee91dfff1856a7846f70f7b9a88ed
+ WechatOpenSDK-XCFramework: 5b8db436b6541d4758d42571d5ac055d609e6fe2
-PODFILE CHECKSUM: 929af93f1ffdf631a5ab2669227b6f219e7a9fec
+PODFILE CHECKSUM: b5b439da9dc39a4c380e925b36b88eada66aa78e
COCOAPODS: 1.15.2
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/README.md b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/README.md
new file mode 100644
index 00000000..79229ade
--- /dev/null
+++ b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/README.md
@@ -0,0 +1,12 @@
+# WechatOpenSDK-XCFramework 2.0.5
+
+This directory contains the official Wechat OpenSDK XCFramework used by the
+iOS application. It is vendored to keep local and GitHub Actions builds from
+depending on the availability of the upstream download CDN.
+
+- Version: `2.0.5`
+- Official archive: `https://dldir1.qq.com/WechatWebDev/opensdk/XCFramework/OpenSDK2.0.5.zip`
+- Archive SHA-256: `00e7c16d76de05cae3f96fd051b928147a17e2047169a5a6e10631a293f0dd14`
+
+When upgrading, create a new version directory instead of replacing this one,
+then update the path in `iosApp/Podfile`.
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK-XCFramework.podspec b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK-XCFramework.podspec
new file mode 100644
index 00000000..4a2e4c26
--- /dev/null
+++ b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK-XCFramework.podspec
@@ -0,0 +1,24 @@
+Pod::Spec.new do |spec|
+ spec.name = 'WechatOpenSDK-XCFramework'
+ spec.version = '2.0.5'
+ spec.summary = 'Wechat OpenSDK XCFramework vendored for reproducible builds.'
+ spec.description = <<-DESC
+ Official Wechat OpenSDK XCFramework vendored in the repository so CI builds
+ do not depend on the availability of the upstream download CDN.
+ DESC
+ spec.homepage = 'https://open.weixin.qq.com/'
+ spec.license = {
+ :type => 'Copyright',
+ :text => 'Copyright 2020 tencent.com. All rights reserved.'
+ }
+ spec.author = { 'tencent' => 'weixin-open@qq.com' }
+ spec.source = {
+ :http => 'https://dldir1.qq.com/WechatWebDev/opensdk/XCFramework/OpenSDK2.0.5.zip'
+ }
+ spec.platform = :ios, '12.0'
+ spec.requires_arc = false
+ spec.static_framework = true
+ spec.vendored_frameworks = 'WechatOpenSDK.xcframework'
+ spec.frameworks = 'Security', 'UIKit', 'CoreGraphics', 'WebKit'
+ spec.libraries = 'z', 'sqlite3.0', 'c++'
+end
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/Info.plist b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/Info.plist
new file mode 100644
index 00000000..c6a49d50
--- /dev/null
+++ b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/Info.plist
@@ -0,0 +1,44 @@
+
+
+
+
+ AvailableLibraries
+
+
+ BinaryPath
+ WechatOpenSDK.framework/WechatOpenSDK
+ LibraryIdentifier
+ ios-arm64_x86_64-simulator
+ LibraryPath
+ WechatOpenSDK.framework
+ SupportedArchitectures
+
+ arm64
+ x86_64
+
+ SupportedPlatform
+ ios
+ SupportedPlatformVariant
+ simulator
+
+
+ BinaryPath
+ WechatOpenSDK.framework/WechatOpenSDK
+ LibraryIdentifier
+ ios-arm64
+ LibraryPath
+ WechatOpenSDK.framework
+ SupportedArchitectures
+
+ arm64
+
+ SupportedPlatform
+ ios
+
+
+ CFBundlePackageType
+ XFWK
+ XCFrameworkFormatVersion
+ 1.0
+
+
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/PrivacyInfo.xcprivacy b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/PrivacyInfo.xcprivacy
new file mode 100644
index 00000000..79bc9e28
--- /dev/null
+++ b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/PrivacyInfo.xcprivacy
@@ -0,0 +1,17 @@
+
+
+
+
+ NSPrivacyAccessedAPITypes
+
+
+ NSPrivacyAccessedAPIType
+ NSPrivacyAccessedAPICategoryUserDefaults
+ NSPrivacyAccessedAPITypeReasons
+
+ CA92.1
+
+
+
+
+
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/README.txt b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/README.txt
new file mode 100644
index 00000000..3f2aab01
--- /dev/null
+++ b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/README.txt
@@ -0,0 +1,167 @@
+重要!
+SDK2.0.5
+1. 支持模块化集成:XCFramework 头文件引用改为标准化格式 #import ,解决路径冲突并支持 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”里增加如下代码:
+LSApplicationQueriesSchemes
+
+weixin
+
+NSAppTransportSecurity
+
+NSAllowsArbitraryLoads
+
+
+2、开发者需要在工程中链接上 CoreTelephony.framework
+3、解决bitcode编译不过问题
+
+SDK1.5
+1、废弃safeSendReq:接口,使用sendReq:即可。
+2、新增+(BOOL) sendAuthReq:(SendAuthReq*) req viewController : (UIViewController*) viewController delegate:(id) delegate;
+支持未安装微信情况下Auth,具体见WXApi.h接口描述
+3、微信开放平台新增了微信模块用户统计功能,便于开发者统计微信功能模块的用户使用和活跃情况。开发者需要在工程中链接上:SystemConfiguration.framework,libz.dylib,libsqlite3.0.dylib。
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Headers/WXApi.h b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Headers/WXApi.h
new file mode 100644
index 00000000..879c5059
--- /dev/null
+++ b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Headers/WXApi.h
@@ -0,0 +1,231 @@
+//
+// WXApi.h
+// 所有Api接口
+//
+// Created by Wechat on 12-2-28.
+// Copyright (c) 2012年 Tencent. All rights reserved.
+//
+
+#import
+#import "WXApiObject.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+
+typedef BOOL(^WXGrantReadPasteBoardPermissionCompletion)(void);
+
+
+#pragma mark - WXApiDelegate
+/*! @brief 接收并处理来自微信终端程序的事件消息
+ *
+ * 接收并处理来自微信终端程序的事件消息,期间微信界面会切换到第三方应用程序。
+ * WXApiDelegate 会在handleOpenURL:delegate:中使用并触发。
+ */
+@protocol WXApiDelegate
+@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
+
+- (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)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)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)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)logDelegate;
+
+/*! @brief 停止打印log,会清理block或者delegate为空,释放block
+ * @param
+ */
++ (void)stopLog;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Headers/WXApiObject.h b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Headers/WXApiObject.h
new file mode 100644
index 00000000..85b64578
--- /dev/null
+++ b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Headers/WXApiObject.h
@@ -0,0 +1,1410 @@
+//
+// MMApiObject.h
+// Api对象,包含所有接口和对象数据定义
+//
+// Created by Wechat on 12-2-28.
+// Copyright (c) 2012年 Tencent. All rights reserved.
+//
+
+#import
+#import
+
+NS_ASSUME_NONNULL_BEGIN
+
+/*! @brief 错误码
+ *
+ */
+enum WXErrCode {
+ WXSuccess = 0, /**< 成功 */
+ WXErrCodeCommon = -1, /**< 普通错误类型 */
+ WXErrCodeUserCancel = -2, /**< 用户点击取消并返回 */
+ WXErrCodeSentFail = -3, /**< 发送失败 */
+ WXErrCodeAuthDeny = -4, /**< 授权失败 */
+ WXErrCodeUnsupport = -5, /**< 微信不支持 */
+};
+
+
+
+/*! @brief 请求发送场景
+ *
+ */
+enum WXScene {
+ WXSceneSession = 0, /**< 聊天界面 */
+ WXSceneTimeline = 1, /**< 朋友圈 */
+ WXSceneFavorite = 2, /**< 收藏 */
+ WXSceneSpecifiedSession = 3, /**< 指定联系人 */
+ WXSceneState = 4, /**< 状态 */
+};
+
+
+enum WXAPISupport {
+ WXAPISupportSession = 0,
+};
+
+
+
+/*! @brief 跳转profile类型
+ *
+ */
+enum WXBizProfileType {
+ WXBizProfileType_Normal = 0, //**< 普通公众号 */
+ WXBizProfileType_Device = 1, //**< 硬件公众号 */
+};
+
+/*! @brief 分享小程序类型
+ *
+ */
+typedef NS_ENUM(NSUInteger, WXMiniProgramType) {
+ WXMiniProgramTypeRelease = 0, //**< 正式版 */
+ WXMiniProgramTypeTest = 1, //**< 开发版 */
+ WXMiniProgramTypePreview = 2, //**< 体验版 */
+};
+
+/*! @brief 跳转mp网页类型
+ *
+ */
+enum WXMPWebviewType {
+ WXMPWebviewType_Ad = 0, /**< 广告网页 **/
+};
+
+/*! @brief log的级别
+ *
+ */
+typedef NS_ENUM(NSInteger,WXLogLevel) {
+ WXLogLevelNormal = 0, // 打印日常的日志
+ WXLogLevelDetail = 1, // 打印详细的日志
+};
+
+
+/*! @brief 打印回调的block
+ *
+ */
+typedef void(^WXLogBolock)(NSString *log);
+
+/*! @brief 微信Universal Link检查函数 (WXApi#checkUniversalLinkReady:),检查步骤枚举值
+ *
+ * WXULCheckStepParams 参数检测
+ * WXULCheckStepSystemVersion 当前系统版本检测
+ * WXULCheckStepWechatVersion 微信客户端版本检测
+ * WXULCheckStepSDKInnerOperation 微信SDK内部操作检测
+ * WXULCheckStepLaunchWechat App拉起微信检测
+ * WXULCheckStepBackToCurrentApp 由微信返回当前App检测
+ * WXULCheckStepFinal 最终结果
+ */
+typedef NS_ENUM(NSInteger, WXULCheckStep)
+{
+ WXULCheckStepParams,
+ WXULCheckStepSystemVersion,
+ WXULCheckStepWechatVersion,
+ WXULCheckStepSDKInnerOperation,
+ WXULCheckStepLaunchWechat,
+ WXULCheckStepBackToCurrentApp,
+ WXULCheckStepFinal,
+};
+
+
+#pragma mark - WXCheckULStepResult
+
+/*! @brief 该类为微信Universal Link检测函数结果类
+*
+*/
+@interface WXCheckULStepResult : NSObject
+
+/** 是否成功 */
+@property(nonatomic, assign) BOOL success;
+/** 当前错误信息 */
+@property(nonatomic, strong) NSString* errorInfo;
+/** 修正建议 */
+@property(nonatomic, strong) NSString* suggestion;
+
+- (instancetype)initWithCheckResult:(BOOL)success errorInfo:(nullable NSString*)errorInfo suggestion:(nullable NSString*)suggestion;
+
+@end
+
+
+/*! @brief 微信Universal Link检查函数 (WXApi#checkUniversalLinkReady:),回调Block
+ *
+ * @param step 当前检测步骤
+ * @param result 检测结果
+ */
+typedef void(^WXCheckULCompletion)(WXULCheckStep step, WXCheckULStepResult* result);
+
+
+#pragma mark - BaseReq
+/*! @brief 该类为微信终端SDK所有请求类的基类
+ *
+ */
+@interface BaseReq : NSObject
+
+/** 请求类型 */
+@property (nonatomic, assign) int type;
+/** 由用户微信号和AppID组成的唯一标识,需要校验微信用户是否换号登录时填写*/
+@property (nonatomic, copy) NSString *openID;
+
+@end
+
+
+
+#pragma mark - BaseResp
+/*! @brief 该类为微信终端SDK所有响应类的基类
+ *
+ */
+@interface BaseResp : NSObject
+/** 错误码 */
+@property (nonatomic, assign) int errCode;
+/** 错误提示字符串 */
+@property (nonatomic, copy) NSString *errStr;
+/** 响应类型 */
+@property (nonatomic, assign) int type;
+
+@end
+
+
+
+#pragma mark - WXMediaMessage
+@class WXMediaMessage;
+
+#ifndef BUILD_WITHOUT_PAY
+
+#pragma mark - PayReq
+/*! @brief 第三方向微信终端发起支付的消息结构体
+ *
+ * 第三方向微信终端发起支付的消息结构体,微信终端处理后会向第三方返回处理结果
+ * @see PayResp
+ */
+@interface PayReq : BaseReq
+
+/** 商家向财付通申请的商家id */
+@property (nonatomic, copy) NSString *partnerId;
+/** 预支付订单 */
+@property (nonatomic, copy) NSString *prepayId;
+/** 随机串,防重发 */
+@property (nonatomic, copy) NSString *nonceStr;
+/** 时间戳,防重发 */
+@property (nonatomic, assign) UInt32 timeStamp;
+/** 商家根据财付通文档填写的数据和签名 */
+@property (nonatomic, copy) NSString *package;
+/** 商家根据微信开放平台文档对数据做的签名 */
+@property (nonatomic, copy) NSString *sign;
+
+@end
+
+
+#pragma mark - PayResp
+/*! @brief 微信终端返回给第三方的关于支付结果的结构体
+ *
+ * 微信终端返回给第三方的关于支付结果的结构体
+ */
+@interface PayResp : BaseResp
+
+/** 财付通返回给商家的信息 */
+@property (nonatomic, copy) NSString *returnKey;
+
+@end
+
+#pragma mark - WXOfflinePay
+/*! @brief 第三方向微信终端发起离线支付
+ *
+ * 第三方向微信终端发起离线支付的消息结构体
+ */
+@interface WXOfflinePayReq : BaseReq
+
+@end
+
+/*! @brief 第三方向微信终端发起离线支付返回
+ *
+ * 第三方向微信终端发起离线支付返回的消息结构体
+ */
+@interface WXOfflinePayResp : BaseResp
+
+@end
+
+
+#pragma mark - WXNontaxPayReq
+@interface WXNontaxPayReq:BaseReq
+
+@property (nonatomic, copy) NSString *urlString;
+
+@end
+
+#pragma mark - WXNontaxPayResp
+@interface WXNontaxPayResp : BaseResp
+
+@property (nonatomic, copy) NSString *wxOrderId;
+
+@end
+
+#pragma mark - WXPayInsuranceReq
+@interface WXPayInsuranceReq : BaseReq
+
+@property (nonatomic, copy) NSString *urlString;
+
+@end
+
+#pragma mark - WXPayInsuranceResp
+@interface WXPayInsuranceResp : BaseResp
+
+@property (nonatomic, copy) NSString *wxOrderId;
+
+@end
+
+
+#pragma mark - WXQRCodePayReq
+@interface WXQRCodePayReq : BaseReq
+/** 码内容
+ * @note 必填,码长度必须大于0且小于10K
+ */
+@property (nonatomic, copy) NSString *codeContent;
+/** 额外信息
+ * @note 长度必须大于0且小于10K
+ */
+@property (nonatomic, copy) NSString *extraMsg;
+
+@end
+
+@interface WXQRCodePayResp : BaseResp
+@end
+
+#endif
+
+
+#pragma mark - SendAuthReq
+/*! @brief 第三方程序向微信终端请求认证的消息结构
+ *
+ * 第三方程序要向微信申请认证,并请求某些权限,需要调用WXApi的sendReq成员函数,
+ * 向微信终端发送一个SendAuthReq消息结构。微信终端处理完后会向第三方程序发送一个处理结果。
+ * @see SendAuthResp
+ */
+@interface SendAuthReq : BaseReq
+/** 第三方程序要向微信申请认证,并请求某些权限,需要调用WXApi的sendReq成员函数,向微信终端发送一个SendAuthReq消息结构。微信终端处理完后会向第三方程序发送一个处理结果。
+ * @see SendAuthResp
+ * @note scope字符串长度不能超过1K
+ */
+@property (nonatomic, copy) NSString *scope;
+/** 第三方程序本身用来标识其请求的唯一性,最后跳转回第三方程序时,由微信终端回传。
+ * @note state字符串长度不能超过1K
+ */
+@property (nonatomic, copy) NSString *state;
+
+@property (nonatomic, assign) BOOL isOption1;
+
+/** 是否关闭自动授权
+ * @note YES为关闭自动授权,每次登陆都需要用户手动授权;NO为允许自动授权
+ */
+@property (nonatomic, assign) BOOL nonautomatic;
+
+@property (nonatomic, copy) NSString *extData;
+
+@end
+
+#pragma mark - SendAuthResp
+/*! @brief 微信处理完第三方程序的认证和权限申请后向第三方程序回送的处理结果。
+ *
+ * 第三方程序要向微信申请认证,并请求某些权限,需要调用WXApi的sendReq成员函数,向微信终端发送一个SendAuthReq消息结构。
+ * 微信终端处理完后会向第三方程序发送一个SendAuthResp。
+ * @see onResp
+ */
+@interface SendAuthResp : BaseResp
+@property (nonatomic, copy, nullable) NSString *code;
+/** 第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传
+ * @note state字符串长度不能超过1K
+ * @note 在复杂度较高的应用程序中,可能会出现其他模块请求的响应对象被错误地回调到当前模块。
+ * 为了避免影响其他模块,建议当前模块的开发者根据SendAuthResp的内容,采用白名单的方式进行处理。
+ * 例如,SendAuthResp.state符合预期时,才对其进行处理。
+ */
+@property (nonatomic, copy, nullable) NSString *state;
+@property (nonatomic, copy, nullable) NSString *lang;
+@property (nonatomic, copy, nullable) NSString *country;
+@end
+
+#pragma mark - WXStateJumpInfo
+/*! @brief 状态发表时的小尾巴跳转信息
+ */
+@interface WXStateJumpInfo : NSObject
+
+@end
+
+#pragma mark - WXStateJumpUrlInfo
+/*! @brief 状态小尾巴跳转指定url的信息
+ */
+@interface WXStateJumpUrlInfo : WXStateJumpInfo
+/** 跳转到指定的url
+ * @note 必填,url长度必须大于0且小于10K
+ */
+@property (nonatomic, copy) NSString *url;
+
+@end
+
+#pragma mark - WXStateJumpWXMiniProgramInfo
+/*! @brief 状态小尾巴跳转指定小程序的信息
+ */
+@interface WXStateJumpMiniProgramInfo : WXStateJumpInfo
+/** 小程序username
+ * @note 必填
+ */
+@property (nonatomic, copy) NSString *username;
+
+/** 小程序页面的路径
+ * @attention 不填默认拉起小程序首页
+ */
+@property (nonatomic, copy, nullable) NSString *path;
+
+/** 分享小程序的版本
+ * @attention (正式,开发,体验)
+ */
+@property (nonatomic, assign) WXMiniProgramType miniProgramType;
+
+@end
+
+
+
+#pragma mark - WXStateJumpWXMiniProgramInfo
+/*! @brief 状态小尾巴跳转指定视频号主页信息
+ */
+@interface WXStateJumpChannelProfileInfo : WXStateJumpInfo
+/** 视频号username
+ * @note 必填,username长度必须大于0且小于1K
+ */
+@property (nonatomic, copy) NSString *username;
+
+
+@end
+
+#pragma mark - WXStateSceneDataObject
+/*! @brief 场景类型额外参数基类
+ */
+@interface WXSceneDataObject : NSObject
+
+@end
+
+#pragma mark - WXStateSceneDataObject
+/*! @brief 状态场景类型
+ * 用户填写WXStateSceneDataObject参数后,可以跳转到微信状态发表页
+ */
+@interface WXStateSceneDataObject : WXSceneDataObject
+
+/** 状态标志的ID
+ * @note 选填,文本长度必须小于10K
+ */
+@property (nonatomic, copy) NSString *stateId;
+/** 状态发表时附带的文本描述
+ * @note 选填,文本长度必须小于10K
+ */
+@property (nonatomic, copy) NSString *stateTitle;
+/** 后台校验token
+ * @note 选填,文本长度必须小于10K
+ */
+@property (nonatomic, copy) NSString *token;
+/** 小尾巴跳转所需的信息
+ * @note 必填,目前仅支持url跳转
+ */
+@property (nonatomic, strong) WXStateJumpInfo *stateJumpDataInfo;
+
+@end
+
+#pragma mark - SendMessageToWXReq
+/*! @brief 第三方程序发送消息至微信终端程序的消息结构体
+ *
+ * 第三方程序向微信发送信息需要传入SendMessageToWXReq结构体,信息类型包括文本消息和多媒体消息,
+ * 分别对应于text和message成员。调用该方法后,微信处理完信息会向第三方程序发送一个处理结果。
+ * @see SendMessageToWXResp
+ */
+@interface SendMessageToWXReq : BaseReq
+/** 发送消息的文本内容
+ * @note 文本长度必须大于0且小于10K
+ */
+@property (nonatomic, copy) NSString *text;
+/** 发送消息的多媒体内容
+ * @see WXMediaMessage
+ */
+@property (nonatomic, strong) WXMediaMessage *message;
+/** 发送消息的类型,包括文本消息和多媒体消息两种,两者只能选择其一,不能同时发送文本和多媒体消息 */
+@property (nonatomic, assign) BOOL bText;
+/** 发送的目标场景,可以选择发送到会话(WXSceneSession)或者朋友圈(WXSceneTimeline)。 默认发送到会话。
+ * @see WXScene
+ */
+@property (nonatomic, assign) int scene;
+/** 指定发送消息的人
+ * @note WXSceneSpecifiedSession时有效
+ */
+@property (nonatomic, copy, nullable) NSString *toUserOpenId;
+/** 目标场景附带信息
+ * @note 目前只针对状态场景
+ */
+@property (nonatomic, strong) WXSceneDataObject *sceneDataObject;
+
+@end
+
+#pragma mark - SendMessageToWXResp
+/*! @brief 微信终端向第三方程序返回的SendMessageToWXReq处理结果。
+ *
+ * 第三方程序向微信终端发送SendMessageToWXReq后,微信发送回来的处理结果,该结果用SendMessageToWXResp表示。
+ */
+@interface SendMessageToWXResp : BaseResp
+@property(nonatomic, copy) NSString *lang;
+@property(nonatomic, copy) NSString *country;
+@end
+
+#pragma mark - GetMessageFromWXReq
+/*! @brief 微信终端向第三方程序请求提供内容的消息结构体。
+ *
+ * 微信终端向第三方程序请求提供内容,微信终端会向第三方程序发送GetMessageFromWXReq消息结构体,
+ * 需要第三方程序调用sendResp返回一个GetMessageFromWXResp消息结构体。
+ */
+@interface GetMessageFromWXReq : BaseReq
+@property (nonatomic, strong) NSString *lang;
+@property (nonatomic, strong) NSString *country;
+@end
+
+
+
+#pragma mark - GetMessageFromWXResp
+/*! @brief 微信终端向第三方程序请求提供内容,第三方程序向微信终端返回的消息结构体。
+ *
+ * 微信终端向第三方程序请求提供内容,第三方程序调用sendResp向微信终端返回一个GetMessageFromWXResp消息结构体。
+ */
+@interface GetMessageFromWXResp : BaseResp
+/** 向微信终端提供的文本内容
+ @note 文本长度必须大于0且小于10K
+ */
+@property (nonatomic, strong) NSString *text;
+/** 向微信终端提供的多媒体内容。
+ * @see WXMediaMessage
+ */
+@property (nonatomic, strong) WXMediaMessage *message;
+/** 向微信终端提供内容的消息类型,包括文本消息和多媒体消息两种,两者只能选择其一,不能同时发送文本和多媒体消息 */
+@property (nonatomic, assign) BOOL bText;
+@end
+
+
+
+#pragma mark - ShowMessageFromWXReq
+/*! @brief 微信通知第三方程序,要求第三方程序显示的消息结构体。
+ *
+ * 微信需要通知第三方程序显示或处理某些内容时,会向第三方程序发送ShowMessageFromWXReq消息结构体。
+ * 第三方程序处理完内容后调用sendResp向微信终端发送ShowMessageFromWXResp。
+ */
+@interface ShowMessageFromWXReq : BaseReq
+/** 微信终端向第三方程序发送的要求第三方程序处理的多媒体内容
+ * @see WXMediaMessage
+ */
+@property (nonatomic, strong) WXMediaMessage *message;
+@property (nonatomic, copy) NSString *lang;
+@property (nonatomic, copy) NSString *country;
+@end
+
+
+
+#pragma mark - ShowMessageFromWXResp
+/*! @brief 微信通知第三方程序,要求第三方程序显示或处理某些消息,第三方程序处理完后向微信终端发送的处理结果。
+ *
+ * 微信需要通知第三方程序显示或处理某些内容时,会向第三方程序发送ShowMessageFromWXReq消息结构体。
+ * 第三方程序处理完内容后调用sendResp向微信终端发送ShowMessageFromWXResp。
+ */
+@interface ShowMessageFromWXResp : BaseResp
+@end
+
+
+#pragma mark - LaunchFromWXReq
+/*! @brief 微信终端打开第三方程序携带的消息结构体
+ *
+ * 微信向第三方发送的结构体,第三方不需要返回
+ */
+@interface LaunchFromWXReq : BaseReq
+@property (nonatomic, strong) WXMediaMessage *message;
+@property (nonatomic, copy) NSString *lang;
+@property (nonatomic, copy) NSString *country;
+@end
+
+
+#pragma mark - OpenWebviewReq
+/* ! @brief 第三方通知微信启动内部浏览器,打开指定网页
+ *
+ * 第三方通知微信启动内部浏览器,打开指定Url对应的网页
+ */
+@interface OpenWebviewReq : BaseReq
+/** 需要打开的网页对应的Url
+ * @attention 长度不能超过1024
+ */
+@property(nonatomic, copy) NSString *url;
+
+@end
+
+#pragma mark - OpenWebviewResp
+/*! @brief 微信终端向第三方程序返回的OpenWebviewReq处理结果
+ *
+ * 第三方程序向微信终端发送OpenWebviewReq后,微信发送回来的处理结果,该结果用OpenWebviewResp表示
+ */
+@interface OpenWebviewResp : BaseResp
+
+@end
+
+
+
+#pragma mark - WXOpenBusinessWebViewReq
+/*! @brief 第三方通知微信启动内部浏览器,打开指定业务的网页
+ *
+ *
+ */
+@interface WXOpenBusinessWebViewReq : BaseReq
+
+/** 网页业务类型
+ * @attention
+ */
+@property (nonatomic, assign) UInt32 businessType;
+
+/** 网页业务参数
+ * @attention
+ */
+@property (nonatomic, strong, nullable) NSDictionary *queryInfoDic;
+
+@end
+
+#pragma mark - WXOpenBusinessWebViewResp
+/*! @brief 微信终端向第三方程序返回的WXOpenBusinessWebViewResp处理结果。
+ *
+ * 第三方程序向微信终端发送WXOpenBusinessWebViewReq后,微信发送回来的处理结果,该结果用WXOpenBusinessWebViewResp表示。
+ */
+@interface WXOpenBusinessWebViewResp : BaseResp
+/** 第三方程序自定义简单数据,微信终端会回传给第三方程序处理
+ * @attention 长度不能超过2k
+ */
+@property (nonatomic, copy) NSString *result;
+
+/** 网页业务类型
+ * @attention
+ */
+@property (nonatomic, assign) UInt32 businessType;
+
+@end
+
+
+#pragma mark - OpenRankListReq
+/* ! @brief 第三方通知微信,打开硬件排行榜
+ *
+ * 第三方通知微信,打开硬件排行榜
+ */
+@interface OpenRankListReq : BaseReq
+
+@end
+
+#pragma mark - OpenRanklistResp
+/*! @brief 微信终端向第三方程序返回的OpenRankListReq处理结果。
+ *
+ * 第三方程序向微信终端发送OpenRankListReq后,微信发送回来的处理结果,该结果用OpenRankListResp表示。
+ */
+@interface OpenRankListResp : BaseResp
+
+@end
+
+
+#pragma mark - WXCardItem
+
+@interface WXCardItem : NSObject
+/** 卡id
+ * @attention 长度不能超过1024字节
+ */
+@property (nonatomic, copy) NSString *cardId;
+/** ext信息
+ * @attention 长度不能超过2024字节
+ */
+@property (nonatomic, copy, nullable) NSString *extMsg;
+/**
+ * @attention 卡的状态,req不需要填。resp:0为未添加,1为已添加。
+ */
+@property (nonatomic, assign) UInt32 cardState;
+/**
+ * @attention req不需要填,chooseCard返回的。
+ */
+@property (nonatomic, copy) NSString *encryptCode;
+/**
+ * @attention req不需要填,chooseCard返回的。
+ */
+@property (nonatomic, copy) NSString *appID;
+@end;
+
+#pragma mark - WXInvoiceItem
+
+@interface WXInvoiceItem : NSObject
+/** 卡id
+ * @attention 长度不能超过1024字节
+ */
+@property (nonatomic, copy) NSString *cardId;
+/** ext信息
+ * @attention 长度不能超过2024字节
+ */
+@property (nonatomic, copy, nullable) NSString *extMsg;
+/**
+ * @attention 卡的状态,req不需要填。resp:0为未添加,1为已添加。
+ */
+@property (nonatomic, assign) UInt32 cardState;
+/**
+ * @attention req不需要填,chooseCard返回的。
+ */
+@property (nonatomic, copy) NSString *encryptCode;
+/**
+ * @attention req不需要填,chooseCard返回的。
+ */
+@property (nonatomic, copy) NSString *appID;
+
+@end
+
+#pragma mark - AddCardToWXCardPackageReq
+/* ! @brief 请求添加卡券至微信卡包
+ *
+ */
+
+@interface AddCardToWXCardPackageReq : BaseReq
+/** 卡列表
+ * @attention 个数不能超过40个 类型WXCardItem
+ */
+@property (nonatomic, strong) NSArray *cardAry;
+
+@end
+
+
+#pragma mark - AddCardToWXCardPackageResp
+/** ! @brief 微信返回第三方添加卡券结果
+ *
+ */
+
+@interface AddCardToWXCardPackageResp : BaseResp
+/** 卡列表
+ * @attention 个数不能超过40个 类型WXCardItem
+ */
+@property (nonatomic, strong) NSArray *cardAry;
+@end
+
+#pragma mark - WXChooseCardReq
+/* ! @brief 请求从微信选取卡券
+ *
+ */
+
+@interface WXChooseCardReq : BaseReq
+@property (nonatomic, copy) NSString *appID;
+@property (nonatomic, assign) UInt32 shopID;
+@property (nonatomic, assign) UInt32 canMultiSelect;
+@property (nonatomic, copy) NSString *cardType;
+@property (nonatomic, copy) NSString *cardTpID;
+@property (nonatomic, copy) NSString *signType;
+@property (nonatomic, copy) NSString *cardSign;
+@property (nonatomic, assign) UInt32 timeStamp;
+@property (nonatomic, copy) NSString *nonceStr;
+@end
+
+
+#pragma mark - WXChooseCardResp
+/** ! @brief 微信返回第三方请求选择卡券结果
+ *
+ */
+
+@interface WXChooseCardResp : BaseResp
+@property (nonatomic, strong ) NSArray* cardAry;
+@end
+
+
+#pragma mark - WXChooseInvoiceReq
+/* ! @brief 请求从微信选取发票
+ *
+ */
+@interface WXChooseInvoiceReq : BaseReq
+@property (nonatomic, copy) NSString *appID;
+@property (nonatomic, assign) UInt32 shopID;
+@property (nonatomic, copy) NSString *signType;
+@property (nonatomic, copy) NSString *cardSign;
+@property (nonatomic, assign) UInt32 timeStamp;
+@property (nonatomic, copy) NSString *nonceStr;
+@end
+
+#pragma mark - WXChooseInvoiceResp
+/** ! @brief 微信返回第三方请求选择发票结果
+ *
+ */
+@interface WXChooseInvoiceResp : BaseResp
+@property (nonatomic, strong) NSArray* cardAry;
+@end
+
+#pragma mark - WXSubscriptionReq
+@interface WXSubscribeMsgReq : BaseReq
+@property (nonatomic, assign) UInt32 scene;
+@property (nonatomic, copy) NSString *templateId;
+@property (nonatomic, copy, nullable) NSString *reserved;
+@end
+
+#pragma mark - WXSubscriptionReq
+@interface WXSubscribeMsgResp : BaseResp
+
+@property (nonatomic, copy) NSString *templateId;
+@property (nonatomic, assign) UInt32 scene;
+@property (nonatomic, copy) NSString *action;
+@property (nonatomic, copy) NSString *reserved;
+@property (nonatomic, copy, nullable) NSString *openId;
+
+@end
+
+#pragma mark - WXSubscribeMiniProgramMsg
+/** ! @brief 第三方请求订阅小程序消息
+ *
+ */
+@interface WXSubscribeMiniProgramMsgReq : BaseReq
+@property (nonatomic, copy) NSString *miniProgramAppid;
+@end
+
+#pragma mark - WXSubscriptionReq
+@interface WXSubscribeMiniProgramMsgResp : BaseResp
+
+@property(nonatomic, copy) NSString *openId; // 小程序openid
+@property(nonatomic, copy) NSString *unionId; // unionId
+@property(nonatomic, copy) NSString *nickName; // 用户昵称
+
+@end
+
+#pragma mark - WXinvoiceAuthInsertReq
+@interface WXInvoiceAuthInsertReq : BaseReq
+
+@property (nonatomic, copy) NSString *urlString;
+
+@end
+
+#pragma mark - WXinvoiceAuthInsertResp
+
+@interface WXInvoiceAuthInsertResp : BaseResp
+
+@property (nonatomic, copy) NSString *wxOrderId;
+
+@end
+
+#pragma mark - WXMediaMessage
+
+/*! @brief 多媒体消息结构体
+ *
+ * 用于微信终端和第三方程序之间传递消息的多媒体消息内容
+ */
+@interface WXMediaMessage : NSObject
+
++ (WXMediaMessage *)message;
+
+/** 标题
+ * @note 长度不能超过512字节
+ */
+@property (nonatomic, copy) NSString *title;
+/** 描述内容
+ * @note 长度不能超过1K
+ */
+@property (nonatomic, copy) NSString *description;
+/** 缩略图数据
+ * @note 大小不能超过64K
+ */
+@property (nonatomic, strong, nullable) NSData *thumbData;
+/**
+ * @note 长度不能超过64字节
+ */
+@property (nonatomic, copy, nullable) NSString *mediaTagName;
+/**
+ *
+ */
+@property (nonatomic, copy, nullable) NSString *messageExt;
+@property (nonatomic, copy, nullable) NSString *messageAction;
+/**
+ * 多媒体数据对象,可以为WXImageObject,WXMusicObject,WXVideoObject,WXWebpageObject等。
+ */
+@property (nonatomic, strong) id mediaObject;
+
+/** 缩略图的hash值
+ * @note 使用sha256得到,用于计算签名
+ */
+@property (nonatomic, copy, nullable) NSString *thumbDataHash;
+
+/** 消息签名
+ * @note 用于校验消息体是否被篡改过
+ */
+@property (nonatomic, copy, nullable) NSString *msgSignature;
+
+
+/*! @brief 设置消息缩略图的方法
+ *
+ * @param image 缩略图
+ * @note 大小不能超过256K
+ */
+- (void)setThumbImage:(UIImage *)image;
+
+@end
+
+
+
+#pragma mark - WXImageObject
+/*! @brief 多媒体消息中包含的图片数据对象
+ *
+ * 微信终端和第三方程序之间传递消息中包含的图片数据对象。
+ * @note imageData成员不能为空
+ * @see WXMediaMessage
+ */
+@interface WXImageObject : NSObject
+/*! @brief 返回一个WXImageObject对象
+ *
+ * @note 返回的WXImageObject对象是自动释放的
+ */
++ (WXImageObject *)object;
+
+/** 图片真实数据内容
+ * @note 大小不能超过25M
+ */
+@property (nonatomic, strong) NSData *imageData;
+
+/** 图片数据的hash值
+ * @note 使用sha256得到,用于计算签名
+ */
+@property (nonatomic, copy, nullable) NSString *imgDataHash;
+
+/** 分享的图片消息是否要带小程序入口,若 'entranceMiniProgramUsername' 非空则显示
+ * 仅部分小程序类目可用
+ * @note 本字段为空则发送普通app图片消息
+ */
+@property (nonatomic, copy, nullable) NSString *entranceMiniProgramUsername;
+
+/** 分享的图片消息显示的小程序入口可以跳转的小程序路径
+ * 仅当 'entranceMiniProgramUsername' 非空时生效
+ */
+@property (nonatomic, copy, nullable) NSString *entranceMiniProgramPath;
+
+@end
+
+
+#pragma mark - WXMusicObject
+/*! @brief 多媒体消息中包含的音乐数据对象
+ *
+ * 微信终端和第三方程序之间传递消息中包含的音乐数据对象。
+ * @note musicUrl和musicLowBandUrl成员不能同时为空。
+ * @see WXMediaMessage
+ */
+@interface WXMusicObject : NSObject
+/*! @brief 返回一个WXMusicObject对象
+ *
+ * @note 返回的WXMusicObject对象是自动释放的
+ */
++ (WXMusicObject *)object;
+
+/** 音乐网页的url地址
+ * @note 长度不能超过10K
+ */
+@property (nonatomic, copy) NSString *musicUrl;
+/** 音乐lowband网页的url地址
+ * @note 长度不能超过10K
+ */
+@property (nonatomic, copy) NSString *musicLowBandUrl;
+/** 音乐数据url地址
+ * @note 长度不能超过10K
+ */
+@property (nonatomic, copy) NSString *musicDataUrl;
+
+/**音乐lowband数据url地址
+ * @note 长度不能超过10K
+ */
+@property (nonatomic, copy) NSString *musicLowBandDataUrl;
+
+/**音乐封面图Url
+ * @note 长度不能超过10K
+ */
+@property (nonatomic, copy) NSString *songAlbumUrl;
+
+/**歌词信息 LRC格式
+ * @note 长度不能超过32K
+ */
+@property (nonatomic, copy, nullable) NSString *songLyric;
+@end
+
+
+
+#pragma mark - WXMusicVideoObject
+
+@interface WXMusicVipInfo : NSObject
+
+/**付费歌曲的id
+ * @note 长度不能超过32K
+ */
+@property (nonatomic, copy) NSString *musicId;
+
+@end
+
+
+@interface WXMusicVideoObject : NSObject
+
+/*! @brief 返回一个WXMusicVideoObject对象
+ *
+ * @note 返回的WXMusicVideoObject对象是自动释放的
+ */
++ (WXMusicVideoObject *)object;
+
+/** 音乐网页的url地址
+ * @note 长度不能超过10K,不能为空
+ */
+@property (nonatomic, copy) NSString *musicUrl;
+
+/** 音乐数据url地址
+ * @note 长度不能超过10K,不能为空
+ */
+@property (nonatomic, copy) NSString *musicDataUrl;
+
+/**歌手名
+ * @note 长度不能超过1k,不能为空
+ */
+@property (nonatomic, copy) NSString *singerName;
+
+/**
+ * @note 音乐时长, 单位毫秒
+ */
+@property (nonatomic, assign) UInt32 duration;
+
+/**歌词信息 LRC格式
+ * @note 长度不能超过32K
+ */
+@property (nonatomic, copy) NSString *songLyric;
+
+/**高清封面图
+ * @note 大小不能超过1M
+ */
+@property (nonatomic, strong) NSData *hdAlbumThumbData;
+
+/** 高清封面图数据的hash值
+ * @note 使用sha256得到,用于计算签名
+ */
+@property (nonatomic, copy, nullable) NSString *hdAlbumThumbFileHash;
+
+/**音乐专辑名称
+ * @note 长度不能超过1k
+ */
+@property (nonatomic, copy, nullable) NSString *albumName;
+
+/**音乐流派
+ * @note 长度不能超过1k
+ */
+@property (nonatomic, copy, nullable) NSString *musicGenre;
+
+/**发行时间
+ * @note Unix时间戳,单位为秒
+ */
+@property (nonatomic, assign) UInt64 issueDate;
+
+/**音乐标识符
+ * @note 长度不能超过1K,从微信跳回应用时会带上
+ */
+@property (nonatomic, copy, nullable) NSString *identification;
+
+/**运营H5地址
+ * @note 选填,建议填写,用户进入歌曲详情页将展示内嵌的运营H5,可展示该歌曲的相关评论、歌曲推荐等内容,不可诱导下载、分享等。
+ */
+@property (nonatomic, copy, nullable) NSString *musicOperationUrl;
+
+/** 付费歌曲相关信息
+ * @note 选填,如果歌曲是需要付费的,那么将付费歌曲id等信息封装在内。
+ */
+@property (nonatomic, strong) WXMusicVipInfo *musicVipInfo;
+
+@end
+
+
+
+#pragma mark - WXVideoObject
+/*! @brief 多媒体消息中包含的视频数据对象
+ *
+ * 微信终端和第三方程序之间传递消息中包含的视频数据对象。
+ * @note videoUrl和videoLowBandUrl不能同时为空。
+ * @see WXMediaMessage
+ */
+@interface WXVideoObject : NSObject
+/*! @brief 返回一个WXVideoObject对象
+ *
+ * @note 返回的WXVideoObject对象是自动释放的
+ */
++ (WXVideoObject *)object;
+
+/** 视频网页的url地址
+ * @note 长度不能超过10K
+ */
+@property (nonatomic, copy) NSString *videoUrl;
+/** 视频lowband网页的url地址
+ * @note 长度不能超过10K
+ */
+@property (nonatomic, copy) NSString *videoLowBandUrl;
+
+@end
+
+
+
+#pragma mark - WXWebpageObject
+/*! @brief 多媒体消息中包含的网页数据对象
+ *
+ * 微信终端和第三方程序之间传递消息中包含的网页数据对象。
+ * @see WXMediaMessage
+ */
+@interface WXWebpageObject : NSObject
+/*! @brief 返回一个WXWebpageObject对象
+ *
+ * @note 返回的WXWebpageObject对象是自动释放的
+ */
++ (WXWebpageObject *)object;
+
+/** 网页的url地址
+ * @note 不能为空且长度不能超过10K
+ */
+@property (nonatomic, copy) NSString *webpageUrl;
+
+/**是否是私密消息
+ */
+@property (nonatomic, assign) BOOL isSecretMessage;
+
+/** 业务所需的额外信息 */
+@property (nonatomic, strong, nullable) NSDictionary *extraInfoDic;
+
+@end
+
+
+
+#pragma mark - WXAppExtendObject
+/*! @brief 多媒体消息中包含的App扩展数据对象
+ *
+ * 第三方程序向微信终端发送包含WXAppExtendObject的多媒体消息,
+ * 微信需要处理该消息时,会调用该第三方程序来处理多媒体消息内容。
+ * @note url,extInfo和fileData不能同时为空
+ * @see WXMediaMessage
+ */
+@interface WXAppExtendObject : NSObject
+/*! @brief 返回一个WXAppExtendObject对象
+ *
+ * @note 返回的WXAppExtendObject对象是自动释放的
+ */
++ (WXAppExtendObject *)object;
+
+/** 若第三方程序不存在,微信终端会打开该url所指的App下载地址
+ * @note 长度不能超过10K
+ */
+@property (nonatomic, copy) NSString *url;
+/** 第三方程序自定义简单数据,微信终端会回传给第三方程序处理
+ * @note 长度不能超过2K
+ */
+@property (nonatomic, copy, nullable) NSString *extInfo;
+/** App文件数据,该数据发送给微信好友,微信好友需要点击后下载数据,微信终端会回传给第三方程序处理
+ * @note 大小不能超过10M
+ */
+@property (nonatomic, strong, nullable) NSData *fileData;
+
+@end
+
+
+
+#pragma mark - WXEmoticonObject
+/*! @brief 多媒体消息中包含的表情数据对象
+ *
+ * 微信终端和第三方程序之间传递消息中包含的表情数据对象。
+ * @see WXMediaMessage
+ */
+@interface WXEmoticonObject : NSObject
+
+/*! @brief 返回一个WXEmoticonObject对象
+ *
+ * @note 返回的WXEmoticonObject对象是自动释放的
+ */
++ (WXEmoticonObject *)object;
+
+/** 表情真实数据内容
+ * @note 大小不能超过10M
+ */
+@property (nonatomic, strong) NSData *emoticonData;
+
+@end
+
+
+
+#pragma mark - WXFileObject
+/*! @brief 多媒体消息中包含的文件数据对象
+ *
+ * @see WXMediaMessage
+ */
+@interface WXFileObject : NSObject
+
+/*! @brief 返回一个WXFileObject对象
+ *
+ * @note 返回的WXFileObject对象是自动释放的
+ */
++ (WXFileObject *)object;
+
+/** 文件后缀名
+ * @note 长度不超过64字节
+ */
+@property (nonatomic, copy) NSString *fileExtension;
+
+/** 文件真实数据内容
+ * @note 大小不能超过10M
+ */
+@property (nonatomic, strong) NSData *fileData;
+
+@end
+
+
+#pragma mark - WXLocationObject
+/*! @brief 多媒体消息中包含的地理位置数据对象
+ *
+ * 微信终端和第三方程序之间传递消息中包含的地理位置数据对象。
+ * @see WXMediaMessage
+ */
+@interface WXLocationObject : NSObject
+
+/*! @brief 返回一个WXLocationObject对象
+ *
+ * @note 返回的WXLocationObject对象是自动释放的
+ */
++ (WXLocationObject *)object;
+
+/** 地理位置信息
+ * @note 经纬度
+ */
+@property (nonatomic, assign) double lng; //经度
+@property (nonatomic, assign) double lat; //纬度
+
+@end
+
+#pragma mark - WXTextObject
+/*! @brief 多媒体消息中包含的文本数据对象
+ *
+ * 微信终端和第三方程序之间传递消息中包含的文本数据对象。
+ * @see WXMediaMessage
+ */
+@interface WXTextObject : NSObject
+
+/*! @brief 返回一个WXTextObject对象
+ *
+ * @note 返回的WXTextObject对象是自动释放的
+ */
++ (WXTextObject *)object;
+
+/** 地理位置信息
+ * @note 文本内容
+ */
+@property (nonatomic, copy) NSString *contentText;
+
+@end
+
+#pragma mark - WXMiniProgramObject
+
+@interface WXMiniProgramObject : NSObject
+
+/*! @brief WXMiniProgramObject对象
+ *
+ * @note 返回的WXMiniProgramObject对象是自动释放的
+ */
++ (WXMiniProgramObject *)object;
+
+/** 低版本网页链接
+ * @attention 长度不能超过1024字节
+ */
+@property (nonatomic, copy) NSString *webpageUrl;
+
+/** 小程序username */
+@property (nonatomic, copy) NSString *userName;
+
+/** 小程序页面的路径
+ * @attention 不填默认拉起小程序首页
+ */
+@property (nonatomic, copy, nullable) NSString *path;
+
+/** 小程序新版本的预览图
+ * @attention 大小不能超过128k
+ */
+@property (nonatomic, strong, nullable) NSData *hdImageData;
+
+/** 是否使用带 shareTicket 的转发 */
+@property (nonatomic, assign) BOOL withShareTicket;
+
+/** 分享小程序的版本
+ * @attention (正式,开发,体验)
+ */
+@property (nonatomic, assign) WXMiniProgramType miniProgramType;
+
+/** 是否禁用转发 */
+@property (nonatomic, assign) BOOL disableForward;
+
+@property (nonatomic, assign) BOOL isUpdatableMessage;
+
+@property (nonatomic, assign) BOOL isSecretMessage;
+
+
+/** 业务所需的额外信息 */
+@property (nonatomic, strong, nullable) NSDictionary *extraInfoDic;
+
+@end
+
+#pragma mark - WXGameLiveObject
+
+/*! @brief WXGameLiveObject对象
+ *
+ * @note 游戏直播消息类型
+ */
+
+@interface WXGameLiveObject : NSObject
+
++ (WXGameLiveObject *)object;
+
+/** 业务所需的额外信息 */
+@property (nonatomic, strong, nullable) NSDictionary *extraInfoDic;
+
+@end
+
+@interface WXNativeGamePageObject : NSObject
+
+/** 是否为视频类型
+ */
+@property (nonatomic, assign) BOOL isVideo;
+
+/** 视频时长
+ @note 当为视频类型时,必填;单位为秒
+ */
+@property (nonatomic, assign) UInt32 videoDuration;
+
+/** 透传字段
+ @note 长度限制为100K
+ */
+@property (nonatomic, copy) NSString *shareData;
+
+/** 缩略图
+ @note 大小限制为256K
+ */
+@property (nonatomic, strong) NSData *gameThumbData;
+
++ (WXNativeGamePageObject *)object;
+
+@end
+
+#pragma mark - WXLaunchMiniProgramReq
+
+/*! @brief WXLaunchMiniProgramReq对象, 可实现通过sdk拉起微信小程序
+ *
+ * @note 返回的WXLaunchMiniProgramReq对象是自动释放的
+ */
+@interface WXLaunchMiniProgramReq : BaseReq
+
++ (WXLaunchMiniProgramReq *)object;
+
+/** 小程序username */
+@property (nonatomic, copy) NSString *userName;
+
+/** 小程序页面的路径
+ * @attention 不填默认拉起小程序首页
+ */
+@property (nonatomic, copy, nullable) NSString *path;
+
+/** 分享小程序的版本
+ * @attention (正式,开发,体验)
+ */
+@property (nonatomic, assign) WXMiniProgramType miniProgramType;
+
+/** ext信息
+ * @attention json格式
+ */
+@property (nonatomic, copy, nullable) NSString *extMsg;
+
+/** extDic
+ * @attention 字典,可存放图片等比较大的数据
+ */
+@property (nonatomic, copy, nullable) NSDictionary *extDic;
+
+@end
+
+#pragma mark - WXLaunchMiniProgramResp
+/*! @brief 微信终端向第三方程序返回的WXLaunchMiniProgramReq处理结果。
+ *
+ * 第三方程序向微信终端发送WXLaunchMiniProgramReq后,微信发送回来的处理结果,该结果用WXLaunchMiniProgramResp表示。
+ */
+@interface WXLaunchMiniProgramResp : BaseResp
+
+@property (nonatomic, copy, nullable) NSString *extMsg;
+
+@end
+
+
+#pragma mark - WXOpenBusinessViewReq
+/*! @brief WXOpenBusinessViewReq对象, 可实现第三方通知微信启动,打开业务页面
+ *
+ * @note 返回的WXOpenBusinessViewReq对象是自动释放的
+ */
+
+@interface WXOpenBusinessViewReq : BaseReq
+
++ (WXOpenBusinessViewReq *)object;
+
+/** 业务类型
+ */
+@property (nonatomic, copy) NSString *businessType;
+
+/** 业务参数
+ */
+@property (nonatomic, copy, nullable) NSString *query;
+
+/** ext信息
+ * @note 选填,json格式
+ */
+@property (nonatomic, copy, nullable) NSString *extInfo;
+
+/** extData数据
+ * @note
+ */
+@property (nonatomic, strong, nullable) NSData *extData;
+@end
+
+
+@interface WXOpenBusinessViewResp : BaseResp
+
+/** 业务类型
+ */
+@property (nonatomic, copy) NSString *businessType;
+
+/** 业务返回数据
+ */
+@property (nonatomic, copy, nullable) NSString *extMsg;
+
+@end
+
+#pragma mark - WXOpenCustomerServiceReq
+@interface WXOpenCustomerServiceReq : BaseReq
+
++ (WXOpenCustomerServiceReq *)object;
+
+/**企微客服发起流程 url
+ */
+@property (nonatomic, copy, nullable) NSString *url;
+
+/**企业 id
+ */
+@property (nonatomic, copy, nullable) NSString *corpid;
+
+@end
+
+@interface WXOpenCustomerServiceResp : BaseResp
+
+/** 业务返回数据
+ */
+@property (nonatomic, copy, nullable) NSString *extMsg;
+
+@end
+
+
+#pragma mark - WXChannelStartLiveReq
+
+@interface WXChannelStartLiveReq : BaseReq
+
++ (WXChannelStartLiveReq *)object;
+
+/** 必填,直播业务数据(json格式)
+ */
+@property (nonatomic, copy) NSString *liveJsonInfo;
+
+@end
+
+@interface WXChannelStartLiveResp : BaseResp
+
+/** 业务返回数据
+ */
+@property (nonatomic, copy, nullable) NSString *extMsg;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Headers/WechatAuthSDK.h b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Headers/WechatAuthSDK.h
new file mode 100644
index 00000000..308aaea1
--- /dev/null
+++ b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Headers/WechatAuthSDK.h
@@ -0,0 +1,68 @@
+//
+// WechatAuthSDK.h
+// WechatAuthSDK
+//
+// Created by 李凯 on 13-11-29.
+// Copyright (c) 2013年 Tencent. All rights reserved.
+//
+
+#import
+#import
+
+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
+@optional
+
+- (void)onAuthGotQrcode:(UIImage *)image; //得到二维码
+- (void)onQrcodeScanned; //二维码被扫描
+- (void)onAuthFinish:(int)errCode AuthCode:(nullable NSString *)authCode; //成功登录
+
+@end
+
+@interface WechatAuthSDK : NSObject{
+ NSString *_sdkVersion;
+ __weak id _delegate;
+}
+
+@property(nonatomic, weak, nullable) id 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
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Headers/WechatOpenSDK.h b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Headers/WechatOpenSDK.h
new file mode 100644
index 00000000..979e5e99
--- /dev/null
+++ b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Headers/WechatOpenSDK.h
@@ -0,0 +1,9 @@
+// WechatOpenSDK.h
+//
+// Created by Wechat.
+// Copyright (c) 2012年 Tencent. All rights reserved.
+//
+#import
+#import
+#import
+
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Info.plist b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Info.plist
new file mode 100755
index 00000000..45d60687
--- /dev/null
+++ b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Info.plist
@@ -0,0 +1,15 @@
+
+
+
+ CFBundleIdentifier
+ com.tencent.WechatOpenSDK
+ CFBundleVersion
+ 1.0.0
+ CFBundleShortVersionString
+ 1.0
+ MinimumOSVersion
+ 12.0
+ CFBundleExecutable
+ WechatOpenSDK
+
+
\ No newline at end of file
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Modules/module.modulemap b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Modules/module.modulemap
new file mode 100644
index 00000000..3ddbeb0b
--- /dev/null
+++ b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/Modules/module.modulemap
@@ -0,0 +1,5 @@
+framework module WechatOpenSDK {
+ umbrella header "WechatOpenSDK.h"
+ export *
+ link "WechatOpenSDK"
+}
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/WechatOpenSDK b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/WechatOpenSDK
new file mode 100644
index 00000000..73d455d5
Binary files /dev/null and b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64/WechatOpenSDK.framework/WechatOpenSDK differ
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/Headers/WXApi.h b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/Headers/WXApi.h
new file mode 100644
index 00000000..879c5059
--- /dev/null
+++ b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/Headers/WXApi.h
@@ -0,0 +1,231 @@
+//
+// WXApi.h
+// 所有Api接口
+//
+// Created by Wechat on 12-2-28.
+// Copyright (c) 2012年 Tencent. All rights reserved.
+//
+
+#import
+#import "WXApiObject.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+
+typedef BOOL(^WXGrantReadPasteBoardPermissionCompletion)(void);
+
+
+#pragma mark - WXApiDelegate
+/*! @brief 接收并处理来自微信终端程序的事件消息
+ *
+ * 接收并处理来自微信终端程序的事件消息,期间微信界面会切换到第三方应用程序。
+ * WXApiDelegate 会在handleOpenURL:delegate:中使用并触发。
+ */
+@protocol WXApiDelegate
+@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
+
+- (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)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)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)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)logDelegate;
+
+/*! @brief 停止打印log,会清理block或者delegate为空,释放block
+ * @param
+ */
++ (void)stopLog;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/Headers/WXApiObject.h b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/Headers/WXApiObject.h
new file mode 100644
index 00000000..85b64578
--- /dev/null
+++ b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/Headers/WXApiObject.h
@@ -0,0 +1,1410 @@
+//
+// MMApiObject.h
+// Api对象,包含所有接口和对象数据定义
+//
+// Created by Wechat on 12-2-28.
+// Copyright (c) 2012年 Tencent. All rights reserved.
+//
+
+#import
+#import
+
+NS_ASSUME_NONNULL_BEGIN
+
+/*! @brief 错误码
+ *
+ */
+enum WXErrCode {
+ WXSuccess = 0, /**< 成功 */
+ WXErrCodeCommon = -1, /**< 普通错误类型 */
+ WXErrCodeUserCancel = -2, /**< 用户点击取消并返回 */
+ WXErrCodeSentFail = -3, /**< 发送失败 */
+ WXErrCodeAuthDeny = -4, /**< 授权失败 */
+ WXErrCodeUnsupport = -5, /**< 微信不支持 */
+};
+
+
+
+/*! @brief 请求发送场景
+ *
+ */
+enum WXScene {
+ WXSceneSession = 0, /**< 聊天界面 */
+ WXSceneTimeline = 1, /**< 朋友圈 */
+ WXSceneFavorite = 2, /**< 收藏 */
+ WXSceneSpecifiedSession = 3, /**< 指定联系人 */
+ WXSceneState = 4, /**< 状态 */
+};
+
+
+enum WXAPISupport {
+ WXAPISupportSession = 0,
+};
+
+
+
+/*! @brief 跳转profile类型
+ *
+ */
+enum WXBizProfileType {
+ WXBizProfileType_Normal = 0, //**< 普通公众号 */
+ WXBizProfileType_Device = 1, //**< 硬件公众号 */
+};
+
+/*! @brief 分享小程序类型
+ *
+ */
+typedef NS_ENUM(NSUInteger, WXMiniProgramType) {
+ WXMiniProgramTypeRelease = 0, //**< 正式版 */
+ WXMiniProgramTypeTest = 1, //**< 开发版 */
+ WXMiniProgramTypePreview = 2, //**< 体验版 */
+};
+
+/*! @brief 跳转mp网页类型
+ *
+ */
+enum WXMPWebviewType {
+ WXMPWebviewType_Ad = 0, /**< 广告网页 **/
+};
+
+/*! @brief log的级别
+ *
+ */
+typedef NS_ENUM(NSInteger,WXLogLevel) {
+ WXLogLevelNormal = 0, // 打印日常的日志
+ WXLogLevelDetail = 1, // 打印详细的日志
+};
+
+
+/*! @brief 打印回调的block
+ *
+ */
+typedef void(^WXLogBolock)(NSString *log);
+
+/*! @brief 微信Universal Link检查函数 (WXApi#checkUniversalLinkReady:),检查步骤枚举值
+ *
+ * WXULCheckStepParams 参数检测
+ * WXULCheckStepSystemVersion 当前系统版本检测
+ * WXULCheckStepWechatVersion 微信客户端版本检测
+ * WXULCheckStepSDKInnerOperation 微信SDK内部操作检测
+ * WXULCheckStepLaunchWechat App拉起微信检测
+ * WXULCheckStepBackToCurrentApp 由微信返回当前App检测
+ * WXULCheckStepFinal 最终结果
+ */
+typedef NS_ENUM(NSInteger, WXULCheckStep)
+{
+ WXULCheckStepParams,
+ WXULCheckStepSystemVersion,
+ WXULCheckStepWechatVersion,
+ WXULCheckStepSDKInnerOperation,
+ WXULCheckStepLaunchWechat,
+ WXULCheckStepBackToCurrentApp,
+ WXULCheckStepFinal,
+};
+
+
+#pragma mark - WXCheckULStepResult
+
+/*! @brief 该类为微信Universal Link检测函数结果类
+*
+*/
+@interface WXCheckULStepResult : NSObject
+
+/** 是否成功 */
+@property(nonatomic, assign) BOOL success;
+/** 当前错误信息 */
+@property(nonatomic, strong) NSString* errorInfo;
+/** 修正建议 */
+@property(nonatomic, strong) NSString* suggestion;
+
+- (instancetype)initWithCheckResult:(BOOL)success errorInfo:(nullable NSString*)errorInfo suggestion:(nullable NSString*)suggestion;
+
+@end
+
+
+/*! @brief 微信Universal Link检查函数 (WXApi#checkUniversalLinkReady:),回调Block
+ *
+ * @param step 当前检测步骤
+ * @param result 检测结果
+ */
+typedef void(^WXCheckULCompletion)(WXULCheckStep step, WXCheckULStepResult* result);
+
+
+#pragma mark - BaseReq
+/*! @brief 该类为微信终端SDK所有请求类的基类
+ *
+ */
+@interface BaseReq : NSObject
+
+/** 请求类型 */
+@property (nonatomic, assign) int type;
+/** 由用户微信号和AppID组成的唯一标识,需要校验微信用户是否换号登录时填写*/
+@property (nonatomic, copy) NSString *openID;
+
+@end
+
+
+
+#pragma mark - BaseResp
+/*! @brief 该类为微信终端SDK所有响应类的基类
+ *
+ */
+@interface BaseResp : NSObject
+/** 错误码 */
+@property (nonatomic, assign) int errCode;
+/** 错误提示字符串 */
+@property (nonatomic, copy) NSString *errStr;
+/** 响应类型 */
+@property (nonatomic, assign) int type;
+
+@end
+
+
+
+#pragma mark - WXMediaMessage
+@class WXMediaMessage;
+
+#ifndef BUILD_WITHOUT_PAY
+
+#pragma mark - PayReq
+/*! @brief 第三方向微信终端发起支付的消息结构体
+ *
+ * 第三方向微信终端发起支付的消息结构体,微信终端处理后会向第三方返回处理结果
+ * @see PayResp
+ */
+@interface PayReq : BaseReq
+
+/** 商家向财付通申请的商家id */
+@property (nonatomic, copy) NSString *partnerId;
+/** 预支付订单 */
+@property (nonatomic, copy) NSString *prepayId;
+/** 随机串,防重发 */
+@property (nonatomic, copy) NSString *nonceStr;
+/** 时间戳,防重发 */
+@property (nonatomic, assign) UInt32 timeStamp;
+/** 商家根据财付通文档填写的数据和签名 */
+@property (nonatomic, copy) NSString *package;
+/** 商家根据微信开放平台文档对数据做的签名 */
+@property (nonatomic, copy) NSString *sign;
+
+@end
+
+
+#pragma mark - PayResp
+/*! @brief 微信终端返回给第三方的关于支付结果的结构体
+ *
+ * 微信终端返回给第三方的关于支付结果的结构体
+ */
+@interface PayResp : BaseResp
+
+/** 财付通返回给商家的信息 */
+@property (nonatomic, copy) NSString *returnKey;
+
+@end
+
+#pragma mark - WXOfflinePay
+/*! @brief 第三方向微信终端发起离线支付
+ *
+ * 第三方向微信终端发起离线支付的消息结构体
+ */
+@interface WXOfflinePayReq : BaseReq
+
+@end
+
+/*! @brief 第三方向微信终端发起离线支付返回
+ *
+ * 第三方向微信终端发起离线支付返回的消息结构体
+ */
+@interface WXOfflinePayResp : BaseResp
+
+@end
+
+
+#pragma mark - WXNontaxPayReq
+@interface WXNontaxPayReq:BaseReq
+
+@property (nonatomic, copy) NSString *urlString;
+
+@end
+
+#pragma mark - WXNontaxPayResp
+@interface WXNontaxPayResp : BaseResp
+
+@property (nonatomic, copy) NSString *wxOrderId;
+
+@end
+
+#pragma mark - WXPayInsuranceReq
+@interface WXPayInsuranceReq : BaseReq
+
+@property (nonatomic, copy) NSString *urlString;
+
+@end
+
+#pragma mark - WXPayInsuranceResp
+@interface WXPayInsuranceResp : BaseResp
+
+@property (nonatomic, copy) NSString *wxOrderId;
+
+@end
+
+
+#pragma mark - WXQRCodePayReq
+@interface WXQRCodePayReq : BaseReq
+/** 码内容
+ * @note 必填,码长度必须大于0且小于10K
+ */
+@property (nonatomic, copy) NSString *codeContent;
+/** 额外信息
+ * @note 长度必须大于0且小于10K
+ */
+@property (nonatomic, copy) NSString *extraMsg;
+
+@end
+
+@interface WXQRCodePayResp : BaseResp
+@end
+
+#endif
+
+
+#pragma mark - SendAuthReq
+/*! @brief 第三方程序向微信终端请求认证的消息结构
+ *
+ * 第三方程序要向微信申请认证,并请求某些权限,需要调用WXApi的sendReq成员函数,
+ * 向微信终端发送一个SendAuthReq消息结构。微信终端处理完后会向第三方程序发送一个处理结果。
+ * @see SendAuthResp
+ */
+@interface SendAuthReq : BaseReq
+/** 第三方程序要向微信申请认证,并请求某些权限,需要调用WXApi的sendReq成员函数,向微信终端发送一个SendAuthReq消息结构。微信终端处理完后会向第三方程序发送一个处理结果。
+ * @see SendAuthResp
+ * @note scope字符串长度不能超过1K
+ */
+@property (nonatomic, copy) NSString *scope;
+/** 第三方程序本身用来标识其请求的唯一性,最后跳转回第三方程序时,由微信终端回传。
+ * @note state字符串长度不能超过1K
+ */
+@property (nonatomic, copy) NSString *state;
+
+@property (nonatomic, assign) BOOL isOption1;
+
+/** 是否关闭自动授权
+ * @note YES为关闭自动授权,每次登陆都需要用户手动授权;NO为允许自动授权
+ */
+@property (nonatomic, assign) BOOL nonautomatic;
+
+@property (nonatomic, copy) NSString *extData;
+
+@end
+
+#pragma mark - SendAuthResp
+/*! @brief 微信处理完第三方程序的认证和权限申请后向第三方程序回送的处理结果。
+ *
+ * 第三方程序要向微信申请认证,并请求某些权限,需要调用WXApi的sendReq成员函数,向微信终端发送一个SendAuthReq消息结构。
+ * 微信终端处理完后会向第三方程序发送一个SendAuthResp。
+ * @see onResp
+ */
+@interface SendAuthResp : BaseResp
+@property (nonatomic, copy, nullable) NSString *code;
+/** 第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传
+ * @note state字符串长度不能超过1K
+ * @note 在复杂度较高的应用程序中,可能会出现其他模块请求的响应对象被错误地回调到当前模块。
+ * 为了避免影响其他模块,建议当前模块的开发者根据SendAuthResp的内容,采用白名单的方式进行处理。
+ * 例如,SendAuthResp.state符合预期时,才对其进行处理。
+ */
+@property (nonatomic, copy, nullable) NSString *state;
+@property (nonatomic, copy, nullable) NSString *lang;
+@property (nonatomic, copy, nullable) NSString *country;
+@end
+
+#pragma mark - WXStateJumpInfo
+/*! @brief 状态发表时的小尾巴跳转信息
+ */
+@interface WXStateJumpInfo : NSObject
+
+@end
+
+#pragma mark - WXStateJumpUrlInfo
+/*! @brief 状态小尾巴跳转指定url的信息
+ */
+@interface WXStateJumpUrlInfo : WXStateJumpInfo
+/** 跳转到指定的url
+ * @note 必填,url长度必须大于0且小于10K
+ */
+@property (nonatomic, copy) NSString *url;
+
+@end
+
+#pragma mark - WXStateJumpWXMiniProgramInfo
+/*! @brief 状态小尾巴跳转指定小程序的信息
+ */
+@interface WXStateJumpMiniProgramInfo : WXStateJumpInfo
+/** 小程序username
+ * @note 必填
+ */
+@property (nonatomic, copy) NSString *username;
+
+/** 小程序页面的路径
+ * @attention 不填默认拉起小程序首页
+ */
+@property (nonatomic, copy, nullable) NSString *path;
+
+/** 分享小程序的版本
+ * @attention (正式,开发,体验)
+ */
+@property (nonatomic, assign) WXMiniProgramType miniProgramType;
+
+@end
+
+
+
+#pragma mark - WXStateJumpWXMiniProgramInfo
+/*! @brief 状态小尾巴跳转指定视频号主页信息
+ */
+@interface WXStateJumpChannelProfileInfo : WXStateJumpInfo
+/** 视频号username
+ * @note 必填,username长度必须大于0且小于1K
+ */
+@property (nonatomic, copy) NSString *username;
+
+
+@end
+
+#pragma mark - WXStateSceneDataObject
+/*! @brief 场景类型额外参数基类
+ */
+@interface WXSceneDataObject : NSObject
+
+@end
+
+#pragma mark - WXStateSceneDataObject
+/*! @brief 状态场景类型
+ * 用户填写WXStateSceneDataObject参数后,可以跳转到微信状态发表页
+ */
+@interface WXStateSceneDataObject : WXSceneDataObject
+
+/** 状态标志的ID
+ * @note 选填,文本长度必须小于10K
+ */
+@property (nonatomic, copy) NSString *stateId;
+/** 状态发表时附带的文本描述
+ * @note 选填,文本长度必须小于10K
+ */
+@property (nonatomic, copy) NSString *stateTitle;
+/** 后台校验token
+ * @note 选填,文本长度必须小于10K
+ */
+@property (nonatomic, copy) NSString *token;
+/** 小尾巴跳转所需的信息
+ * @note 必填,目前仅支持url跳转
+ */
+@property (nonatomic, strong) WXStateJumpInfo *stateJumpDataInfo;
+
+@end
+
+#pragma mark - SendMessageToWXReq
+/*! @brief 第三方程序发送消息至微信终端程序的消息结构体
+ *
+ * 第三方程序向微信发送信息需要传入SendMessageToWXReq结构体,信息类型包括文本消息和多媒体消息,
+ * 分别对应于text和message成员。调用该方法后,微信处理完信息会向第三方程序发送一个处理结果。
+ * @see SendMessageToWXResp
+ */
+@interface SendMessageToWXReq : BaseReq
+/** 发送消息的文本内容
+ * @note 文本长度必须大于0且小于10K
+ */
+@property (nonatomic, copy) NSString *text;
+/** 发送消息的多媒体内容
+ * @see WXMediaMessage
+ */
+@property (nonatomic, strong) WXMediaMessage *message;
+/** 发送消息的类型,包括文本消息和多媒体消息两种,两者只能选择其一,不能同时发送文本和多媒体消息 */
+@property (nonatomic, assign) BOOL bText;
+/** 发送的目标场景,可以选择发送到会话(WXSceneSession)或者朋友圈(WXSceneTimeline)。 默认发送到会话。
+ * @see WXScene
+ */
+@property (nonatomic, assign) int scene;
+/** 指定发送消息的人
+ * @note WXSceneSpecifiedSession时有效
+ */
+@property (nonatomic, copy, nullable) NSString *toUserOpenId;
+/** 目标场景附带信息
+ * @note 目前只针对状态场景
+ */
+@property (nonatomic, strong) WXSceneDataObject *sceneDataObject;
+
+@end
+
+#pragma mark - SendMessageToWXResp
+/*! @brief 微信终端向第三方程序返回的SendMessageToWXReq处理结果。
+ *
+ * 第三方程序向微信终端发送SendMessageToWXReq后,微信发送回来的处理结果,该结果用SendMessageToWXResp表示。
+ */
+@interface SendMessageToWXResp : BaseResp
+@property(nonatomic, copy) NSString *lang;
+@property(nonatomic, copy) NSString *country;
+@end
+
+#pragma mark - GetMessageFromWXReq
+/*! @brief 微信终端向第三方程序请求提供内容的消息结构体。
+ *
+ * 微信终端向第三方程序请求提供内容,微信终端会向第三方程序发送GetMessageFromWXReq消息结构体,
+ * 需要第三方程序调用sendResp返回一个GetMessageFromWXResp消息结构体。
+ */
+@interface GetMessageFromWXReq : BaseReq
+@property (nonatomic, strong) NSString *lang;
+@property (nonatomic, strong) NSString *country;
+@end
+
+
+
+#pragma mark - GetMessageFromWXResp
+/*! @brief 微信终端向第三方程序请求提供内容,第三方程序向微信终端返回的消息结构体。
+ *
+ * 微信终端向第三方程序请求提供内容,第三方程序调用sendResp向微信终端返回一个GetMessageFromWXResp消息结构体。
+ */
+@interface GetMessageFromWXResp : BaseResp
+/** 向微信终端提供的文本内容
+ @note 文本长度必须大于0且小于10K
+ */
+@property (nonatomic, strong) NSString *text;
+/** 向微信终端提供的多媒体内容。
+ * @see WXMediaMessage
+ */
+@property (nonatomic, strong) WXMediaMessage *message;
+/** 向微信终端提供内容的消息类型,包括文本消息和多媒体消息两种,两者只能选择其一,不能同时发送文本和多媒体消息 */
+@property (nonatomic, assign) BOOL bText;
+@end
+
+
+
+#pragma mark - ShowMessageFromWXReq
+/*! @brief 微信通知第三方程序,要求第三方程序显示的消息结构体。
+ *
+ * 微信需要通知第三方程序显示或处理某些内容时,会向第三方程序发送ShowMessageFromWXReq消息结构体。
+ * 第三方程序处理完内容后调用sendResp向微信终端发送ShowMessageFromWXResp。
+ */
+@interface ShowMessageFromWXReq : BaseReq
+/** 微信终端向第三方程序发送的要求第三方程序处理的多媒体内容
+ * @see WXMediaMessage
+ */
+@property (nonatomic, strong) WXMediaMessage *message;
+@property (nonatomic, copy) NSString *lang;
+@property (nonatomic, copy) NSString *country;
+@end
+
+
+
+#pragma mark - ShowMessageFromWXResp
+/*! @brief 微信通知第三方程序,要求第三方程序显示或处理某些消息,第三方程序处理完后向微信终端发送的处理结果。
+ *
+ * 微信需要通知第三方程序显示或处理某些内容时,会向第三方程序发送ShowMessageFromWXReq消息结构体。
+ * 第三方程序处理完内容后调用sendResp向微信终端发送ShowMessageFromWXResp。
+ */
+@interface ShowMessageFromWXResp : BaseResp
+@end
+
+
+#pragma mark - LaunchFromWXReq
+/*! @brief 微信终端打开第三方程序携带的消息结构体
+ *
+ * 微信向第三方发送的结构体,第三方不需要返回
+ */
+@interface LaunchFromWXReq : BaseReq
+@property (nonatomic, strong) WXMediaMessage *message;
+@property (nonatomic, copy) NSString *lang;
+@property (nonatomic, copy) NSString *country;
+@end
+
+
+#pragma mark - OpenWebviewReq
+/* ! @brief 第三方通知微信启动内部浏览器,打开指定网页
+ *
+ * 第三方通知微信启动内部浏览器,打开指定Url对应的网页
+ */
+@interface OpenWebviewReq : BaseReq
+/** 需要打开的网页对应的Url
+ * @attention 长度不能超过1024
+ */
+@property(nonatomic, copy) NSString *url;
+
+@end
+
+#pragma mark - OpenWebviewResp
+/*! @brief 微信终端向第三方程序返回的OpenWebviewReq处理结果
+ *
+ * 第三方程序向微信终端发送OpenWebviewReq后,微信发送回来的处理结果,该结果用OpenWebviewResp表示
+ */
+@interface OpenWebviewResp : BaseResp
+
+@end
+
+
+
+#pragma mark - WXOpenBusinessWebViewReq
+/*! @brief 第三方通知微信启动内部浏览器,打开指定业务的网页
+ *
+ *
+ */
+@interface WXOpenBusinessWebViewReq : BaseReq
+
+/** 网页业务类型
+ * @attention
+ */
+@property (nonatomic, assign) UInt32 businessType;
+
+/** 网页业务参数
+ * @attention
+ */
+@property (nonatomic, strong, nullable) NSDictionary *queryInfoDic;
+
+@end
+
+#pragma mark - WXOpenBusinessWebViewResp
+/*! @brief 微信终端向第三方程序返回的WXOpenBusinessWebViewResp处理结果。
+ *
+ * 第三方程序向微信终端发送WXOpenBusinessWebViewReq后,微信发送回来的处理结果,该结果用WXOpenBusinessWebViewResp表示。
+ */
+@interface WXOpenBusinessWebViewResp : BaseResp
+/** 第三方程序自定义简单数据,微信终端会回传给第三方程序处理
+ * @attention 长度不能超过2k
+ */
+@property (nonatomic, copy) NSString *result;
+
+/** 网页业务类型
+ * @attention
+ */
+@property (nonatomic, assign) UInt32 businessType;
+
+@end
+
+
+#pragma mark - OpenRankListReq
+/* ! @brief 第三方通知微信,打开硬件排行榜
+ *
+ * 第三方通知微信,打开硬件排行榜
+ */
+@interface OpenRankListReq : BaseReq
+
+@end
+
+#pragma mark - OpenRanklistResp
+/*! @brief 微信终端向第三方程序返回的OpenRankListReq处理结果。
+ *
+ * 第三方程序向微信终端发送OpenRankListReq后,微信发送回来的处理结果,该结果用OpenRankListResp表示。
+ */
+@interface OpenRankListResp : BaseResp
+
+@end
+
+
+#pragma mark - WXCardItem
+
+@interface WXCardItem : NSObject
+/** 卡id
+ * @attention 长度不能超过1024字节
+ */
+@property (nonatomic, copy) NSString *cardId;
+/** ext信息
+ * @attention 长度不能超过2024字节
+ */
+@property (nonatomic, copy, nullable) NSString *extMsg;
+/**
+ * @attention 卡的状态,req不需要填。resp:0为未添加,1为已添加。
+ */
+@property (nonatomic, assign) UInt32 cardState;
+/**
+ * @attention req不需要填,chooseCard返回的。
+ */
+@property (nonatomic, copy) NSString *encryptCode;
+/**
+ * @attention req不需要填,chooseCard返回的。
+ */
+@property (nonatomic, copy) NSString *appID;
+@end;
+
+#pragma mark - WXInvoiceItem
+
+@interface WXInvoiceItem : NSObject
+/** 卡id
+ * @attention 长度不能超过1024字节
+ */
+@property (nonatomic, copy) NSString *cardId;
+/** ext信息
+ * @attention 长度不能超过2024字节
+ */
+@property (nonatomic, copy, nullable) NSString *extMsg;
+/**
+ * @attention 卡的状态,req不需要填。resp:0为未添加,1为已添加。
+ */
+@property (nonatomic, assign) UInt32 cardState;
+/**
+ * @attention req不需要填,chooseCard返回的。
+ */
+@property (nonatomic, copy) NSString *encryptCode;
+/**
+ * @attention req不需要填,chooseCard返回的。
+ */
+@property (nonatomic, copy) NSString *appID;
+
+@end
+
+#pragma mark - AddCardToWXCardPackageReq
+/* ! @brief 请求添加卡券至微信卡包
+ *
+ */
+
+@interface AddCardToWXCardPackageReq : BaseReq
+/** 卡列表
+ * @attention 个数不能超过40个 类型WXCardItem
+ */
+@property (nonatomic, strong) NSArray *cardAry;
+
+@end
+
+
+#pragma mark - AddCardToWXCardPackageResp
+/** ! @brief 微信返回第三方添加卡券结果
+ *
+ */
+
+@interface AddCardToWXCardPackageResp : BaseResp
+/** 卡列表
+ * @attention 个数不能超过40个 类型WXCardItem
+ */
+@property (nonatomic, strong) NSArray *cardAry;
+@end
+
+#pragma mark - WXChooseCardReq
+/* ! @brief 请求从微信选取卡券
+ *
+ */
+
+@interface WXChooseCardReq : BaseReq
+@property (nonatomic, copy) NSString *appID;
+@property (nonatomic, assign) UInt32 shopID;
+@property (nonatomic, assign) UInt32 canMultiSelect;
+@property (nonatomic, copy) NSString *cardType;
+@property (nonatomic, copy) NSString *cardTpID;
+@property (nonatomic, copy) NSString *signType;
+@property (nonatomic, copy) NSString *cardSign;
+@property (nonatomic, assign) UInt32 timeStamp;
+@property (nonatomic, copy) NSString *nonceStr;
+@end
+
+
+#pragma mark - WXChooseCardResp
+/** ! @brief 微信返回第三方请求选择卡券结果
+ *
+ */
+
+@interface WXChooseCardResp : BaseResp
+@property (nonatomic, strong ) NSArray* cardAry;
+@end
+
+
+#pragma mark - WXChooseInvoiceReq
+/* ! @brief 请求从微信选取发票
+ *
+ */
+@interface WXChooseInvoiceReq : BaseReq
+@property (nonatomic, copy) NSString *appID;
+@property (nonatomic, assign) UInt32 shopID;
+@property (nonatomic, copy) NSString *signType;
+@property (nonatomic, copy) NSString *cardSign;
+@property (nonatomic, assign) UInt32 timeStamp;
+@property (nonatomic, copy) NSString *nonceStr;
+@end
+
+#pragma mark - WXChooseInvoiceResp
+/** ! @brief 微信返回第三方请求选择发票结果
+ *
+ */
+@interface WXChooseInvoiceResp : BaseResp
+@property (nonatomic, strong) NSArray* cardAry;
+@end
+
+#pragma mark - WXSubscriptionReq
+@interface WXSubscribeMsgReq : BaseReq
+@property (nonatomic, assign) UInt32 scene;
+@property (nonatomic, copy) NSString *templateId;
+@property (nonatomic, copy, nullable) NSString *reserved;
+@end
+
+#pragma mark - WXSubscriptionReq
+@interface WXSubscribeMsgResp : BaseResp
+
+@property (nonatomic, copy) NSString *templateId;
+@property (nonatomic, assign) UInt32 scene;
+@property (nonatomic, copy) NSString *action;
+@property (nonatomic, copy) NSString *reserved;
+@property (nonatomic, copy, nullable) NSString *openId;
+
+@end
+
+#pragma mark - WXSubscribeMiniProgramMsg
+/** ! @brief 第三方请求订阅小程序消息
+ *
+ */
+@interface WXSubscribeMiniProgramMsgReq : BaseReq
+@property (nonatomic, copy) NSString *miniProgramAppid;
+@end
+
+#pragma mark - WXSubscriptionReq
+@interface WXSubscribeMiniProgramMsgResp : BaseResp
+
+@property(nonatomic, copy) NSString *openId; // 小程序openid
+@property(nonatomic, copy) NSString *unionId; // unionId
+@property(nonatomic, copy) NSString *nickName; // 用户昵称
+
+@end
+
+#pragma mark - WXinvoiceAuthInsertReq
+@interface WXInvoiceAuthInsertReq : BaseReq
+
+@property (nonatomic, copy) NSString *urlString;
+
+@end
+
+#pragma mark - WXinvoiceAuthInsertResp
+
+@interface WXInvoiceAuthInsertResp : BaseResp
+
+@property (nonatomic, copy) NSString *wxOrderId;
+
+@end
+
+#pragma mark - WXMediaMessage
+
+/*! @brief 多媒体消息结构体
+ *
+ * 用于微信终端和第三方程序之间传递消息的多媒体消息内容
+ */
+@interface WXMediaMessage : NSObject
+
++ (WXMediaMessage *)message;
+
+/** 标题
+ * @note 长度不能超过512字节
+ */
+@property (nonatomic, copy) NSString *title;
+/** 描述内容
+ * @note 长度不能超过1K
+ */
+@property (nonatomic, copy) NSString *description;
+/** 缩略图数据
+ * @note 大小不能超过64K
+ */
+@property (nonatomic, strong, nullable) NSData *thumbData;
+/**
+ * @note 长度不能超过64字节
+ */
+@property (nonatomic, copy, nullable) NSString *mediaTagName;
+/**
+ *
+ */
+@property (nonatomic, copy, nullable) NSString *messageExt;
+@property (nonatomic, copy, nullable) NSString *messageAction;
+/**
+ * 多媒体数据对象,可以为WXImageObject,WXMusicObject,WXVideoObject,WXWebpageObject等。
+ */
+@property (nonatomic, strong) id mediaObject;
+
+/** 缩略图的hash值
+ * @note 使用sha256得到,用于计算签名
+ */
+@property (nonatomic, copy, nullable) NSString *thumbDataHash;
+
+/** 消息签名
+ * @note 用于校验消息体是否被篡改过
+ */
+@property (nonatomic, copy, nullable) NSString *msgSignature;
+
+
+/*! @brief 设置消息缩略图的方法
+ *
+ * @param image 缩略图
+ * @note 大小不能超过256K
+ */
+- (void)setThumbImage:(UIImage *)image;
+
+@end
+
+
+
+#pragma mark - WXImageObject
+/*! @brief 多媒体消息中包含的图片数据对象
+ *
+ * 微信终端和第三方程序之间传递消息中包含的图片数据对象。
+ * @note imageData成员不能为空
+ * @see WXMediaMessage
+ */
+@interface WXImageObject : NSObject
+/*! @brief 返回一个WXImageObject对象
+ *
+ * @note 返回的WXImageObject对象是自动释放的
+ */
++ (WXImageObject *)object;
+
+/** 图片真实数据内容
+ * @note 大小不能超过25M
+ */
+@property (nonatomic, strong) NSData *imageData;
+
+/** 图片数据的hash值
+ * @note 使用sha256得到,用于计算签名
+ */
+@property (nonatomic, copy, nullable) NSString *imgDataHash;
+
+/** 分享的图片消息是否要带小程序入口,若 'entranceMiniProgramUsername' 非空则显示
+ * 仅部分小程序类目可用
+ * @note 本字段为空则发送普通app图片消息
+ */
+@property (nonatomic, copy, nullable) NSString *entranceMiniProgramUsername;
+
+/** 分享的图片消息显示的小程序入口可以跳转的小程序路径
+ * 仅当 'entranceMiniProgramUsername' 非空时生效
+ */
+@property (nonatomic, copy, nullable) NSString *entranceMiniProgramPath;
+
+@end
+
+
+#pragma mark - WXMusicObject
+/*! @brief 多媒体消息中包含的音乐数据对象
+ *
+ * 微信终端和第三方程序之间传递消息中包含的音乐数据对象。
+ * @note musicUrl和musicLowBandUrl成员不能同时为空。
+ * @see WXMediaMessage
+ */
+@interface WXMusicObject : NSObject
+/*! @brief 返回一个WXMusicObject对象
+ *
+ * @note 返回的WXMusicObject对象是自动释放的
+ */
++ (WXMusicObject *)object;
+
+/** 音乐网页的url地址
+ * @note 长度不能超过10K
+ */
+@property (nonatomic, copy) NSString *musicUrl;
+/** 音乐lowband网页的url地址
+ * @note 长度不能超过10K
+ */
+@property (nonatomic, copy) NSString *musicLowBandUrl;
+/** 音乐数据url地址
+ * @note 长度不能超过10K
+ */
+@property (nonatomic, copy) NSString *musicDataUrl;
+
+/**音乐lowband数据url地址
+ * @note 长度不能超过10K
+ */
+@property (nonatomic, copy) NSString *musicLowBandDataUrl;
+
+/**音乐封面图Url
+ * @note 长度不能超过10K
+ */
+@property (nonatomic, copy) NSString *songAlbumUrl;
+
+/**歌词信息 LRC格式
+ * @note 长度不能超过32K
+ */
+@property (nonatomic, copy, nullable) NSString *songLyric;
+@end
+
+
+
+#pragma mark - WXMusicVideoObject
+
+@interface WXMusicVipInfo : NSObject
+
+/**付费歌曲的id
+ * @note 长度不能超过32K
+ */
+@property (nonatomic, copy) NSString *musicId;
+
+@end
+
+
+@interface WXMusicVideoObject : NSObject
+
+/*! @brief 返回一个WXMusicVideoObject对象
+ *
+ * @note 返回的WXMusicVideoObject对象是自动释放的
+ */
++ (WXMusicVideoObject *)object;
+
+/** 音乐网页的url地址
+ * @note 长度不能超过10K,不能为空
+ */
+@property (nonatomic, copy) NSString *musicUrl;
+
+/** 音乐数据url地址
+ * @note 长度不能超过10K,不能为空
+ */
+@property (nonatomic, copy) NSString *musicDataUrl;
+
+/**歌手名
+ * @note 长度不能超过1k,不能为空
+ */
+@property (nonatomic, copy) NSString *singerName;
+
+/**
+ * @note 音乐时长, 单位毫秒
+ */
+@property (nonatomic, assign) UInt32 duration;
+
+/**歌词信息 LRC格式
+ * @note 长度不能超过32K
+ */
+@property (nonatomic, copy) NSString *songLyric;
+
+/**高清封面图
+ * @note 大小不能超过1M
+ */
+@property (nonatomic, strong) NSData *hdAlbumThumbData;
+
+/** 高清封面图数据的hash值
+ * @note 使用sha256得到,用于计算签名
+ */
+@property (nonatomic, copy, nullable) NSString *hdAlbumThumbFileHash;
+
+/**音乐专辑名称
+ * @note 长度不能超过1k
+ */
+@property (nonatomic, copy, nullable) NSString *albumName;
+
+/**音乐流派
+ * @note 长度不能超过1k
+ */
+@property (nonatomic, copy, nullable) NSString *musicGenre;
+
+/**发行时间
+ * @note Unix时间戳,单位为秒
+ */
+@property (nonatomic, assign) UInt64 issueDate;
+
+/**音乐标识符
+ * @note 长度不能超过1K,从微信跳回应用时会带上
+ */
+@property (nonatomic, copy, nullable) NSString *identification;
+
+/**运营H5地址
+ * @note 选填,建议填写,用户进入歌曲详情页将展示内嵌的运营H5,可展示该歌曲的相关评论、歌曲推荐等内容,不可诱导下载、分享等。
+ */
+@property (nonatomic, copy, nullable) NSString *musicOperationUrl;
+
+/** 付费歌曲相关信息
+ * @note 选填,如果歌曲是需要付费的,那么将付费歌曲id等信息封装在内。
+ */
+@property (nonatomic, strong) WXMusicVipInfo *musicVipInfo;
+
+@end
+
+
+
+#pragma mark - WXVideoObject
+/*! @brief 多媒体消息中包含的视频数据对象
+ *
+ * 微信终端和第三方程序之间传递消息中包含的视频数据对象。
+ * @note videoUrl和videoLowBandUrl不能同时为空。
+ * @see WXMediaMessage
+ */
+@interface WXVideoObject : NSObject
+/*! @brief 返回一个WXVideoObject对象
+ *
+ * @note 返回的WXVideoObject对象是自动释放的
+ */
++ (WXVideoObject *)object;
+
+/** 视频网页的url地址
+ * @note 长度不能超过10K
+ */
+@property (nonatomic, copy) NSString *videoUrl;
+/** 视频lowband网页的url地址
+ * @note 长度不能超过10K
+ */
+@property (nonatomic, copy) NSString *videoLowBandUrl;
+
+@end
+
+
+
+#pragma mark - WXWebpageObject
+/*! @brief 多媒体消息中包含的网页数据对象
+ *
+ * 微信终端和第三方程序之间传递消息中包含的网页数据对象。
+ * @see WXMediaMessage
+ */
+@interface WXWebpageObject : NSObject
+/*! @brief 返回一个WXWebpageObject对象
+ *
+ * @note 返回的WXWebpageObject对象是自动释放的
+ */
++ (WXWebpageObject *)object;
+
+/** 网页的url地址
+ * @note 不能为空且长度不能超过10K
+ */
+@property (nonatomic, copy) NSString *webpageUrl;
+
+/**是否是私密消息
+ */
+@property (nonatomic, assign) BOOL isSecretMessage;
+
+/** 业务所需的额外信息 */
+@property (nonatomic, strong, nullable) NSDictionary *extraInfoDic;
+
+@end
+
+
+
+#pragma mark - WXAppExtendObject
+/*! @brief 多媒体消息中包含的App扩展数据对象
+ *
+ * 第三方程序向微信终端发送包含WXAppExtendObject的多媒体消息,
+ * 微信需要处理该消息时,会调用该第三方程序来处理多媒体消息内容。
+ * @note url,extInfo和fileData不能同时为空
+ * @see WXMediaMessage
+ */
+@interface WXAppExtendObject : NSObject
+/*! @brief 返回一个WXAppExtendObject对象
+ *
+ * @note 返回的WXAppExtendObject对象是自动释放的
+ */
++ (WXAppExtendObject *)object;
+
+/** 若第三方程序不存在,微信终端会打开该url所指的App下载地址
+ * @note 长度不能超过10K
+ */
+@property (nonatomic, copy) NSString *url;
+/** 第三方程序自定义简单数据,微信终端会回传给第三方程序处理
+ * @note 长度不能超过2K
+ */
+@property (nonatomic, copy, nullable) NSString *extInfo;
+/** App文件数据,该数据发送给微信好友,微信好友需要点击后下载数据,微信终端会回传给第三方程序处理
+ * @note 大小不能超过10M
+ */
+@property (nonatomic, strong, nullable) NSData *fileData;
+
+@end
+
+
+
+#pragma mark - WXEmoticonObject
+/*! @brief 多媒体消息中包含的表情数据对象
+ *
+ * 微信终端和第三方程序之间传递消息中包含的表情数据对象。
+ * @see WXMediaMessage
+ */
+@interface WXEmoticonObject : NSObject
+
+/*! @brief 返回一个WXEmoticonObject对象
+ *
+ * @note 返回的WXEmoticonObject对象是自动释放的
+ */
++ (WXEmoticonObject *)object;
+
+/** 表情真实数据内容
+ * @note 大小不能超过10M
+ */
+@property (nonatomic, strong) NSData *emoticonData;
+
+@end
+
+
+
+#pragma mark - WXFileObject
+/*! @brief 多媒体消息中包含的文件数据对象
+ *
+ * @see WXMediaMessage
+ */
+@interface WXFileObject : NSObject
+
+/*! @brief 返回一个WXFileObject对象
+ *
+ * @note 返回的WXFileObject对象是自动释放的
+ */
++ (WXFileObject *)object;
+
+/** 文件后缀名
+ * @note 长度不超过64字节
+ */
+@property (nonatomic, copy) NSString *fileExtension;
+
+/** 文件真实数据内容
+ * @note 大小不能超过10M
+ */
+@property (nonatomic, strong) NSData *fileData;
+
+@end
+
+
+#pragma mark - WXLocationObject
+/*! @brief 多媒体消息中包含的地理位置数据对象
+ *
+ * 微信终端和第三方程序之间传递消息中包含的地理位置数据对象。
+ * @see WXMediaMessage
+ */
+@interface WXLocationObject : NSObject
+
+/*! @brief 返回一个WXLocationObject对象
+ *
+ * @note 返回的WXLocationObject对象是自动释放的
+ */
++ (WXLocationObject *)object;
+
+/** 地理位置信息
+ * @note 经纬度
+ */
+@property (nonatomic, assign) double lng; //经度
+@property (nonatomic, assign) double lat; //纬度
+
+@end
+
+#pragma mark - WXTextObject
+/*! @brief 多媒体消息中包含的文本数据对象
+ *
+ * 微信终端和第三方程序之间传递消息中包含的文本数据对象。
+ * @see WXMediaMessage
+ */
+@interface WXTextObject : NSObject
+
+/*! @brief 返回一个WXTextObject对象
+ *
+ * @note 返回的WXTextObject对象是自动释放的
+ */
++ (WXTextObject *)object;
+
+/** 地理位置信息
+ * @note 文本内容
+ */
+@property (nonatomic, copy) NSString *contentText;
+
+@end
+
+#pragma mark - WXMiniProgramObject
+
+@interface WXMiniProgramObject : NSObject
+
+/*! @brief WXMiniProgramObject对象
+ *
+ * @note 返回的WXMiniProgramObject对象是自动释放的
+ */
++ (WXMiniProgramObject *)object;
+
+/** 低版本网页链接
+ * @attention 长度不能超过1024字节
+ */
+@property (nonatomic, copy) NSString *webpageUrl;
+
+/** 小程序username */
+@property (nonatomic, copy) NSString *userName;
+
+/** 小程序页面的路径
+ * @attention 不填默认拉起小程序首页
+ */
+@property (nonatomic, copy, nullable) NSString *path;
+
+/** 小程序新版本的预览图
+ * @attention 大小不能超过128k
+ */
+@property (nonatomic, strong, nullable) NSData *hdImageData;
+
+/** 是否使用带 shareTicket 的转发 */
+@property (nonatomic, assign) BOOL withShareTicket;
+
+/** 分享小程序的版本
+ * @attention (正式,开发,体验)
+ */
+@property (nonatomic, assign) WXMiniProgramType miniProgramType;
+
+/** 是否禁用转发 */
+@property (nonatomic, assign) BOOL disableForward;
+
+@property (nonatomic, assign) BOOL isUpdatableMessage;
+
+@property (nonatomic, assign) BOOL isSecretMessage;
+
+
+/** 业务所需的额外信息 */
+@property (nonatomic, strong, nullable) NSDictionary *extraInfoDic;
+
+@end
+
+#pragma mark - WXGameLiveObject
+
+/*! @brief WXGameLiveObject对象
+ *
+ * @note 游戏直播消息类型
+ */
+
+@interface WXGameLiveObject : NSObject
+
++ (WXGameLiveObject *)object;
+
+/** 业务所需的额外信息 */
+@property (nonatomic, strong, nullable) NSDictionary *extraInfoDic;
+
+@end
+
+@interface WXNativeGamePageObject : NSObject
+
+/** 是否为视频类型
+ */
+@property (nonatomic, assign) BOOL isVideo;
+
+/** 视频时长
+ @note 当为视频类型时,必填;单位为秒
+ */
+@property (nonatomic, assign) UInt32 videoDuration;
+
+/** 透传字段
+ @note 长度限制为100K
+ */
+@property (nonatomic, copy) NSString *shareData;
+
+/** 缩略图
+ @note 大小限制为256K
+ */
+@property (nonatomic, strong) NSData *gameThumbData;
+
++ (WXNativeGamePageObject *)object;
+
+@end
+
+#pragma mark - WXLaunchMiniProgramReq
+
+/*! @brief WXLaunchMiniProgramReq对象, 可实现通过sdk拉起微信小程序
+ *
+ * @note 返回的WXLaunchMiniProgramReq对象是自动释放的
+ */
+@interface WXLaunchMiniProgramReq : BaseReq
+
++ (WXLaunchMiniProgramReq *)object;
+
+/** 小程序username */
+@property (nonatomic, copy) NSString *userName;
+
+/** 小程序页面的路径
+ * @attention 不填默认拉起小程序首页
+ */
+@property (nonatomic, copy, nullable) NSString *path;
+
+/** 分享小程序的版本
+ * @attention (正式,开发,体验)
+ */
+@property (nonatomic, assign) WXMiniProgramType miniProgramType;
+
+/** ext信息
+ * @attention json格式
+ */
+@property (nonatomic, copy, nullable) NSString *extMsg;
+
+/** extDic
+ * @attention 字典,可存放图片等比较大的数据
+ */
+@property (nonatomic, copy, nullable) NSDictionary *extDic;
+
+@end
+
+#pragma mark - WXLaunchMiniProgramResp
+/*! @brief 微信终端向第三方程序返回的WXLaunchMiniProgramReq处理结果。
+ *
+ * 第三方程序向微信终端发送WXLaunchMiniProgramReq后,微信发送回来的处理结果,该结果用WXLaunchMiniProgramResp表示。
+ */
+@interface WXLaunchMiniProgramResp : BaseResp
+
+@property (nonatomic, copy, nullable) NSString *extMsg;
+
+@end
+
+
+#pragma mark - WXOpenBusinessViewReq
+/*! @brief WXOpenBusinessViewReq对象, 可实现第三方通知微信启动,打开业务页面
+ *
+ * @note 返回的WXOpenBusinessViewReq对象是自动释放的
+ */
+
+@interface WXOpenBusinessViewReq : BaseReq
+
++ (WXOpenBusinessViewReq *)object;
+
+/** 业务类型
+ */
+@property (nonatomic, copy) NSString *businessType;
+
+/** 业务参数
+ */
+@property (nonatomic, copy, nullable) NSString *query;
+
+/** ext信息
+ * @note 选填,json格式
+ */
+@property (nonatomic, copy, nullable) NSString *extInfo;
+
+/** extData数据
+ * @note
+ */
+@property (nonatomic, strong, nullable) NSData *extData;
+@end
+
+
+@interface WXOpenBusinessViewResp : BaseResp
+
+/** 业务类型
+ */
+@property (nonatomic, copy) NSString *businessType;
+
+/** 业务返回数据
+ */
+@property (nonatomic, copy, nullable) NSString *extMsg;
+
+@end
+
+#pragma mark - WXOpenCustomerServiceReq
+@interface WXOpenCustomerServiceReq : BaseReq
+
++ (WXOpenCustomerServiceReq *)object;
+
+/**企微客服发起流程 url
+ */
+@property (nonatomic, copy, nullable) NSString *url;
+
+/**企业 id
+ */
+@property (nonatomic, copy, nullable) NSString *corpid;
+
+@end
+
+@interface WXOpenCustomerServiceResp : BaseResp
+
+/** 业务返回数据
+ */
+@property (nonatomic, copy, nullable) NSString *extMsg;
+
+@end
+
+
+#pragma mark - WXChannelStartLiveReq
+
+@interface WXChannelStartLiveReq : BaseReq
+
++ (WXChannelStartLiveReq *)object;
+
+/** 必填,直播业务数据(json格式)
+ */
+@property (nonatomic, copy) NSString *liveJsonInfo;
+
+@end
+
+@interface WXChannelStartLiveResp : BaseResp
+
+/** 业务返回数据
+ */
+@property (nonatomic, copy, nullable) NSString *extMsg;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/Headers/WechatAuthSDK.h b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/Headers/WechatAuthSDK.h
new file mode 100644
index 00000000..308aaea1
--- /dev/null
+++ b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/Headers/WechatAuthSDK.h
@@ -0,0 +1,68 @@
+//
+// WechatAuthSDK.h
+// WechatAuthSDK
+//
+// Created by 李凯 on 13-11-29.
+// Copyright (c) 2013年 Tencent. All rights reserved.
+//
+
+#import
+#import
+
+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
+@optional
+
+- (void)onAuthGotQrcode:(UIImage *)image; //得到二维码
+- (void)onQrcodeScanned; //二维码被扫描
+- (void)onAuthFinish:(int)errCode AuthCode:(nullable NSString *)authCode; //成功登录
+
+@end
+
+@interface WechatAuthSDK : NSObject{
+ NSString *_sdkVersion;
+ __weak id _delegate;
+}
+
+@property(nonatomic, weak, nullable) id 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
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/Headers/WechatOpenSDK.h b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/Headers/WechatOpenSDK.h
new file mode 100644
index 00000000..979e5e99
--- /dev/null
+++ b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/Headers/WechatOpenSDK.h
@@ -0,0 +1,9 @@
+// WechatOpenSDK.h
+//
+// Created by Wechat.
+// Copyright (c) 2012年 Tencent. All rights reserved.
+//
+#import
+#import
+#import
+
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/Info.plist b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/Info.plist
new file mode 100755
index 00000000..45d60687
--- /dev/null
+++ b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/Info.plist
@@ -0,0 +1,15 @@
+
+
+
+ CFBundleIdentifier
+ com.tencent.WechatOpenSDK
+ CFBundleVersion
+ 1.0.0
+ CFBundleShortVersionString
+ 1.0
+ MinimumOSVersion
+ 12.0
+ CFBundleExecutable
+ WechatOpenSDK
+
+
\ No newline at end of file
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/Modules/module.modulemap b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/Modules/module.modulemap
new file mode 100644
index 00000000..3ddbeb0b
--- /dev/null
+++ b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/Modules/module.modulemap
@@ -0,0 +1,5 @@
+framework module WechatOpenSDK {
+ umbrella header "WechatOpenSDK.h"
+ export *
+ link "WechatOpenSDK"
+}
diff --git a/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/WechatOpenSDK b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/WechatOpenSDK
new file mode 100644
index 00000000..415bd55e
Binary files /dev/null and b/iosApp/Vendor/WechatOpenSDK-XCFramework/2.0.5/WechatOpenSDK.xcframework/ios-arm64_x86_64-simulator/WechatOpenSDK.framework/WechatOpenSDK differ
diff --git a/iosApp/wxpusher/Page/Main/MainTabBarController.swift b/iosApp/wxpusher/Page/Main/MainTabBarController.swift
index e6e6bd0b..4725657e 100644
--- a/iosApp/wxpusher/Page/Main/MainTabBarController.swift
+++ b/iosApp/wxpusher/Page/Main/MainTabBarController.swift
@@ -21,6 +21,7 @@ class MainTabBarController: UITabBarController {
setupViewControllers()
// setupAppearance()
+ setupKvListener()
notificationPermissionRemind()
setupListenBackToRegisterAPNs()
@@ -28,35 +29,114 @@ class MainTabBarController: UITabBarController {
}
+ //底部 tab 类型
+ private enum MainTab { case messageList, market, extFunc, profile }
+
+ //已应用的 tab 配置快照,用于 diff:仅变化才重建
+ private var appliedTabConfig: WxpTabConfig?
+ //tab 导航控制器缓存:重建时复用已存在实例,保留其导航栈与状态(关键:不打断压栈中的配置页)
+ private var tabControllerCache: [MainTab: UINavigationController] = [:]
+ //KV 变更监听 id(保存即广播机制)
+ private var kvListenerId: Int32 = -1
+
+ //按配置构建有序 tab:消息列表(必) → 消息市场(可配) → 扩展功能(可配) → 我的(必)
+ private func currentTabs(_ config: WxpTabConfig) -> [MainTab] {
+ var tabs: [MainTab] = [.messageList]
+ if config.market {
+ tabs.append(.market)
+ }
+ if config.extFunc {
+ tabs.append(.extFunc)
+ }
+ tabs.append(.profile)
+ return tabs
+ }
+
+ private func makeTabNavController(_ tab: MainTab) -> UINavigationController {
+ let vc: UIViewController
+ let item: UITabBarItem
+ switch tab {
+ case .messageList:
+ vc = MessageListViewController()
+ item = UITabBarItem(title: "消息列表",
+ image: UIImage(systemName: "paperplane"),
+ selectedImage: UIImage(systemName: "paperplane.fill"))
+ case .market:
+ vc = WxpProviderListViewController()
+ item = UITabBarItem(title: "消息市场",
+ image: UIImage(systemName: "cloud"),
+ selectedImage: UIImage(systemName: "cloud.fill"))
+ case .extFunc:
+ vc = WxpExtFuncViewController()
+ item = UITabBarItem(title: "扩展功能",
+ image: UIImage(systemName: "square.grid.2x2"),
+ selectedImage: UIImage(systemName: "square.grid.2x2.fill"))
+ case .profile:
+ vc = WxpProfileViewController()
+ item = UITabBarItem(title: "我的",
+ image: UIImage(systemName: "person"),
+ selectedImage: UIImage(systemName: "person.fill"))
+ }
+ vc.tabBarItem = item
+ return UINavigationController(rootViewController: vc)
+ }
+
+ //取缓存的导航控制器,没有则新建并缓存
+ private func navController(for tab: MainTab) -> UINavigationController {
+ if let cached = tabControllerCache[tab] {
+ return cached
+ }
+ let nav = makeTabNavController(tab)
+ tabControllerCache[tab] = nav
+ return nav
+ }
+
private func setupViewControllers() {
- let messageListVC = MessageListViewController()
- let providerListVC = WxpProviderListViewController()
- let profileVC = WxpProfileViewController()
- // 创建导航控制器
- messageListVC.tabBarItem = UITabBarItem(
- title: "消息列表",
- image: UIImage(systemName: "paperplane"),
- selectedImage: UIImage(systemName: "paperplane.fill")
- )
- providerListVC.tabBarItem = UITabBarItem(
- title: "消息市场",
- image: UIImage(systemName: "cloud"),
- selectedImage: UIImage(systemName: "cloud.fill")
- )
- profileVC.tabBarItem = UITabBarItem(
- title: "我的",
- image: UIImage(systemName: "person"),
- selectedImage: UIImage(systemName: "person.fill")
- )
-
- // 设置视图控制器数组
- let controllers = [UINavigationController(rootViewController: messageListVC),
- UINavigationController(rootViewController: providerListVC),
- UINavigationController(rootViewController: profileVC)]
-
- self.viewControllers = controllers
- self.title = controllers[self.selectedIndex].title
-
+ applyTabs(WxpTabConfigStore.shared.read(), initial: true)
+ }
+
+ //增量重建:复用已存在的 tab 实例,只新增/移除变化的 tab,按 tab 身份保持选中项。
+ //复用当前 tab 的导航控制器 → 其已压栈的配置页得以保留,保存即重建时用户无感。
+ private func applyTabs(_ config: WxpTabConfig, initial: Bool) {
+ let oldTabs = appliedTabConfig.map { currentTabs($0) } ?? []
+ let selectedTab: MainTab? = (!initial && selectedIndex >= 0 && selectedIndex < oldTabs.count)
+ ? oldTabs[selectedIndex] : nil
+ appliedTabConfig = config
+ let newTabs = currentTabs(config)
+ //丢弃已移除 tab 的缓存实例
+ for tab in tabControllerCache.keys where !newTabs.contains(tab) {
+ tabControllerCache.removeValue(forKey: tab)
+ }
+ self.viewControllers = newTabs.map { navController(for: $0) }
+ //恢复到原来所在 tab;若该 tab 已被隐藏,回落到消息列表
+ if let sel = selectedTab, let idx = newTabs.firstIndex(of: sel) {
+ selectedIndex = idx
+ } else if !initial {
+ selectedIndex = 0
+ }
+ self.title = viewControllers?[selectedIndex].title
+ }
+
+ //注册 KV 变更监听(保存即广播):tab_config 变化即增量重建,未变不动。
+ //回调已由共享层 runAtMainSuspend 切到主线程。
+ private func setupKvListener() {
+ kvListenerId = WxpSaveService.shared.addListener(listener: { [weak self] key in
+ guard let self = self, key == "tab_config" else {
+ return
+ }
+ self.refreshTabsIfConfigChanged()
+ })
+ }
+
+ private func refreshTabsIfConfigChanged() {
+ guard let applied = appliedTabConfig else {
+ return
+ }
+ let latest = WxpTabConfigStore.shared.read()
+ if applied.market == latest.market && applied.extFunc == latest.extFunc {
+ return
+ }
+ applyTabs(latest, initial: false)
}
//没有权限的异常提醒
@@ -107,6 +187,9 @@ class MainTabBarController: UITabBarController {
deinit {
NotificationCenter.default.removeObserver(self)
+ if kvListenerId >= 0 {
+ WxpSaveService.shared.removeListener(id: kvListenerId)
+ }
}
// private func setupAppearance() {
@@ -149,4 +232,47 @@ class MainTabBarController: UITabBarController {
// func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
// tabBarController.title = viewController.title
// }
-//}
+//}
+
+/// 扩展功能 tab —— 原生 WebView 容器加载 app-fe 的九宫格入口页。
+/// 与消息市场 tab(WxpProviderListViewController)结构一致。
+class WxpExtFuncViewController: WxpWebViewController {
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ view.backgroundColor = .systemBackground
+ title = "扩展功能"
+ // 默认隐藏底部 webview 操作栏:父类首次 applyWebMenuVisibility 时 url 还是 nil 会默认显示,
+ // 直到网页加载/H5 异步 setWebBottomBarVisible(false) 才隐藏,造成打开瞬间闪烁。这里提前置为隐藏。
+ setBottomBarVisibleOverride(false)
+ loadPage()
+ }
+
+ private var pageUrl: String {
+ return "\(WxpConfig.shared.appFeUrl)/app/#/ext-func"
+ }
+
+ //覆盖为空,避免网页标题改变影响 tab 标题
+ override func setPageTitle(title: String) {
+ }
+
+ override func updateWebOptionBtnStatus() {
+ super.updateWebOptionBtnStatus()
+ closeButton.isEnabled = webView?.canGoBack ?? false
+ }
+
+ override func getLastBtnIcon() -> String {
+ return "house"
+ }
+
+ @objc func loadPage() {
+ guard let url = URL(string: pageUrl) else {
+ return
+ }
+ webView?.load(URLRequest(url: url))
+ }
+
+ @objc override func closeButtonTapped() {
+ loadPage()
+ }
+}
diff --git a/iosApp/wxpusher/Page/Profile/WxpProfileViewController.swift b/iosApp/wxpusher/Page/Profile/WxpProfileViewController.swift
index a5fe2f0a..2cf89b08 100644
--- a/iosApp/wxpusher/Page/Profile/WxpProfileViewController.swift
+++ b/iosApp/wxpusher/Page/Profile/WxpProfileViewController.swift
@@ -150,6 +150,10 @@ class WxpProfileViewController: UIViewController {
]),
("通用", [
+ ProfileItem(title: "底部标签设置", subtitle: "自定义底部导航标签的显示",
+ accessoryType: .disclosureIndicator) {
+ WxpJumpPageUtils.jumpToWebUrl(url: "\(WxpConfig.shared.appFeUrl)/app/#/tab-setting")
+ },
ProfileItem(title: "反馈建议", subtitle: "欢迎你指导我们进步",
accessoryType: .disclosureIndicator) {
WxpJumpPageUtils.jumpToWebUrl(url: "https://wj.qq.com/s2/22198188/cc95/")
diff --git a/iosApp/wxpusher/Page/ProviderList/WxpProviderListViewController.swift b/iosApp/wxpusher/Page/ProviderList/WxpProviderListViewController.swift
index 8377daf5..4b805347 100644
--- a/iosApp/wxpusher/Page/ProviderList/WxpProviderListViewController.swift
+++ b/iosApp/wxpusher/Page/ProviderList/WxpProviderListViewController.swift
@@ -15,9 +15,12 @@ class WxpProviderListViewController: WxpWebViewController,IWxpProviderListView {
view.backgroundColor = .systemBackground
title = "消息市场"
presenter = createPresenter() as? any IWxpProviderListPresenter
-
+ // 默认隐藏底部 webview 操作栏:首次 applyWebMenuVisibility 时 url 为 nil 会默认显示,
+ // 直到网页加载/H5 异步 setWebBottomBarVisible(false) 才隐藏,造成打开瞬间闪烁。这里提前置为隐藏。
+ setBottomBarVisibleOverride(false)
+
showOption()
-
+
presenter?.loadPage()
}
diff --git a/iosApp/wxpusher/Page/WebView/bridge/WxpWebBridgeManager.swift b/iosApp/wxpusher/Page/WebView/bridge/WxpWebBridgeManager.swift
index c1e4da01..cfa9e46a 100644
--- a/iosApp/wxpusher/Page/WebView/bridge/WxpWebBridgeManager.swift
+++ b/iosApp/wxpusher/Page/WebView/bridge/WxpWebBridgeManager.swift
@@ -35,6 +35,8 @@ final class WxpWebBridgeManager {
registerHandler(action: "setWebOptionMenu", requiresWhitelist: true, handler: WxpSetWebOptionMenuBridgeHandler())
registerHandler(action: "setWebBottomBar", requiresWhitelist: true, handler: WxpSetWebBottomBarBridgeHandler())
registerHandler(action: "closeWebPage", requiresWhitelist: true, handler: WxpCloseWebPageBridgeHandler())
+ registerHandler(action: "getByKey", requiresWhitelist: true, handler: WxpGetByKeyBridgeHandler())
+ registerHandler(action: "setKeyValue", requiresWhitelist: true, handler: WxpSetKeyValueBridgeHandler())
}
private func registerHandler(action: String, requiresWhitelist: Bool, handler: WxpBridgeActionHandler) {
@@ -63,3 +65,32 @@ final class WxpWebBridgeManager {
return WxpWebHostPolicy.shared.isHostInWhitelist(host: host)
}
}
+
+/// 通用存储读取。直接读 WxpSaveService(原生与 H5 同一 key 空间,无前缀),空值视为不存在返回空 data。
+final class WxpGetByKeyBridgeHandler: WxpBridgeActionHandler {
+ func handle(request: WxpBridgeRequest, context: WxpBridgeContext, emitter: WxpBridgeEmitter) {
+ guard let key = request.data["key"] as? String, !key.isEmpty else {
+ emitter.sendBridgeCallback(callbackId: request.callbackId, response: .fail("key is empty"))
+ return
+ }
+ let value = WxpSaveService.shared.getStringValue(key: key, defaultValue: "")
+ if value.isEmpty {
+ emitter.sendBridgeCallback(callbackId: request.callbackId, response: .ok([:]))
+ } else {
+ emitter.sendBridgeCallback(callbackId: request.callbackId, response: .ok(["value": value]))
+ }
+ }
+}
+
+/// 通用存储写入。直接写 WxpSaveService(原生与 H5 同一 key 空间,无前缀);安全由桥 requiresWhitelist 保证。
+final class WxpSetKeyValueBridgeHandler: WxpBridgeActionHandler {
+ func handle(request: WxpBridgeRequest, context: WxpBridgeContext, emitter: WxpBridgeEmitter) {
+ guard let key = request.data["key"] as? String, !key.isEmpty else {
+ emitter.sendBridgeCallback(callbackId: request.callbackId, response: .fail("key is empty"))
+ return
+ }
+ let value = request.data["value"] as? String ?? ""
+ WxpSaveService.shared.setStringValue(key: key, value: value)
+ emitter.sendBridgeCallback(callbackId: request.callbackId, response: .ok())
+ }
+}
diff --git a/iosApp/wxpusher/wxpusher.xcodeproj/project.pbxproj b/iosApp/wxpusher/wxpusher.xcodeproj/project.pbxproj
index 6eb2d655..138a48d6 100644
--- a/iosApp/wxpusher/wxpusher.xcodeproj/project.pbxproj
+++ b/iosApp/wxpusher/wxpusher.xcodeproj/project.pbxproj
@@ -894,7 +894,7 @@
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 11.0;
- MARKETING_VERSION = 1.7.50;
+ MARKETING_VERSION = 1.8.12;
PRODUCT_BUNDLE_IDENTIFIER = com.smjcco.wxpusher;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -945,7 +945,7 @@
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 11.0;
- MARKETING_VERSION = 1.7.50;
+ MARKETING_VERSION = 1.8.12;
PRODUCT_BUNDLE_IDENTIFIER = com.smjcco.wxpusher;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
diff --git a/shared/src/commonMain/kotlin/com/smjcco/wxpusher/base/common/WxpSaveService.kt b/shared/src/commonMain/kotlin/com/smjcco/wxpusher/base/common/WxpSaveService.kt
index 8c7e569b..b25d1bfc 100644
--- a/shared/src/commonMain/kotlin/com/smjcco/wxpusher/base/common/WxpSaveService.kt
+++ b/shared/src/commonMain/kotlin/com/smjcco/wxpusher/base/common/WxpSaveService.kt
@@ -11,10 +11,16 @@ expect fun ExpWxpSaveService_remove(key: String)
expect fun ExpWxpSaveService_init()
/**
- * 数据存储服务,提供基础的数据持久化存储
+ * 数据存储服务,提供基础的数据持久化存储。
+ * 原生与 H5(通过桥 getByKey/setKeyValue)共享同一份存储、同一 key 空间。
+ *
+ * 内置变更观察者:任意 set 写入后按 key 通知 listener(主线程回调),供底部 tab 显隐等场景订阅。
*/
object WxpSaveService {
+ private val listeners = mutableMapOf Unit>()
+ private var nextListenerId = 0
+
fun init() {
ExpWxpSaveService_init()
}
@@ -25,6 +31,7 @@ object WxpSaveService {
fun set(key: String, value: String?) {
ExpWxpSaveService_set(key, value)
+ notifyChanged(key)
}
fun get(key: String, value: Boolean): Boolean {
@@ -36,7 +43,7 @@ object WxpSaveService {
}
fun set(key: String, value: Boolean) {
- ExpWxpSaveService_set(key, value.toString())
+ set(key, value.toString())
}
fun get(key: String, value: Int): Int {
@@ -48,7 +55,7 @@ object WxpSaveService {
}
fun set(key: String, value: Int) {
- ExpWxpSaveService_set(key, value.toString())
+ set(key, value.toString())
}
fun get(key: String, value: Double): Double {
@@ -57,7 +64,41 @@ object WxpSaveService {
fun set(key: String, value: Double) {
ExpWxpSaveService_setDouble(key, value)
+ notifyChanged(key)
+ }
+
+ /**
+ * 无重载歧义的字符串读写:供 iOS 桥等 ObjC/Swift 互操作场景直接调用。
+ * get/set 的 String/Boolean/Int/Double 多个重载导出到 Swift 后,"干净"的 get(key:value:)/set(key:value:)
+ * 选择器被分配给 Bool 重载,直接用 String 参数会编译报错,故提供唯一命名的别名。
+ */
+ fun getStringValue(key: String, defaultValue: String): String = get(key, defaultValue)
+
+ fun setStringValue(key: String, value: String?) = set(key, value)
+
+ /**
+ * 注册存储变更监听,返回用于注销的 id。须在主线程调用;回调在主线程执行,参数为变更的 key。
+ */
+ fun addListener(listener: (String) -> Unit): Int {
+ val id = nextListenerId++
+ listeners[id] = listener
+ return id
+ }
+ fun removeListener(id: Int) {
+ listeners.remove(id)
}
-}
\ No newline at end of file
+ private fun notifyChanged(key: String) {
+ // 无 listener 时零开销(早期 init 也走这里,安全跳过)
+ if (listeners.isEmpty()) {
+ return
+ }
+ // 切主线程回调:注册/注销/通知都在主线程访问 listeners,无需锁(commonMain 无 @Synchronized)
+ runAtMainSuspend {
+ if (listeners.isNotEmpty()) {
+ listeners.values.toList().forEach { it(key) }
+ }
+ }
+ }
+}
diff --git a/shared/src/commonMain/kotlin/com/smjcco/wxpusher/biz/tab/WxpTabConfig.kt b/shared/src/commonMain/kotlin/com/smjcco/wxpusher/biz/tab/WxpTabConfig.kt
new file mode 100644
index 00000000..cd1cfada
--- /dev/null
+++ b/shared/src/commonMain/kotlin/com/smjcco/wxpusher/biz/tab/WxpTabConfig.kt
@@ -0,0 +1,36 @@
+package com.smjcco.wxpusher.biz.tab
+
+import com.smjcco.wxpusher.base.common.WxpSaveService
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.json.JsonIgnoreUnknownKeys
+
+/**
+ * 底部 tab 显隐配置。「消息列表」「我的」为核心 tab 恒显示,此处仅管理两个可配置 tab。
+ * 与 H5(app-fe common/TabConfig.ts)约定同一份 JSON 结构,缺省全部显示。
+ */
+@Serializable
+@JsonIgnoreUnknownKeys
+data class WxpTabConfig(
+ // 消息市场
+ val market: Boolean = true,
+ // 扩展功能
+ val extFunc: Boolean = true
+)
+
+object WxpTabConfigStore {
+ // 与 H5 约定的存储 key(原生与 H5 共享同一 WxpSaveService,无前缀)
+ const val TAB_CONFIG_KEY = "tab_config"
+
+ fun read(): WxpTabConfig {
+ val raw = WxpSaveService.get(TAB_CONFIG_KEY, "")
+ if (raw.isEmpty()) {
+ return WxpTabConfig()
+ }
+ return try {
+ Json.decodeFromString(raw)
+ } catch (e: Exception) {
+ WxpTabConfig()
+ }
+ }
+}
diff --git a/shared/src/commonMain/kotlin/com/smjcco/wxpusher/page/providerlist/WxpProviderListPresenter.kt b/shared/src/commonMain/kotlin/com/smjcco/wxpusher/page/providerlist/WxpProviderListPresenter.kt
index ea8230fa..b2fd96eb 100644
--- a/shared/src/commonMain/kotlin/com/smjcco/wxpusher/page/providerlist/WxpProviderListPresenter.kt
+++ b/shared/src/commonMain/kotlin/com/smjcco/wxpusher/page/providerlist/WxpProviderListPresenter.kt
@@ -23,7 +23,7 @@ class WxpProviderListPresenter(view: IWxpProviderListView) :
WxpToastUtils.showToast("获取openId失败,请重试")
return@runAtMainSuspend
}
- view?.onLoadPage("${WxpConfig.appFeUrl}/app#/market")
+ view?.onLoadPage("${WxpConfig.appFeUrl}/app/#/market")
}
}
-}
\ No newline at end of file
+}