Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/zadr/j2s
A macOS app to convert JSON to Swift structs
https://github.com/zadr/j2s
Last synced: 11 days ago
JSON representation
A macOS app to convert JSON to Swift structs
- Host: GitHub
- URL: https://github.com/zadr/j2s
- Owner: zadr
- License: other
- Created: 2017-01-01T02:14:33.000Z (almost 8 years ago)
- Default Branch: main
- Last Pushed: 2023-07-31T06:22:56.000Z (over 1 year ago)
- Last Synced: 2024-10-16T02:56:16.384Z (26 days ago)
- Language: Swift
- Homepage:
- Size: 2.17 MB
- Stars: 231
- Watchers: 6
- Forks: 13
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
- open-source-mac-os-apps - j2s - macOS app to convert JSON objects into Swift structs (currently targets Swift 4 and Codable). ![swift_icon] (Applications / Development)
- open-source-mac-os-apps - j2s - macOS app to convert JSON objects into Swift structs (currently targets Swift 4 and Codable). ![swift_icon] (Applications / Development)
- awesome-swift-macos-apps - j2s - macOS app to convert JSON objects into Swift structs (currently targets Swift 4 and Codable). (Development / JSON Parsing)
- awesome-swift-macos-apps - j2s - macOS app to convert JSON objects into Swift structs (currently targets Swift 4 and Codable). (Development / JSON Parsing)
README
## What's this?
`j2s` is a macOS app that converts [`JSON`](https://en.wikipedia.org/wiki/JSON) dictionaries into [Swift](https://swift.org) `struct`s.![Screenshot](Screenshot.png?raw=true)
## That's it? Can I make it do anything else?
No, yeah, that's it. You give `j2s` a `json` file, and it gives you Swift `struct`s. You can pick if it outputs to one file or a _n_ files for _n_ `struct`s.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](https://github.com/krzysztofzablocki/Sourcery) instead.
## Codable-compliant `struct`s, right?
Yup.## Cool
Yeah. `j2s` will also convert `snake_case_key_names` into `camelCasePropertyNames`, and if you have a key where the value is an array of of dictionaries, the key name will be — naively — [depluralized](https://github.com/zadr/j2s/blob/main/j2s/StringTransformations.swift#L14) (exact line of code may change, but look around there for the algorithm).And, if your `JSON` value is a string that's secretly a `Date` in a format that `j2s` understands (Currently: `ISO8601`), the generated code will use the correct (`Date`) type.
Also, an integer like `5` is an `Int` and a floating point number like `5.0` is a `Double`. Because, you know, thats how these things should work.
## What version of Swift does this target?
`j2s.xcodeproj` requires 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.## What's the generated code look like?
`j2s` can take in the following `JSON`:
```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:
```swift
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
}
}// 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)
}
}
```## What about `Optional`s? I heard Swift has `Optional`s, but, I don't see any `Optional`s.
`Optional`s are sort of handled by `j2s`. `JSON` doesn't have `Optional`s, so it's hard to map them over automatically.While parsing, if `j2s` is told to create the same `struct` multiple times, it considers any properties that don't exist in both models to be [`Optional`](http://swiftdoc.org/v3.0/type/Optional/).
The same is also true for properties that show up as `null` and as a `Type`.
`null`s are turned into `Any?`.
## Oh.
Yeah. Usually happens in the case of an array of dictionaries. This `JSON`:```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:
```swift
public struct Demo: Codable {
public let nested: Nested
public let outer: Boolpublic struct Nested: Codable {
public let imGoingTo: [String]
public let what: String
}
}// 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)
}
}
```## Why build this and not use some other tool?
Seemed like a good idea. This was before `Codable` was a thing.## Still hung up on depluralization? (Singularity?)
A `JSON` dictionary with a key named `potatoes`, where the value is a list of dictionaries will be given the Swift type `[Potato]`. Similarly, `soliloquies` becomes `[Soliloquy]`, `dwarves` and `[Dwarf]`, and so on. Depluralization is a giant `if` statement though, so while `indices` becomes `[Index]`, `matrices` incorrectly becomes `matrex`. If Anyone wanted to do some natural language processing to solve this, that would be cool.## Okay then
Before you go, remember that `j2s` code is released under a [2-Clause BSD License](LICENSE.md) and all contributions and project activity should be in line with our [Code of Conduct](CODE_OF_CONDUCT.md).