4.B QQ 链接分享补 previewimageUrl:用 app icon 当缩略图
QQ 会话里链接分享的缩略图位空白,因为 News 类型缺 previewimageUrl 字段。 对齐 msext QQShareManager.m:517-522 + 1271-1278 的写法: 1. app icon JPEG 0.7 写到 NSTemporaryDirectory()/qq_share_<UUID>.jpg 2. 拼 file://<path> 字符串 3. base64 后再 URL-encode 4. append &previewimageUrl=<那串> writeAppIconToTemp() 与 appIconImage() 直接抄 WechatShare 同源策略(读 Info.plist CFBundleIcons → CFBundlePrimaryIcon → CFBundleIconFiles 最后 一个)。两处复制可接受 —— Share 模块统一缩略图工具可后续抽到 ImageProvider,本次保持改动范围最小。
This commit is contained in:
@@ -114,6 +114,13 @@ public final class QQShare: SharePlatform {
|
||||
parts.append("url=\(Self.encode(Self.base64(content.webpageUrl)))")
|
||||
}
|
||||
|
||||
// 3. 缩略图 —— app icon 写到 tmp 目录 → previewimageUrl = urlenc(base64("file://<path>"))
|
||||
// 对齐 msext QQShareManager.m:517-522 saveImageToTempDirectory + base64
|
||||
if let thumbPath = Self.writeAppIconToTemp() {
|
||||
let fileURL = "file://\(thumbPath)"
|
||||
parts.append("previewimageUrl=\(Self.encode(Self.base64(fileURL)))")
|
||||
}
|
||||
|
||||
let urlString = "mqqapi://\(host)?\(parts.joined(separator: "&"))"
|
||||
Self.log.debug("QQShare URL → \(urlString, privacy: .public)")
|
||||
|
||||
@@ -184,6 +191,38 @@ public final class QQShare: SharePlatform {
|
||||
return top
|
||||
}
|
||||
|
||||
// MARK: - 缩略图(app icon → tmp file)
|
||||
|
||||
/// 把 app icon JPEG 写到 NSTemporaryDirectory,返回绝对路径。
|
||||
/// 对齐 msext QQShareManager.m:1271-1278 saveImageToTempDirectory:
|
||||
/// 文件名 qq_share_<UUID>.jpg,JPEG 0.7 质量。失败返回 nil。
|
||||
private static func writeAppIconToTemp() -> String? {
|
||||
guard let data = appIconImage().jpegData(compressionQuality: 0.7) else { return nil }
|
||||
let path = NSTemporaryDirectory() + "qq_share_\(UUID().uuidString).jpg"
|
||||
do {
|
||||
try data.write(to: URL(fileURLWithPath: path), options: .atomic)
|
||||
return path
|
||||
} catch {
|
||||
log.error("QQShare 写缩略图临时文件失败 \(error.localizedDescription, privacy: .public)")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
/// app icon UIImage,与 WechatShare.appIconImage() 同源策略
|
||||
/// (读 Info.plist CFBundleIcons → CFBundlePrimaryIcon → CFBundleIconFiles 最后一个)
|
||||
private static func appIconImage() -> UIImage {
|
||||
if let icons = Bundle.main.object(forInfoDictionaryKey: "CFBundleIcons") as? [String: Any],
|
||||
let primary = icons["CFBundlePrimaryIcon"] as? [String: Any],
|
||||
let files = primary["CFBundleIconFiles"] as? [String],
|
||||
let last = files.last,
|
||||
let icon = UIImage(named: last) {
|
||||
return icon
|
||||
}
|
||||
if let icon = UIImage(named: "AppIcon") { return icon }
|
||||
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 1, height: 1))
|
||||
return renderer.image { _ in }
|
||||
}
|
||||
|
||||
// MARK: - URL / Base64 编码
|
||||
|
||||
/// RFC 3986 unreserved + URL-encode(与 msext line 1262-1268 等价)
|
||||
|
||||
Reference in New Issue
Block a user