fix: 修复签名不匹配的根本原因,改用手动拼接 URL 替代 URLComponents,增加加载重试机制
CI / lint-and-build (push) Has been cancelled
CI / lint-and-build (push) Has been cancelled
This commit is contained in:
@@ -66,15 +66,12 @@ actor VODClient {
|
|||||||
params["Signature"] = signature
|
params["Signature"] = signature
|
||||||
|
|
||||||
let host = endpoint()
|
let host = endpoint()
|
||||||
var components = URLComponents()
|
let query = params.sorted(by: { $0.key < $1.key })
|
||||||
components.scheme = "https"
|
.map { "\(VODSignature.percentEncodePublic($0.key))=\(VODSignature.percentEncodePublic($0.value))" }
|
||||||
components.host = host
|
.joined(separator: "&")
|
||||||
components.path = "/"
|
let urlString = "https://\(host)/?\(query)"
|
||||||
components.queryItems = params.sorted(by: { $0.key < $1.key }).map {
|
|
||||||
URLQueryItem(name: $0.key, value: $0.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let url = components.url else {
|
guard let url = URL(string: urlString) else {
|
||||||
throw VODClientError.invalidResponse
|
throw VODClientError.invalidResponse
|
||||||
}
|
}
|
||||||
return url
|
return url
|
||||||
@@ -93,7 +90,17 @@ actor VODClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let decoder = JSONDecoder()
|
let decoder = JSONDecoder()
|
||||||
|
do {
|
||||||
return try decoder.decode(T.self, from: data)
|
return try decoder.decode(T.self, from: data)
|
||||||
|
} catch {
|
||||||
|
if action == "GetPlayInfo" {
|
||||||
|
print("[VODClient] GetPlayInfo 解码失败: \(error)")
|
||||||
|
if let raw = String(data: data, encoding: .utf8) {
|
||||||
|
print("[VODClient] GetPlayInfo 原始响应: \(raw)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func searchMedia(
|
func searchMedia(
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ struct VODSignature {
|
|||||||
|
|
||||||
let stringToSign = "\(method)&%2F&\(percentEncode(canonicalQuery))"
|
let stringToSign = "\(method)&%2F&\(percentEncode(canonicalQuery))"
|
||||||
|
|
||||||
print("[VODSignature] stringToSign: \(stringToSign)")
|
|
||||||
|
|
||||||
guard let keyData = "\(accessKeySecret)&".data(using: .utf8) else {
|
guard let keyData = "\(accessKeySecret)&".data(using: .utf8) else {
|
||||||
throw VODSignatureError.invalidKey
|
throw VODSignatureError.invalidKey
|
||||||
}
|
}
|
||||||
@@ -41,6 +39,10 @@ struct VODSignature {
|
|||||||
return signatureData.base64EncodedString()
|
return signatureData.base64EncodedString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func percentEncodePublic(_ value: String) -> String {
|
||||||
|
percentEncode(value)
|
||||||
|
}
|
||||||
|
|
||||||
private static func percentEncode(_ value: String) -> String {
|
private static func percentEncode(_ value: String) -> String {
|
||||||
let allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~"
|
let allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~"
|
||||||
var result = ""
|
var result = ""
|
||||||
|
|||||||
@@ -243,7 +243,9 @@ struct VideoListView: View {
|
|||||||
private func refreshFromAPI() async {
|
private func refreshFromAPI() async {
|
||||||
isLoading = true
|
isLoading = true
|
||||||
errorMessage = nil
|
errorMessage = nil
|
||||||
loadingStatus = "正在加载视频列表..."
|
let maxRetries = 3
|
||||||
|
for attempt in 1...maxRetries {
|
||||||
|
loadingStatus = attempt == 1 ? "正在加载视频列表..." : "重试中... (第 \(attempt)/\(maxRetries) 次)"
|
||||||
var collected: [VideoItem] = []
|
var collected: [VideoItem] = []
|
||||||
var page = 1
|
var page = 1
|
||||||
let size = 100
|
let size = 100
|
||||||
@@ -262,12 +264,21 @@ struct VideoListView: View {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
page += 1
|
page += 1
|
||||||
|
try? await Task.sleep(for: .milliseconds(200))
|
||||||
}
|
}
|
||||||
allVideos = collected
|
allVideos = collected
|
||||||
applyFilter()
|
applyFilter()
|
||||||
loadingStatus = ""
|
loadingStatus = ""
|
||||||
|
isLoading = false
|
||||||
|
return
|
||||||
} catch {
|
} catch {
|
||||||
errorMessage = "加载失败:\(error.localizedDescription)"
|
if attempt < maxRetries {
|
||||||
|
let delay = UInt64(attempt) * 1_000_000_000
|
||||||
|
try? await Task.sleep(nanoseconds: delay)
|
||||||
|
} else {
|
||||||
|
errorMessage = "加载失败(已重试 \(maxRetries) 次):\(error.localizedDescription)"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
isLoading = false
|
isLoading = false
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user