You can use this open source class JSONSerializer
from https://github.com/peheje/JsonSerializerSwift/blob/master/JsonSerializerSwift/JsonSerializer.swift
I have made some changes in this class to append an array of objects with key in existing JSON
import Foundation
open class JSONSerializer {
public enum JSONSerializerError: Error {
case jsonIsNotDictionary
case jsonIsNotArray
case jsonIsNotValid
}
open static func toDictionary(_ jsonString: String) throws -> NSDictionary {
if let dictionary = try jsonToAnyObject(jsonString) as? NSDictionary {
return dictionary
} else {
throw JSONSerializerError.jsonIsNotDictionary
}
}
open static func toArray(_ jsonString: String) throws -> NSArray {
if let array = try jsonToAnyObject(jsonString) as? NSArray {
return array
} else {
throw JSONSerializerError.jsonIsNotArray
}
}
fileprivate static func jsonToAnyObject(_ jsonString: String) throws -> Any? {
var any: Any?
if let data = jsonString.data(using: String.Encoding.utf8) {
do {
any = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
}
catch let error as NSError {
let sError = String(describing: error)
NSLog(sError)
throw JSONSerializerError.jsonIsNotValid
}
}
return any
}
open static func toJson(_ object: Any, prettify: Bool = false) -> String {
var json = ""
if (!(object is Array<Any>)) {
json += "{"
}
let mirror = Mirror(reflecting: object)
var children = [(label: String?, value: Any)]()
if let mirrorChildrenCollection = AnyRandomAccessCollection(mirror.children) {
children += mirrorChildrenCollection
}
else {
let mirrorIndexCollection = AnyCollection(mirror.children)
children += mirrorIndexCollection
}
var currentMirror = mirror
while let superclassChildren = currentMirror.superclassMirror?.children {
let randomCollection = AnyRandomAccessCollection(superclassChildren)!
children += randomCollection
currentMirror = currentMirror.superclassMirror!
}
var filteredChildren = [(label: String?, value: Any)]()
for (optionalPropertyName, value) in children {
if let optionalPropertyName = optionalPropertyName {
if !optionalPropertyName.contains("notMapped_") {
filteredChildren.append((optionalPropertyName, value))
}
}
else {
filteredChildren.append((nil, value))
}
}
var skip = false
let size = filteredChildren.count
var index = 0
var first = true
for (optionalPropertyName, value) in filteredChildren {
skip = false
let propertyName = optionalPropertyName
let property = Mirror(reflecting: value)
var handledValue = String()
if propertyName != nil && propertyName == "some" && property.displayStyle == Mirror.DisplayStyle.struct {
handledValue = toJson(value)
skip = true
}
else if (value is Int ||
value is Int32 ||
value is Int64 ||
value is Double ||
value is Float ||
value is Bool) && property.displayStyle != Mirror.DisplayStyle.optional {
handledValue = String(describing: value)
}
else if let array = value as? [Int?] {
handledValue += "["
for (index, value) in array.enumerated() {
handledValue += value != nil ? String(value!) : "null"
handledValue += (index < array.count-1 ? ", " : "")
}
handledValue += "]"
}
else if let array = value as? [Double?] {
handledValue += "["
for (index, value) in array.enumerated() {
handledValue += value != nil ? String(value!) : "null"
handledValue += (index < array.count-1 ? ", " : "")
}
handledValue += "]"
}
else if let array = value as? [Float?] {
handledValue += "["
for (index, value) in array.enumerated() {
handledValue += value != nil ? String(value!) : "null"
handledValue += (index < array.count-1 ? ", " : "")
}
handledValue += "]"
}
else if let array = value as? [Bool?] {
handledValue += "["
for (index, value) in array.enumerated() {
handledValue += value != nil ? String(value!) : "null"
handledValue += (index < array.count-1 ? ", " : "")
}
handledValue += "]"
}
else if let array = value as? [String?] {
handledValue += "["
for (index, value) in array.enumerated() {
handledValue += value != nil ? "\"\(value!)\"" : "null"
handledValue += (index < array.count-1 ? ", " : "")
}
handledValue += "]"
}
else if let array = value as? [String] {
handledValue += "["
for (index, value) in array.enumerated() {
handledValue += "\"\(value)\""
handledValue += (index < array.count-1 ? ", " : "")
}
handledValue += "]"
}
else if let array = value as? NSArray {
handledValue += "["
for (index, value) in array.enumerated() {
if !(value is Int) &&
!(value is Int32) &&
!(value is Int64) &&
!(value is Double) && !(value is Float) && !(value is Bool) && !(value is String) {
handledValue += toJson(value)
}
else {
handledValue += "\(value)"
}
handledValue += (index < array.count-1 ? ", " : "")
}
handledValue += "]"
}
else if property.displayStyle == Mirror.DisplayStyle.class ||
property.displayStyle == Mirror.DisplayStyle.struct ||
String(describing: value).contains("#") {
handledValue = toJson(value)
}
else if property.displayStyle == Mirror.DisplayStyle.optional {
let str = String(describing: value)
if str != "nil" {
var d = String(str).dropFirst(9)
d = d.dropLast(1)
handledValue = String(d)
} else {
handledValue = "null"
}
}
else {
handledValue = String(describing: value) != "nil" ? "\"\(value)\"" : "null"
}
if !skip {
if let propertyName = propertyName {
json += "\"\(propertyName)\": \(handledValue)" + (index < size-1 ? ", " : "")
}
else {
if first {
json += "["
first = false
}
json += "\(handledValue)" + (index < size-1 ? ", " : "]")
}
} else {
json = "\(handledValue)" + (index < size-1 ? ", " : "")
}
index += 1
}
if !skip {
if (!(object is Array<Any>)) {
json += "}"
}
}
if prettify {
let jsonData = json.data(using: String.Encoding.utf8)!
let jsonObject = try! JSONSerialization.jsonObject(with: jsonData, options: [])
let prettyJsonData = try! JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted)
json = NSString(data: prettyJsonData, encoding: String.Encoding.utf8.rawValue)! as String
}
return json
}
open static func toJson(key: String, _ object: Any, existingJson: String = "", prettify: Bool = false) -> String {
var json = ""
if (!(object is Array<Any>)) {
json += "{ "
}
let mirror = Mirror(reflecting: object)
var children = [(label: String?, value: Any)]()
if let mirrorChildrenCollection = AnyRandomAccessCollection(mirror.children) {
children += mirrorChildrenCollection
}
else {
let mirrorIndexCollection = AnyCollection(mirror.children)
children += mirrorIndexCollection
}
var currentMirror = mirror
while let superclassChildren = currentMirror.superclassMirror?.children {
let randomCollection = AnyRandomAccessCollection(superclassChildren)!
children += randomCollection
currentMirror = currentMirror.superclassMirror!
}
var filteredChildren = [(label: String?, value: Any)]()
for (optionalPropertyName, value) in children {
if let optionalPropertyName = optionalPropertyName {
if !optionalPropertyName.contains("notMapped_") {
filteredChildren.append((optionalPropertyName, value))
}
}
else {
filteredChildren.append((nil, value))
}
}
var skip = false
let size = filteredChildren.count
var index = 0
var first = true
for (optionalPropertyName, value) in filteredChildren {
skip = false
let propertyName = optionalPropertyName
let property = Mirror(reflecting: value)
var handledValue = String()
if propertyName != nil && propertyName == "some" && property.displayStyle == Mirror.DisplayStyle.struct {
handledValue = toJson(value)
skip = true
}
else if (value is Int ||
value is Int32 ||
value is Int64 ||
value is Double ||
value is Float ||
value is Bool) && property.displayStyle != Mirror.DisplayStyle.optional {
handledValue = String(describing: value)
}
else if let array = value as? [Int?] {
handledValue += "["
for (index, value) in array.enumerated() {
handledValue += value != nil ? String(value!) : "null"
handledValue += (index < array.count-1 ? ", " : "")
}
handledValue += "]"
}
else if let array = value as? [Double?] {
handledValue += "["
for (index, value) in array.enumerated() {
handledValue += value != nil ? String(value!) : "null"
handledValue += (index < array.count-1 ? ", " : "")
}
handledValue += "]"
}
else if let array = value as? [Float?] {
handledValue += "["
for (index, value) in array.enumerated() {
handledValue += value != nil ? String(value!) : "null"
handledValue += (index < array.count-1 ? ", " : "")
}
handledValue += "]"
}
else if let array = value as? [Bool?] {
handledValue += "["
for (index, value) in array.enumerated() {
handledValue += value != nil ? String(value!) : "null"
handledValue += (index < array.count-1 ? ", " : "")
}
handledValue += "]"
}
else if let array = value as? [String?] {
handledValue += "["
for (index, value) in array.enumerated() {
handledValue += value != nil ? "\"\(value!)\"" : "null"
handledValue += (index < array.count-1 ? ", " : "")
}
handledValue += "]"
}
else if let array = value as? [String] {
handledValue += "["
for (index, value) in array.enumerated() {
handledValue += "\"\(value)\""
handledValue += (index < array.count-1 ? ", " : "")
}
handledValue += "]"
}
else if let array = value as? NSArray {
handledValue += "["
for (index, value) in array.enumerated() {
if !(value is Int) &&
!(value is Int32) &&
!(value is Int64) &&
!(value is Double) && !(value is Float) && !(value is Bool) && !(value is String) {
handledValue += toJson(value)
}
else {
handledValue += "\(value)"
}
handledValue += (index < array.count-1 ? ", " : "")
}
handledValue += "]"
}
else if property.displayStyle == Mirror.DisplayStyle.class ||
property.displayStyle == Mirror.DisplayStyle.struct ||
String(describing: value).contains("#") {
handledValue = toJson(value)
}
else if property.displayStyle == Mirror.DisplayStyle.optional {
let str = String(describing: value)
if str != "nil" {
var d = String(str).dropFirst(9)
d = d.dropLast(1)
handledValue = String(d)
} else {
handledValue = "null"
}
}
else {
handledValue = String(describing: value) != "nil" ? "\"\(value)\"" : "null"
}
if !skip {
if let propertyName = propertyName {
json += "\"\(propertyName)\": \(handledValue)" + (index < size-1 ? ", " : "")
}
else {
if first {
json += "["
first = false
}
json += "\(handledValue)" + (index < size-1 ? ", " : "]")
}
} else {
json = "\(handledValue)" + (index < size-1 ? ", " : "")
}
index += 1
}
if !skip {
if (!(object is Array<Any>)) {
json += "}"
}
}
if !existingJson.isEmpty {
var JSON = existingJson
JSON.removeLast()
JSON = JSON + ", \"\(key)\": " + json + " }"
if prettify {
return prettyJson(json: JSON)
}
return JSON
} else if existingJson.isEmpty {
if prettify {
return prettyJson(json: "{ \"\(key)\": " + json + " }")
}
return "{ \"\(key)\": " + json + " }"
}
return prettyJson(json: json)
}
private static func prettyJson(json: String) -> String {
let jsonData = json.data(using: String.Encoding.utf8)!
let jsonObject = try! JSONSerialization.jsonObject(with: jsonData, options: [])
let prettyJsonData = try! JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted)
return NSString(data: prettyJsonData, encoding: String.Encoding.utf8.rawValue)! as String
}
}
And here is the code to use this class
let params = [ "some key": "some value"]
if let theJSONData = try? JSONSerialization.data(withJSONObject: params, options: []) {
let theJSONText = String(data: theJSONData, encoding: .ascii)
let json = JSONSerializer.toJson(key: "Products", Cart.sharedInstance.products, existingJson: theJSONText!, prettify: true)
print("JSON string = \(json)")
let finalParams = json.convertToDictionary()
}
Replace Cart.sharedInstance.products with your array of objects and Products with your key.
You can see the overloaded methods as per your need.
Hope you get the desired result.