Files
youle_app_ios_v2/ylgamehall/Source/Network/QiniuTokenSigner.swift
T
joywayerandClaude Opus 4.7 a3679aba7d 修复 SDK 真实接入后的 Swift 编译错误 + Xcode 链接配置
实测三个 SDK(微信 / 高德 / 七牛)链接进 Target 后,暴露出 9 个 Swift 编译错误,逐一修正:

代码侧(5 个 Swift 文件):
- AMapWrapper:updatePrivacyShow / updatePrivacyAgree 是 AMapLocationManager
  类方法(since 2.8.0),不在 AMapServices 上;改为 AMapLocationManager.*
  并补 import AMapLocationKit
- BackGameDataHandler:删 `WXApi.delegate = nil`。新版 SDK 2.x 无 static
  delegate API,delegate 由调用方逐次传给 handleOpenURL/sendAuthReq 并被
  SDK 弱引用;WeChatManager singleton 长生命周期不析构,无需 cleanup
- QiniuConfig / QiniuTokenSigner:所有 static 成员标 nonisolated,让 actor
  QiniuUploader 可直接调,无需 await MainActor.run
- QiniuUploader:QNUploadManager() 在七牛 SDK 8.x 已 kQNDeprecated,改用
  initWithConfiguration: + defaultConfigurationV2

工程侧(pbxproj,Xcode UI 自动写入):
- 新 Frameworks group 容纳 Vendor/WechatSDK / Vendor/AMap 引用
- WechatOpenSDK-NoPay.xcframework:Embed & Sign(动态库)
- AMapFoundationKit / AMapLocationKit:Do Not Embed(静态 fat .framework)

BuildProject 验证:Swift 全部编译通过;剩余 AMap fat framework arch 冲突
(M Mac iOS-simulator)是工程配置选择,下个 commit 处理。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 01:03:29 +08:00

70 lines
2.7 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// QiniuTokenSigner.swift
// ylgamehall
//
// 七牛上传 token 客户端自签(HMAC-SHA1 + Base64URL)。
// 与 msext QiniuManager.m:200-230 generateUploadToken 等价算法。
//
// putPolicy 结构:
// { "scope": "iosaudio[:key]", "deadline": now + expiresIn }
// 签名流程:
// putPolicy JSON → Base64URL → HMAC-SHA1(secretKey) → Base64URL
// → `${AccessKey}:${sign}:${encodedPolicy}`
//
// ⚠️ 用 CryptoKitiOS 13+),不依赖 Qiniu SDK,纯 Swift 自签 token。
//
import Foundation
import CryptoKit
/// 七牛上传 token 自签。整体 nonisolatedactor 内可直接调(不需要 await MainActor.run)。
public enum QiniuTokenSigner {
/// 生成上传 token。
/// - Parameters:
/// - key: 上传文件 key(可空:scope = bucketallow override;非空:scope = bucket:key
/// - expiresIn: token 有效时长(默认 3600 秒)
public nonisolated static func uploadToken(key: String? = nil, expiresIn: TimeInterval = 3600) -> String {
// 1. 拼 scope
let scope: String
if let key, !key.isEmpty {
scope = "\(QiniuConfig.bucketName):\(key)"
} else {
scope = QiniuConfig.bucketName
}
let deadline = Int(Date().timeIntervalSince1970 + expiresIn)
// 2. putPolicy JSON(注意 key 顺序与 msext 等价:scope / deadline
// 实际七牛后端不要求顺序,但保持与 msext 一致便于排错)
let putPolicy: [String: Any] = [
"scope": scope,
"deadline": deadline
]
let policyData = (try? JSONSerialization.data(withJSONObject: putPolicy, options: [.sortedKeys])) ?? Data()
// 3. Base64URL(putPolicy)
let encodedPolicy = base64URLEncode(policyData)
// 4. HMAC-SHA1(secretKey, encodedPolicy) → Base64URL
let secretKeyData = Data(QiniuConfig.secretKey.utf8)
let key = SymmetricKey(data: secretKeyData)
let signature = HMAC<Insecure.SHA1>.authenticationCode(
for: Data(encodedPolicy.utf8),
using: key
)
let encodedSign = base64URLEncode(Data(signature))
// 5. token = AccessKey:encodedSign:encodedPolicy
return "\(QiniuConfig.accessKey):\(encodedSign):\(encodedPolicy)"
}
/// Base64URL: 标准 Base64 把 + → -、/ → _、去掉末尾 =
/// 与七牛 SDK `QNUrlSafeBase64.encodeData:` 等价
private nonisolated static func base64URLEncode(_ data: Data) -> String {
data.base64EncodedString()
.replacingOccurrences(of: "+", with: "-")
.replacingOccurrences(of: "/", with: "_")
.replacingOccurrences(of: "=", with: "")
}
}