fix(ios): APIClient 兼容有无 ResponseInterceptor 两种响应格式
服务器部署版本可能未启用 ResponseInterceptor,返回裸 JSON 而非
{ success, data, timestamp } 信封格式。APIClient 解码时先探测
JSON 结构,自动适配包裹/裸数据两种格式。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
5e19bd740e
commit
b182203464
@ -63,12 +63,7 @@ actor APIClient {
|
||||
|
||||
switch httpResponse.statusCode {
|
||||
case 200, 201:
|
||||
do {
|
||||
let envelope = try JSONDecoder().decode(APIEnvelope<T>.self, from: data)
|
||||
return envelope.data
|
||||
} catch {
|
||||
throw APIError.decodingFailed(error.localizedDescription)
|
||||
}
|
||||
return try decodeResponse(data)
|
||||
case 401 where !isRetry:
|
||||
if let newToken = await refreshAccessToken() {
|
||||
self.token = newToken
|
||||
@ -109,6 +104,25 @@ actor APIClient {
|
||||
NotificationCenter.default.post(name: .tokenExpired, object: nil)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Decoding
|
||||
|
||||
private func decodeResponse<T: Decodable>(_ data: Data) throws -> T {
|
||||
let decoder = JSONDecoder()
|
||||
// Try unwrapped response first (no envelope), then wrapped
|
||||
if let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
||||
json["data"] == nil && json["success"] == nil {
|
||||
return try decoder.decode(T.self, from: data)
|
||||
}
|
||||
// Has envelope wrapper
|
||||
do {
|
||||
let envelope = try decoder.decode(APIEnvelope<T>.self, from: data)
|
||||
return envelope.data
|
||||
} catch {
|
||||
// Fallback: try decoding T directly (e.g. server returns unwrapped on some endpoints)
|
||||
return try decoder.decode(T.self, from: data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Helper for encoding arbitrary Encodable
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user