How to encode multiple objects with JSONEncoder

How do I encode multiple objects to a JSON file with JSONEncoder? At the moment if I only encode one of my custom "Event" objects it works fine and I can read from it, but when I try to encode multiple of them I get the error "dataCorrupted(Swift.DecodingError.Context(codingPath: , debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Garbage at end." UserInfo={NSDebugDescription=Garbage at end.})))".

I'm attempting to add multiple objects by doing this: "try data.append(encoder.encode(events[i][j]))", but I'm assuming this is what causes the error. I have no idea how to "append" the next object to the data otherwise.

Your best bet is to just stick all your objects in an array and the encode that. Trying to append raw data like is probably not what you want to be doing.

struct Person : Codable {
  let name: String
  var age: Int
}

let encoder = JSONEncoder()
let encodedArray = try encoder.encode([Person(name: "bob", age: 20), Person(name: "alice", age: 22)])

You might even want to just have a wrapping struct so you can just have a property

struct People: Codable {
   struct Person: Codable {
      var name: String
      var age: Int
    }
   var people: [Person]
}

let encodedArray = try JSONEncoder().encode(People.init(blah))

Appending seems to work on my end here. The following code compiles without error for me:

import Foundation

struct Person: Codable {
    let name: String
    let age: Int
}

let originalData = [ Person(name: "Alice", age: 23), Person(name: "Bob", age: 23) ]
let singleValueToAppend = Person(name: "Darth", age: 23)

var data = try! JSONEncoder().encode(originalData)
var dataString: String { return String(data: data, encoding: .utf8)! }
print(dataString)

data.append(try! JSONEncoder().encode(singleValueToAppend))
print(dataString)

Here’s the output, though:

[{"name":"Alice","age":23},{"name":"Bob","age":23}]
[{"name":"Alice","age":23},{"name":"Bob","age":23}]{"name":"Darth","age":23}

Note that instead of appending to the original array, it’s appending a new JSON object every time. I believe this is correct behaviour too since data is meant to be a binary representation with no knowledge of what the underlying data represents. To decode the final representation, you’re need a type that looks a bit like this:

This is probably not what you were looking, and I’m not sure if it’s even valid JSON.

Creating an array of events to encode, appending events to it, and encoding that once you’re done, is probably what you’re looking for.