本文衔接 如何将JavaScript转化成Swift?(二) ,主要是关于将JavaScript的解析Json代码翻译到Swift当中?(如何将一段Json字符串自动生成HandyJson格式的Model类)git
将JavaScript的解析JSON代码翻译到Swiftgithub
{
"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 中获取 "name" 只须要一行代码便可json
var jsonObj = str.parseJSON();
jsonObj.data[0].name
复制代码
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解析!函数
这里就直接贴代码了。。。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,因此都赋了一个默认值,总感受会有一点问题,后面再修改。。。
完成了Model的生成,将JavaScript的解析Json代码解析翻译成Swift就简单不少了
jsonObj.data[0].name
甚至能够不用修改直接翻译便可 ~
最后贴上生成HandyJson的 代码