My use case is storing drawing data. I have defined a Codable
data object in Swift, something like this:
class DrawingData : Codable {
var startTime : Double?
var pointsOverTime : [String : CGPoint] = [:]
var templateLine : [CGPoint]
}
(it turns out, objects like CGPoint
have a very nice Codable
implementation, as you will see below).
In my Java 8 Lambda function, I have defined the object this way:
public class DrawingData {
Double startTime;
HashMap<String, Double[][]> pointsOverTime;
Double[][] templateLine;
}
To encode, on the iOS side, I would love to just do this:
func sendToLambda(drawingData : DrawingData) {
let request = AWSLambdaInvokerInvocationRequest()
request.payload = drawingData
...
but in this case, I get an NSInvalidArgumentException: Invalid type in JSON write
. OK, no problem, I thought, I will encode the object:
let encoder = JSONEncoder()
let data = try encoder.encode(drawingData)
let json = String(data: data, encoding: .utf8)
At first, I tried request.payload = data
but this gives me the same NSInvalidArgumentException
error as above. When I try request.payload = json
it actually sends it to the Lambda, but then I receive a deserialization error from Lambda:
com.fasterxml.jackson.databind.JsonMappingException:
Can not instantiate value of type [simple type, class com.(...).DrawingData] from String value ...
Now here's the part that really gets me. I copy the String value (from the above error), convert escaped quotes to quotes, and paste the exact string as a test object in the Lambda console, and it works just fine! (I also tried modifying my json string in my code using .replacingOccurrences(of: "\\\"", with: "\"")
- no dice).
So it seems the problem lies either with a) the Swift JSONEncoder
and/or String.init(data:)
or else b) something about the Jackson configuration that is part of the AWS Lambda environment. I'm not sure how to figure out which one it is, or what the best way to fix it would be.
I'll likely submit a request for the AWS iOS SDK to accept a Codable object as a payload, but in the meantime, any suggestions how to work around this? Any alternatives I could try? Thanks in advance!
Edit: as suggested, here is a snippet of the JSON as printed to my XCode console:
{\"startTime\":1612896264.1828671,
\"templateLine\":[[115.53672736136741,335.1095896791432],
[1055.5423897415162,193.17949493333694]],\"pointsOverTime\":
{\"363899.94621276855\":[880.5,145.5],\"209530.83038330078\":
[242,347.5],\"331470.9663391113\":[843,156.5],\"175115.10848999023\":
[187,369.5],\"156777.85873413086\":[173,373],\"209379.9114227295\":
[242,347.5],\"281613.826751709\":[698,197.5],\"265787.12463378906\":
[606.5,224],\"347551.8226623535\":[868.5,148.5],\"174979.92515563965\":
[187,369.5],\"0\":[172.5,373],\"156646.9669342041\":
[173,373],\"224991.7984008789\":[331,313]...