本文銜接 如何將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的 代碼