2

I'm trying to serialize two different types of object to JSON, but I've only been able to do so using JSONEncoder for one, and JSONSerialization for the other.

One is a simple Int, which I serialize as follows:

let ticket: [String:Any] = ["ticket": -1]
let ticketJson = try! JSONSerialization.data(withJSONObject: ticket)
let ticketJsonString = String(data: ticketJson, encoding: String.Encoding.utf8)

The other object type is a class I created, which I serialize as follows:

let encodedNotification = try! JSONEncoder().encode(notification)
let encodedNotificationJsonString = String(data: encodedNotification, encoding: String.Encoding.utf8)

Ideally, I would serialize both at once, using the following dictionary:

let parameters: [String:Any] = ["ticket": -1, "notification": notification]

Is this possible? If so, how? I have not been able to figure it out.

Thanks!

kyrers
  • 489
  • 1
  • 6
  • 22

1 Answers1

1

Put the values in a struct rather than a [String: Any].

struct Parameters: Encodable {
    let ticket: Int
    let notification: Notification
}

let parameters = Parameters(ticket: -1, notification: notification)

let encoded = try JSONEncoder().encode(parameters)

As a rule, avoid Any in Swift. It is a very difficult type to use correctly and does not play particularly nicely with the type system. Except in fairly advanced code, it mostly shows up due to ObjC-bridging (such as in JSONSerialization, which is a bridge to the ObjC NSJSONSerialization).

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • Thanks. How did I not think of this? :( Anyway, is there any issue if I create the struct inside the function I'm using to create the request? – kyrers Oct 01 '20 at 15:11
  • 1
    That's totally fine and good practice. You can create a local struct type that is private to a single function. Like a local variable, it can even have the same name as local structs you use in other functions without causing collisions. – Rob Napier Oct 01 '20 at 15:18