按 msext gameController.m:575-597 / SharePanel.m 模式落地分享框架。
新增 Source/Share/:
- SharePlatform.swift:
* SharePlatform 协议(name / isInstalled / share async → ShareResult)
* ShareContent struct(nonisolated Sendable,6 字段 sharefriend/sharetype/
type/webpageUrl/title/desc)
* ShareResult enum (success / cancelled / notInstalled / failed)
* ShareScene enum (friend / timeline)
- SharePanel.swift:
* @MainActor UIView,半透明黑底覆盖全屏 + 底部圆角内容视图滑入
* 三按钮(微信绿 / QQ 蓝 / 抖音黑)+ label 等间距居中布局
* 已安装平台按钮高亮,未装置灰
* 点击空白区 dismiss + completion(.cancelled)
* 点击按钮 dismiss + 触发对应 SharePlatform.share + completion(result)
* 0.25s 滑入/滑出动画
* 与 msext SharePanel.m 等价行为
- ShareCenter.swift:
* sharefriend == "1" → SharePanel.show 三选一
* sharefriend == "2" → WechatShare.share scene: .timeline 朋友圈
* 与 msext gameController.m:585 行为 1:1
- WechatShare.swift:stub(Phase 4.E 等微信 SDK 接入)
- QQShare.swift:stub + canOpenURL("mqqapi://") 检测(Phase 4.C 升级
URL Scheme 真实调起)
- DouyinShare.swift:stub + canOpenURL("snssdk1128://") 检测(Phase 4.D 升级
URL Scheme + Photos)
FriendsShareHandler 升级:
- 入参解析为 ShareContent
- 调 ShareCenter.dispatch
- completion 内根据 result 触发 sharesuccess 反向 callback:
* success / cancelled → bridge.call("sharesuccess", {success:"2", type:sharefriend})
* notInstalled / failed → 不发(H5 业务期 timeout 后自行 fallback,msext 乐观策略)
ShareContent 标 nonisolated 解 Swift 6 actor 隔离(项目默认 MainActor isolation
让 struct 跨 actor 受限)。
BuildProject 通过
Plan §5 Phase 4.2 勾选
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
71 lines
2.4 KiB
Swift
71 lines
2.4 KiB
Swift
//
|
||
// SharePlatform.swift
|
||
// ylgamehall
|
||
//
|
||
// 分享平台抽象 + ShareContent 数据载荷 + ShareResult。
|
||
//
|
||
// 策略模式:微信 / QQ / 抖音 各自实现 SharePlatform 协议,由 ShareCenter
|
||
// 按 sharefriend / 用户选择分发。新增平台只加一个 conformance。
|
||
//
|
||
// 详见 docs/H5-Native-Implementation-Design.md §8.2 ShareKit。
|
||
//
|
||
|
||
import Foundation
|
||
import UIKit
|
||
|
||
/// 分享内容(H5 → Native 桥的 friendsShare 参数解析后的 Swift 类型)。
|
||
/// 项目默认 SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor 让 struct 也跨 actor 受限;
|
||
/// 标 nonisolated 让 handler 闭包(@Sendable async)可自由构造与传递。
|
||
nonisolated public struct ShareContent: Sendable {
|
||
/// 分享给好友("1")还是朋友圈("2")
|
||
public let sharefriend: String
|
||
/// msext 旧描述:1 微信 / 2 微信 / 3 闲聊。新代码读了但不用(SharePanel 由用户选平台决定)。
|
||
/// 保留字段以维持契约 §3.1 [2]兼容性
|
||
public let sharetype: String
|
||
/// 1 链接 / 2 截图 / 其他=远端图 URL 分享
|
||
public let type: String
|
||
/// 链接 URL 或图片 URL
|
||
public let webpageUrl: String
|
||
public let title: String
|
||
public let desc: String
|
||
|
||
public init(
|
||
sharefriend: String,
|
||
sharetype: String,
|
||
type: String,
|
||
webpageUrl: String,
|
||
title: String,
|
||
desc: String
|
||
) {
|
||
self.sharefriend = sharefriend
|
||
self.sharetype = sharetype
|
||
self.type = type
|
||
self.webpageUrl = webpageUrl
|
||
self.title = title
|
||
self.desc = desc
|
||
}
|
||
}
|
||
|
||
public enum ShareResult: Sendable {
|
||
case success
|
||
case cancelled
|
||
case notInstalled(platform: String)
|
||
case failed(reason: String)
|
||
}
|
||
|
||
/// 分享场景:好友 / 朋友圈(仅微信有意义;QQ / 抖音 暂不区分)。
|
||
public enum ShareScene: Sendable {
|
||
case friend // 微信好友 / QQ 好友
|
||
case timeline // 微信朋友圈 / QQ 空间
|
||
}
|
||
|
||
@MainActor
|
||
public protocol SharePlatform: AnyObject {
|
||
/// 平台唯一标识(用于 log / 错误提示)
|
||
var name: String { get }
|
||
/// 平台 app 是否已安装(用于 SharePanel 按钮置灰)
|
||
var isInstalled: Bool { get }
|
||
/// 执行分享(按 content.type 路由到链接 / 截图 / 远端图)
|
||
func share(_ content: ShareContent, scene: ShareScene) async -> ShareResult
|
||
}
|