A macOS app to convert JSON to Swift structs
j2sis a macOS app that converts
JSONdictionaries into Swift
structs.
No, yeah, that's it. You give
j2sa
jsonfile, and it gives you Swift
structs. You can pick if it outputs to one file or a n files for n
structs.
If you want to make it do anything else, you'll have to write some more code. I'll probably accept pull requests, but, you should probably look into other tools like Sourcery instead.
structs, right?
Yup.
Yeah.
j2swill also convert
snake_case_key_namesinto
camelCasePropertyNames, and if you have a key where the value is an array of of dictionaries, the key name will be — naively — depluralized (exact line of code may change, but look around there for the algorithm).
And, if your
JSONvalue is a string that's secretly a
Datein a format that
j2sunderstands (Currently:
ISO8601), the generated code will use the correct (
Date) type.
Also, an integer like
5is an
Intand a floating point number like
5.0is a
Double. Because, you know, thats how these things should work.
j2s.xcodeprojrequires Swift 4 (Xcode 9 or greater) to build. The code it outputs requires Swift 4. If you need Swift 3 support, try looking back in commit history for an older version.
j2scan take in the following
JSON:
{ "outer" : true, "nested" : { "what_if_i_want_to" : [ "boogie? wouldn't dream of stopping you" ], "when" : "2017-06-27T17:58:28+00:00", "cool" : true } }
and turn it into Swift code that looks like this:
public struct Root: Codable { public let nested: Nested public let outer: Boolpublic struct Nested: Codable { public let cool: Bool public let whatIfIWantTo: [String] public let when: Date private enum CodingKeys: String, CodingKey { case cool case whatIfIWantTo = "what_if_i_want_to" case when } }
}
// MARK: -
public extension Root { static func create(with data: Data) throws -> Root { return try JSONDecoder().decode(Root.self, from: data) }
static func create(with data: Data) throws -> [Root] { return try JSONDecoder().decode([Root].self, from: data) }
}
// MARK: -
public extension Root.Nested { static func create(with data: Data) throws -> Root.Nested { let decoder = JSONDecoder() decoder.dateDecodingStrategy = .iso8601 return try decoder.decode(Root.Nested.self, from: data) }
static func create(with data: Data) throws -> [Root.Nested] { let decoder = JSONDecoder() decoder.dateDecodingStrategy = .iso8601 return try decoder.decode([Root.Nested].self, from: data) }
}
Optionals? I heard Swift has
Optionals, but, I don't see any
Optionals.
Optionals are sort of handled by
j2s.
JSONdoesn't have
Optionals, so it's hard to map them over automatically.
While parsing, if
j2sis told to create the same
structmultiple times, it considers any properties that don't exist in both models to be
Optional.
The same is also true for properties that show up as
nulland as a
Type.
nulls are turned into
Any?.
Yeah. Usually happens in the case of an array of dictionaries. This
JSON:
{ "outer" : true, "nested" : { "im_going_to_" : [ "type? sure, but uncheck the \"Pretty-Print JSON\" box down there --v", "boogie? wouldn't dream of stopping you" ], "what" : "paste json here" } }
will generate this Swift code:
public struct Demo: Codable { public let nested: Nested public let outer: Boolpublic struct Nested: Codable { public let imGoingTo: [String] public let what: String private enum CodingKeys: String, CodingKey { case im_going_to_ = "imGoingTo" case what } } private enum CodingKeys: String, CodingKey { case nested case outer }
}
// MARK: -
public extension Nested { public static func create(with data: Data) throws -> Nested { return try JSONDecoder().decode(Nested.self, from: data) }
public static func create(with data: Data) throws -> [Nested] { return try JSONDecoder().decode([Nested].self, from: data) }
}
// MARK: -
public extension Demo { public static func create(with data: Data) throws -> Demo { return try JSONDecoder().decode(Demo.self, from: data) }
public static func create(with data: Data) throws -> [Demo] { return try JSONDecoder().decode([Demo].self, from: data) }
}
Seemed like a good idea. This was before
Codablewas a thing.
A
JSONdictionary with a key named
potatoes, where the value is a list of dictionaries will be given the Swift type
[Potato]. Similarly,
soliloquiesbecomes
[Soliloquy],
dwarvesand
[Dwarf], and so on. Depluralization is a giant
ifstatement though, so while
indicesbecomes
[Index],
matricesincorrectly becomes
matrex. If Anyone wanted to do some natural language processing to solve this, that would be cool.
Before you go, remember that
j2scode is released under a 2-Clause BSD License and all contributions and project activity should be in line with our Code of Conduct.