I know there are various threads on this but it seems like there's a fundamental flaw in my understanding of objects in Swift.
So I have the following function that returns a JSON response as expected:
func executeGet( completion: @escaping ([[String:Any]]?, Error?) -> Void) {
AF.request("https://myURL",
method:.get,
headers:headers).responseJSON{ response in
debugPrint(response) <- I get readable JSON response from here
if let error = response.error {
completion(nil, error)
}
else if let jsonArray = response.value as? [[String:Any]]{
completion(jsonArray, nil)
}
else if let jsonDict = response.value as? [String:Any]{
completion([jsonDict], nil )
}
}
}
And then I'm able to leverage the completion handler to read the JSON response outside of AL's scope:
executeGet() { (json, error) in
if let error = error{
print(error.localizedDescription)
}
else if let json = json {
print(type(of:json)) <- did this for sanity check
print(json["result"][0]["capturedlists"]) <- Error No exact matches in call to subscript
}
}
But I'm unable to just get the 'capturedLists' part of the JSON. The JSON snippet I need to capture looks as follows:
"capturedLists":{"Something":
[{"Position":"1","A1":"a1","B1":"b1"},
{"Position":"2","A2":"a2","B2":"b2"}]}}}
Can anyone help me figure out what am I doing wrong? I know usually you can get data from Json by something like response[a][0] but that doesn't work here for some reason.
EDIT: Upone suggestion I used Quicktype to get a struct for my response and got the following:
struct Welcome: Codable {
let statusCode: Int
let messageCode: String
let result: Result
}
// MARK: - Result
struct Result: Codable {
let id: String
let inputParameters: InputParameters
let robotID: String
let runByUserID, runByTaskMonitorID: JSONNull?
let runByAPI: Bool
let createdAt, startedAt, finishedAt: Int
let userFriendlyError: JSONNull?
let triedRecordingVideo: Bool
let videoURL: String
let videoRemovedAt: Int
let retriedOriginalTaskID: String
let retriedByTaskID: JSONNull?
let capturedDataTemporaryURL: String
let capturedTexts: CapturedTexts
let capturedScreenshots: CapturedScreenshots
let capturedLists: CapturedLists
enum CodingKeys: String, CodingKey {
case id, inputParameters
case robotID = "robotId"
case runByUserID = "runByUserId"
case runByTaskMonitorID = "runByTaskMonitorId"
case runByAPI, createdAt, startedAt, finishedAt, userFriendlyError, triedRecordingVideo
case videoURL = "videoUrl"
case videoRemovedAt
case retriedOriginalTaskID = "retriedOriginalTaskId"
case retriedByTaskID = "retriedByTaskId"
case capturedDataTemporaryURL = "capturedDataTemporaryUrl"
case capturedTexts, capturedScreenshots, capturedLists
}
}
.responseJSON
is deprecated. Don't use it.The error occurs because
json["result"]
returnsAny
but the compiler must know the static type for the subsequent index subscription.As you have a
Decodable
model AF providesresponseDecodable
. Change your function towhich can even be simplified to
And call it
If you get an error the model doesn't match the JSON and the error tells you exactly what's wrong