如何在我的Swift应用程序中反序列化AWS API网关+ Lambda响应?



我有一个AWS Lambda函数,它执行以下操作:

def lambda_handler(event, context):
# Logic
return json.dumps({"name": "foo", "job": "bar"})

和一个通过GET方法与上述Lambda集成的AWS API Gateway端点。当我对Gateway端点进行cURL操作时,效果很好:

$ curl https://my-aws-gateway-endpoint/stage/endpoint
"{"name": "foo", "job": "bar"}"

然而,当我在我的Swift应用程序中发出相同的请求时,我得到以下错误:

typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found a string/data instead.", underlyingError: nil))

我是这样发出请求的:

let semaphore = DispatchSemaphore(value: 0)
var data: Data // This is a struct that contains the fields "name" and "job"
let task = URLSession.shared.dataTask(with: url) { data, response, error in
defer { semaphore.signal() }
if let _ = error {
return
}
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
print("Invalid response: (response?.description ?? "")")
return
}
guard let data = data else {
print("No data received")
return
}
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
let jsonData = try JSONSerialization.data(withJSONObject: json, options: .fragmentsAllowed)
let decoder = JSONDecoder()
songData = try decoder.decode(Data.self, from: jsonData)
} catch {
print(error)
return
}
}
task.resume()
semaphore.wait()
return data

我做错了什么?

您可以尝试一些更现代的东西,例如下面的示例代码:

struct SongModel: Codable {
let name, job: String
}
var mySong: SongModel?
Task {
if let url = URL(string: "https://my-aws-gateway-endpoint/stage/endpoint") {
mySong = await doRequest(url: url)
}
}
func doRequest(url: URL) async -> SongModel? {
do {
let (data, response) = try await URLSession.shared.data(from: url)
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
print("Invalid response: (response.description)")
return nil
}
return try JSONDecoder().decode(SongModel.self, from: data)
} catch {
print(error)
return nil
}
}