You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Swift设置Accept-Language后无法获取英文API数据问题

iOS Swift API请求无法通过Accept-Language获取英文数据问题排查与解决

问题描述

在Postman中设置Accept-Language为"en"可正常获取英文API数据,但自己编写的fetchDataByToken函数无法实现相同效果。

可能原因与解决方案

1. 确认请求头是否实际发送

很多时候代码里设置了请求头,但实际发送时被覆盖或未生效。可以通过以下方式验证:

  • 使用Charles或Proxyman抓包,查看实际请求的Accept-Language头是否正确携带。
  • 临时修改代码,打印请求头信息:
    print("Request Headers: \(request.allHTTPHeaderFields ?? [:])")
    

2. 调整Accept-Language格式为标准格式

部分API服务器对语言头的格式要求严格,单纯的"en"可能不被识别,建议改用标准的权重格式:

request.setValue("en-US,en;q=0.9", forHTTPHeaderField: "Accept-Language")

Postman可能会自动补全标准格式,而代码中手动设置的"en"不符合服务器预期。

3. 禁用请求缓存

如果之前的请求被缓存,新的语言头设置可能不会触发服务器返回新数据。给请求添加缓存策略:

request.cachePolicy = .reloadIgnoringLocalCacheData

4. 检查服务器逻辑是否优先用户默认语言

部分API会根据token关联的用户账号默认语言返回数据,忽略Accept-Language头。可以在Postman中使用相同的token测试,确认是否存在这种情况。如果是,需要后端调整逻辑,优先使用请求头的语言设置。

5. 优化错误捕获,排查真实问题

当前代码将所有错误统一归为APIError.invalidData,无法定位具体问题。修改错误处理逻辑,保留原始错误信息:

.mapError { error -> APIError in
    if let apiError = error as? APIError {
        return apiError
    }
    // 保留原始错误描述,方便排查
    return APIError.invalidData(message: error.localizedDescription)
}

(需要先给APIError添加带message的枚举case,比如case invalidData(message: String))

修改后的完整示例代码

func fetchDataByToken<T: Decodable>(urlString: String, type: T.Type) -> AnyPublisher<T, APIError> {
    guard let token = UserManager.shared.getToken() else {
        return Fail(error: APIError.serverError)
            .eraseToAnyPublisher()
    }
    guard let url = URL(string: urlString) else {
        return Fail(error: APIError.invalidURL)
            .eraseToAnyPublisher()
    }
    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    // 使用标准格式的语言头
    request.setValue("en-US,en;q=0.9", forHTTPHeaderField: "Accept-Language")
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
    // 禁用缓存
    request.cachePolicy = .reloadIgnoringLocalCacheData
    
    return URLSession.shared.dataTaskPublisher(for: request)
        .tryMap { output -> Data in
            guard let response = output.response as? HTTPURLResponse,
                  response.statusCode >= 200 && response.statusCode < 300 else {
                throw APIError.invalidData(message: "HTTP Status Code: \(response.statusCode)")
            }
            return output.data
        }
        .decode(type: T.self, decoder: JSONDecoder())
        .mapError { error -> APIError in
            if let apiError = error as? APIError {
                return apiError
            }
            return APIError.invalidData(message: error.localizedDescription)
        }
        .eraseToAnyPublisher()
}

// 假设APIError枚举定义如下
enum APIError: Error {
    case serverError
    case invalidURL
    case invalidData(message: String)
}

内容的提问来源于stack exchange,提问作者Mohamed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 06:50:06