我正在遇到以下麻烦。客户端iOS应用程序正在与某些后端服务合作发送2种响应类型:成功的JSON和错误的文本错误。
对于JSON,我具有简单的可解码结构:
struct Response: Decodable {
let message: String
}
它起作用,直到服务器在HTTP主体中发送简单的文本,我会收到以下错误:
"错误域= nScocoaErrordomain代码= 3840" JSON文本未启动 使用数组或对象和选项以允许片段未设置。"
也许在这种情况下,响应结构可能更普遍?
没有简单的方法使您的Decodable
结构处理此错误,因为如果您要解释的Data
,则init(from decoder:)
方法甚至都没有调用,所以您需要处理初始化器范围之外的错误。
一种可能的解决方案是处理JSONDecoder.decode(Response.self,from:)
方法的捕获块中的错误。一旦decode
函数丢弃了错误,您可以检查错误是否是由于输入不正确(在这种情况下,这很可能意味着输入是一个简单的字符串而不是JSON(,您可以简单地将响应数据转换为String
,然后调用Response
的成员Wision初始化器,以使用字符串响应进行初始化。
以下示例显示了如何使用两个示例响应处理此类情况,一个是有效的JSON,另一个是一个简单的字符串。
let validJsonResponseData = """
{"message" : "A message"}
""".data(using: .utf8)!
let simpleTextResponseData = "Error".data(using: .utf8)!
struct Response: Decodable {
let message: String
}
do {
let successResponse = try JSONDecoder().decode(Response.self, from: validJsonResponseData)
let errorResponse = try JSONDecoder().decode(Response.self, from: simpleTextResponseData)
} catch {
if let error = error as? DecodingError {
switch error {
case .dataCorrupted(_):
if let simpleTextResponse = String(data: simpleTextResponseData, encoding: .utf8) {
let errorResponse = Response(message: simpleTextResponse)
}
default:
throw error
}
} else {
throw error
}
}