JSON 自動生成HandyJson Model Class

本文銜接 如何將JavaScript轉化成Swift?(二) ,主要是關於將JavaScript的解析Json代碼翻譯到Swift當中?(如何將一段Json字符串自動生成HandyJson格式的Model類)git

將JavaScript的解析JSON代碼翻譯到Swiftgithub

JSON解析

{
    "error":0,
    "msg":"success",
    "data":[
        {
            "id":27,
            "name":"協議和幫助",
            "sname":"xy",
            "parent_id":"0",
            "flag":"0",
            "created":"2017-01-15 09:47:09",
            "tag":[
                1,
                5
            ],
            "dated":"2017-01-15 16:31:32"
        }
    ]
}
複製代碼

JavaScript 解析Json

JavaScript 中獲取 "name" 只須要一行代碼便可json

var jsonObj = str.parseJSON();
jsonObj.data[0].name
複製代碼

Swift 解析 Json

Swift中經常使用的JOSN解析庫有 HandyJson、ObjectMapper、SwiftyJsonswift

SwiftyJson 不要預先定義 Model Class 文件,可是不支持轉Mode,並且解析Json的語法和Js差別較大;數組

ObjectMapper Model類必須實現Mappable協議,即實現init和mapping函數;適合跟Alamofire配合。可是mapping函數過於臃腫耗時;bash

HandyJson 採用Swift反射+內存賦值的方式來構造Model實例,寫法簡便且能支持json和model互轉的需求,並且一直在更新維護,解析Json的語法和Js差別較小;app

結論: 採用HandyJson來進行Json解析!函數

如何生成HandyJson所須要的Model類?

這裏就直接貼代碼了。。。post

// 生成Swift的Model文件
var generateCode = function (jsonString, className) {
    var k = "";

    // 首字母大寫
    var toUpperVar = function (a) {
        return a.replace(/\b[a-z]/g, function (a) {
            return a.toUpperCase()
        })
    };

    // 小寫
    var toLowerVar = function (a) {
        return a.replace(/\b[a-z]/g, function (a) {
            return a.toLowerCase()
        })
    };

    // 判斷是否有嵌套的Model
    var q = function (a) {
        // 判斷是不是一個數組
        return a instanceof Object ? a.constructor.prototype.hasOwnProperty("push") : !1
    };

    var r = function (a) {
        // 判斷是不是一個數組
        return a instanceof Object ? !a.constructor.prototype.hasOwnProperty("push") : !1
    };

    // 生成 class
    var getClass = function (a, d) {
        let required = "\n required init() {}"
        return "class " + a + ": HandyJSON {\n" + d + required + "\n}"
    };

    // 生成變量
    var getVar = function (a, d) {
        return " var " + d + ": " + a + "\n"
    };

    // swift  解析 json
    var generateSwift = function (a, d) {
        var c = "";
        if (q(a)) {
            if (a.length > 0) {
                for (var e = a[0], f = a.length - 1; 0 <= f; f--) {
                    var b = a[f];
                    q(b) ? b.length > e.length && (e = b) :
                        r(b) && Object.keys(b).length > Object.keys(e).length && (e = b)
                }
                c += generateSwift(e, d)
            }
        } else if (r(a)) for (e in a) {
            b = a[e];
            var h = toUpperVar(e);
            f = toLowerVar(e);
            if (q(b)) {
                var g;
                // 獲取第一個
                0 < b.length && (g = b[0]);

                if ("string" === typeof g) {
                    c += getVar("[String]!", f);
                } else {
                    if ("number" === typeof g) {
                        // 判斷浮點數
                        if (0 <= b.toString().indexOf(".")) {
                            c += getVar("[Float]!", f);
                        } else {
                            c += getVar("[Int]!", f);
                        }
                    } else if ("boolean" === typeof g) {
                        c += getVar("[Bool]", f)
                    } else if ("object" === typeof g) {
                        h += "Item";
                        c += getVar("[" + h + "]!", f);
                        b = generateSwift(b, e);
                        if (0 < k.length) {
                            k += "\r\n\r\n" + getClass(h, b)
                        } else {
                            k = getClass(h, b)
                        }
                    }
                }
            } else {
                if (r(b)) {
                    b = generateSwift(b, e)
                    c += getVar(h, f)
                    k = 0 < k.length ? k + "\r\n\r\n" + getClass(h, b) : getClass(h, b)
                } else {
                    if ("string" === typeof b) {
                        c += getVar("String = ''", f)
                    } else if ("number" === typeof b) {
                        // 判斷浮點數
                        if (0 <= b.toString().indexOf(".")) {
                            c += getVar("Float = 0.0", f)
                        } else {
                            c += getVar("Int = 0", f)
                        }
                    } else if ("boolean" === typeof b) {
                        c += getVar("Bool = false", f)
                    }
                }
            }
        } else alert("key = " + d); return c
    };

    var swiftFunc = function (a, d) {
        k = ""
        0 == d.length && (d = "DefaultModelName");
        var c = generateSwift(a, d);
        k = 0 < k.length ? k + "\r\n\r\n" + getClass(d, c) : getClass(d, c);
        return k
    };

    return {
        swiftModel: function () {
            var d = eval("(" + jsonString + ")");
            return swiftFunc(d, toUpperVar(className))
        }
    }

};

exports.generateCode = generateCode;
複製代碼

如何調用?ui

var generateModel = require('./generateModel.js');
var fs = require("fs")
const { exec } = require('child_process');

var d = "{'error': 0,'msg': 'success','data': [{'id': 27,'name': '協議和幫助','sname': 'xy','parent_id': '0','flag': '0','created': '2017-01-15 09:47:09','tag':[1, 5], 'dated': '2017-01-15 16:31:32'}]}"

var fileName = "testModel"
var code = generateModel.generateCode(d, fileName).swiftModel();
console.log(code)


fs.writeFile('./Swift_Code/' + fileName + '.swift', code,  function(err) {
    if (err) {
        return console.error(err);
    }
 });
 
 // 格式化代碼
 exec('swiftformat ./Swift_Code/' + fileName + '.swift --swiftversion 4.2 ', (err, stdout, stderr) => {
     if(err) {
         return;
     }
 })
 
複製代碼

執行上述代碼便可生成以下文件:

class DataItem: HandyJSON {
    var id: Int = 0
    var name: String = ""
    var sname: String = ""
    var parent_id: String = ""
    var flag: String = ""
    var created: String = ""
    var tag: [Int]!
    var dated: String = ""

    required init() {}
}

class TestModel: HandyJSON {
    var error: Int = 0
    var msg: String = ""
    var data: [DataItem]!

    required init() {}
}

複製代碼

這裏爲了不Optional解析發生Crash,因此都賦了一個默認值,總感受會有一點問題,後面再修改。。。

將JavaScript解析Json代碼翻譯成Swift

完成了Model的生成,將JavaScript的解析Json代碼解析翻譯成Swift就簡單不少了

jsonObj.data[0].name 甚至能夠不用修改直接翻譯便可 ~

最後貼上生成HandyJson的 代碼

如何將JavaScript轉化成Swift?(一)

如何將JavaScript轉化成Swift?(二)

相關文章
相關標籤/搜索