Currently probably the best solution to use is Codable protocol. There are many examples and tutorials online so please do check one or two, I am sure you will find it very simple to use.
The point is that you can encode concrete classes or structures directly to (and from) JSON. So your problem is then not in JSON itself but just structuring your classes. For instance:
class Survey {
class Answer {
enum AnswerType: String {
case imagepicker
}
class Value {
var value: String?
}
var type: AnswerType = .imagepicker
var qcode: String?
var values: [Value] = [Value]()
}
let interactionId: String
var futureSurveyAnswers: [Answer] = [Answer]()
var originalResultArray: String?
init(interactionId: String) { self.interactionId = interactionId }
}
This way you can easily modify your structure as you want to. For instance:
let survey = Survey(interactionId: "0")
survey.futureSurveyAnswers.append({
let answer = Survey.Answer()
answer.qcode = "test"
return answer
}())
So to extend it to codable all you need to do is actually append Codable protocol to your class and any embedded component:
class Survey: Codable {
class Answer: Codable {
enum AnswerType: String, Codable {
case imagepicker
}
class Value: Codable {
var value: String?
}
var type: AnswerType = .imagepicker
var qcode: String?
var values: [Value] = [Value]()
}
let interactionId: String
var futureSurveyAnswers: [Answer] = [Answer]()
var originalResultArray: String?
init(interactionId: String) { self.interactionId = interactionId }
}
Now you can get JSON as simple as the following:
let survey = Survey(interactionId: "0")
survey.futureSurveyAnswers.append({
let answer = Survey.Answer()
answer.values.append({
let value = Survey.Answer.Value()
value.value = "some"
return value
}())
answer.qcode = "test"
return answer
}())
let encoder = JSONEncoder()
if let jsonData = try? encoder.encode(survey) {
print("Generated data: \(jsonData)")
}
I hope this puts you in the right direction.
From comments this is what I used as a test example for JSON:
class Survey: Codable {
class Answer: Codable {
enum AnswerType: String, Codable {
case imagepicker
}
class Value: Codable {
var value: String?
init(value: String? = nil) { self.value = value }
}
var type: AnswerType = .imagepicker
var qcode: String?
var values: [Value] = [Value]()
}
let interactionId: String
var futureSurveyAnswers: [Answer] = [Answer]()
var originalResultArray: String?
init(interactionId: String) { self.interactionId = interactionId }
}
func addTestAnswer(to survey: Survey) {
let answer = Survey.Answer()
answer.values.append(.init(value: "Random value \(Int.random(in: 1...100))"))
answer.values.append(.init(value: "Random value \(Int.random(in: 1...100))"))
answer.values.append(.init(value: "Random value \(Int.random(in: 1...100))"))
answer.values.append(.init(value: "Random value \(Int.random(in: 1...100))"))
survey.futureSurveyAnswers.append(answer)
}
func testRandomSurveyJSON() {
let survey = Survey(interactionId: "randomSurvey")
addTestAnswer(to: survey)
addTestAnswer(to: survey)
addTestAnswer(to: survey)
addTestAnswer(to: survey)
addTestAnswer(to: survey)
print("Got JSON: \(String(data: try! JSONEncoder().encode(survey), encoding: .utf8)!)")
}
And got the following result:
Got JSON: {"interactionId":"randomSurvey","futureSurveyAnswers":[{"type":"imagepicker","values":[{"value":"Random value 74"},{"value":"Random value 4"},{"value":"Random value 26"},{"value":"Random value 93"}]},{"type":"imagepicker","values":[{"value":"Random value 43"},{"value":"Random value 65"},{"value":"Random value 38"},{"value":"Random value 88"}]},{"type":"imagepicker","values":[{"value":"Random value 56"},{"value":"Random value 88"},{"value":"Random value 57"},{"value":"Random value 94"}]},{"type":"imagepicker","values":[{"value":"Random value 66"},{"value":"Random value 52"},{"value":"Random value 89"},{"value":"Random value 27"}]},{"type":"imagepicker","values":[{"value":"Random value 53"},{"value":"Random value 93"},{"value":"Random value 30"},{"value":"Random value 55"}]}]}
which seems to be correct.