From b182203464ad7de7ca2228c1c24c206b0eafef9e Mon Sep 17 00:00:00 2001 From: WangDL Date: Sun, 17 May 2026 19:42:17 +0800 Subject: [PATCH] =?UTF-8?q?fix(ios):=20APIClient=20=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E6=9C=89=E6=97=A0=20ResponseInterceptor=20=E4=B8=A4=E7=A7=8D?= =?UTF-8?q?=E5=93=8D=E5=BA=94=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 服务器部署版本可能未启用 ResponseInterceptor,返回裸 JSON 而非 { success, data, timestamp } 信封格式。APIClient 解码时先探测 JSON 结构,自动适配包裹/裸数据两种格式。 Co-Authored-By: Claude Opus 4.7 --- .../AIStudyApp/Core/Network/APIClient.swift | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/AIStudyApp/AIStudyApp/Core/Network/APIClient.swift b/AIStudyApp/AIStudyApp/Core/Network/APIClient.swift index cf58870..9f02b74 100644 --- a/AIStudyApp/AIStudyApp/Core/Network/APIClient.swift +++ b/AIStudyApp/AIStudyApp/Core/Network/APIClient.swift @@ -63,12 +63,7 @@ actor APIClient { switch httpResponse.statusCode { case 200, 201: - do { - let envelope = try JSONDecoder().decode(APIEnvelope.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(_ 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.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