Currently I'm developing an app - while learning Swift and SwiftUI - that shows stock prices in real time. I'm using Alamofire to stream the data from the servers but I'm receiving this weird format:
I'm a beginner but I think this is not proper JSON, I mean, I've tried to Decode this data with the following structs:
struct Response: Codable {
var data: Data
}
struct Data: Codable {
var symbol: String
}
But that gives me an error. I think the problem is the data : before the array.
If you want more information, this is the exact error:
responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.decodingFailed(error: Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.})))))
And this is my streamRequest:
AF.streamRequest(urlStream).responseStreamDecodable(of: Response.self) { stream in
switch stream.event {
case let .stream(result):
switch result {
case let .success(value):
print(value)
case let .failure(error):
print(error)
}
case let .complete(completion):
print(completion)
}
}
So, the question is: Am I doing something wrong? If not, How can I decode this format?
Thank you.
struct Response: Codable {
var data: [Data]
}
struct Data: Codable {
var symbol: String
}
Decoding
let json = """
{
"data": [{
"symbol": "SPY",
"price": 400.9200,
"size": 500,
"time": 1617309355738,
"seq": 9057
}]
}
"""
let decoder = JSONDecoder()
if let data = json.data(using: .utf8),
let result = try? decoder.decode(Response.self, from: data) {
print(result)
}
// prints: Response(data: [Data(symbol: "SPY")])
Encoding
let value = Response(data: [Data(symbol: "Swift")])
let encoder = JSONEncoder()
if let data = try? encoder.encode(value),
let result = String(bytes: data, encoding: .utf8) {
print(result)
}
// prints: {"data":[{"symbol":"Swift"}]}
Thanks for your quick reply. Maybe I misunderstood something but I'm not receiving data inside curly brackets as if it was a JSON response, this is my problem. The exact response I'm receiving from the server is:
data:[{"symbol":"BTCUSD","primaryExchange":"Gemini","sector":"cryptocurrency","calculationPrice":"realtime","high":null,"low":null,"latestPrice":"59187.42","latestSource":"Real time price","latestUpdate":1617370913090,"latestVolume":"0.00828046","previousClose":null}]
As you can see, before data: there is no {, the same at the end of the response.
You either need to manually remove data: and decode the string as [Data] or add { and } and decode it as Response. I never used Alamofire, but from the documentation of responseStreamDecodable(of:on:using:preprocessor:stream:) it looks like you can add a preprocessor that transforms the data just before decoding it.
I moved the topic to the Alamofire section, since it seem to be related to that framework.