JsonMagic a Json to Model tool

V1.1.6 Update!

🧨🧨 Hi Da Pu Ben 🧨🧨 : 2021-02-06 v1.1.6 release!

Content:

  1. New Json to Objective-C function;
  2. Reconstruct the output part to make the custom output easier;

preface

JsonMagic is a Mac application for converting Json data into class-definition code. Conversion code can be many, including Swift, Kotlin, Java. There is also support for converting Kotlin Models to Swift Models. Suitable for clients, Java backend engineers, of course, if customized, as long as there are modeling requirements for development can be used.

The project is written by an individual in Swift and is open source. Interested coders can fork to their own tools. Code address point I, there are DMG files, you can directly download the use.

The outline of the article is as follows:

  1. Application background;
  2. Application characteristics;
  3. Usage introduction;
  4. Code framework & user-defined output;
  5. Conclusion;

Application background

The biggest original intention of the application is to reduce the repetitive and less technical work time of converting Json to Model in software development and improve development efficiency. Wages are not low in any industry, and working hours are precious. The extra time we can use to further learn technology to improve ourselves, or just watch NBA, brush B station, the mood is also very good.

The purpose of Json modeling is to make the data easy to read and process. Common in application development, the most common scenario is to transform server-side data into Model classes that are easy for the client to use. The conversion content mainly consists of two parts: first, the dictionary node is converted into a class; second, the key value in the dictionary is converted into the field name of the class, and the field type is the value type corresponding to the key.

This process is very mechanical and can be automatically converted by program. There are few tools in this aspect on iOS platform, and most of them are command line tools, which are not friendly enough for students who are used to interface development. The Android platform, however, has a number of useful tools, the best of which is the Android Studio plugin. The Json to Model process can be completed within Android Studio.

Why make your own new tools?

Summary: First, for iOS, there is no user-friendly tool; Secondly, all the tools on iOS and Android platforms are not good enough for the collation and fault tolerance of Json data. Mainly reflected in the comma, comments:

  1. The comma. The comma after the last object in an array, or the comma of the last property in an object, will be returned by current tools. For example: The following example cannot be generated

    {
    	"name": "zhang san"."address_list ": [{"code": 12345."receiver_name": "li si"."receiver_address": "Haidian District, Beijing"],},"city_code": "010",}Copy the code

    Where the illegal comma appears:

    1. } of the first element of address_list,
    2. Receiver_address: “Haidian District, Beijing “,
    3. “city_code”: “010”,
  2. The comments. JSON data is sometimes annotated to make it easier to read, and current tools on the market often report errors when parsing. For example: The following example cannot be generated

    {
    	"name": "zhang san"."address_list ": [{// Address code
    			"code": 12345."receiver_name": "li si".// Recipient name
    			"receiver_address": "Haidian District, Beijing" // Receiver address}]."city_code": "010" // City code
    }
    Copy the code

JsonMagic is to solve these two problems.

Application characteristics

JsonMagic features are summarized as follows:

  1. Common illegal comma fault tolerance;
  2. Specification comment fault tolerance;
  3. Unified iOS and Android. Integrate the conversion work of iOS and Android. Support Swift code, Kotlin code, Java code. It also supports conversion of Kotlin Model to Swift Model;
  4. Custom conversion capability. The code is open source and abstracts JSON, and developers only need to care about the final part of the transformation;
  5. Kotlin’s optional annotations. Can be selected or notSerializedName or JsonProperty;

Used to introduce

After the application is started, the interface is shown as follows:

The large area in the middle is the Json data input by the user on the left and the Model data generated on the right.

Other operation parts are divided into five chunks according to the marked numbers:

  1. Select the code you want to convert, the default is Swift. Json to Swift, Json to Kotlin… ;
  2. Suffixes can be specified; the default is Model; Need to fill in the name of Model, no suffix;
  3. Click Run to start generating, and the generated code is in the Model box. Success and failure states are displayed at the bottom;
  4. Operations on results. Such asCopy ModelCopy to clipboard. The latter is the build file;
  5. If you want to see what’s going on, you can click Log, it’ll pop up;

Success status diagram:

Failed status icon:

There are extra comments, commas, but parsing succeeded:

Code architecture & custom Modeling

The json-generated code is divided into three main processes, as shown in the figure below:

  • First, preprocess Json, check necessary input, remove comments, etc.

  • Second, convert Json to a custom object and save it using Jsonic.DataType.

    internal indirect enum DataType: Equatable {
            static func = = (lhs: Jsonic.DataType.rhs: Jsonic.DataType) -> Bool {
                return lhs.swiftDescription = = rhs.swiftDescription
            }
            
            case string, int, long, double, bool, unknown
            case array(itemType: DataType)
            case object(name: String, properties: [PropertyDefine])
            .
    Copy the code
  • Finally, different output codes are generated according to different generation types.

    public enum OutputType {
        public struct KotlinConfig {
            /// should output SerializedName
            var isSerializedNameEnable: Bool
            /// should output JsonProperty
            var isJsonPropertyEnable: Bool
        }
        
        case swift
        case kotlin(config: KotlinConfig)
        case java
        .
    Copy the code

Custom output

From an overall architecture perspective, custom Output only needs to be concerned with the last Output step. There are only two steps:

  1. Add an OutputType;
  2. Define class and property outputs;

Isn’t it easier than putting an elephant in a fridge

Take transferring to Swift as an example: Step 1 add Swift type:

public enum OutputType {
    .
    case swift
    case kotlin(config: KotlinConfig)
    case java
    .
Copy the code

Step 2, add custom Model conversion code (add SwiftOutput class and inherit Modelable interface) :

class SwiftOutput: Modelable {
    typealias ModelConfig = DefaultModelConfig
    
    func modelDescription(name: String.properties: [Jsonic.PropertyDefine].config: DefaultModelConfig?). -> String {
        var text = "class \(name): Codable {\n"
        for property in properties {
            let typeDescription = dataTypeDescription(type: property.type)
            text + = "    var \(property.name): \(typeDescription)?\n"
        }
        text + = "}"
        return text
    }
    
    func dataTypeDescription(type: Jsonic.DataType) -> String {
        switch type {
        case .string:
            return "String"
        case .int:
            return "Int"
        case .long:
            return "Int64"
        case .double:
            return "Double"
        case .bool:
            return "Bool"
        case .unknown:
            return "String"
        case .object(let name, _) :return name
        case .array(let itemType):
            let typeDescription = dataTypeDescription(type: itemType)
            return "Array<" + typeDescription + ">"}}}Copy the code

Modelable interface

The Modelable interface defines two methods that personalization output needs to be implemented:

protocol Modelable {
    associatedtype ModelConfig
    func modelDescription(name: String, properties: [Jsonic.PropertyDefine], config: ModelConfig?) -> String
    func dataTypeDescription(type: Jsonic.DataType) -> String
}
Copy the code

ModelDescription defines how to format the output Model;

DataTypeDescription defines formatted output for each base or high-level type;

ModelConfig is a customized personalized attribute configuration in the interface. Currently, only Kotlin conversion has it.

The last

I used Python to convert the Model a few years ago, and recently had the opportunity to interface it and rewrite it using Swift code. Code may have a bug, you can leave a message, I will repair as soon as possible. Of course, you can upgrade the code after fork, but I still hope to feedback any problems, so as to help more students. Happy Coding~