在iOS開發中,只要有網絡模塊,就須要數據模型的編寫。在進行數據模型的解析和映射時,JSONModel是一個很是經常使用且優秀的第三方框架,以前有有過博客對其分析,地址以下:javascript
JSONModel源碼分析:http://www.javashuo.com/article/p-vrnocope-bt.html。html
不管使用什麼第三方的JSON數據解析框架,咱們都須要手動來編寫數據模型類,這是一個十分機械性的體力活,本篇博客將介紹一個配合與JSONModel使用的自動生成屬性腳本(支持類的嵌套)。java
本腳本採用的語言爲JavaScript,採用JavaScript編寫有兩個好處,首先其能夠在node環境運行,能夠十分方便的操做文件,使用它能夠直接將JSON文件轉換成OC數據模型類。其次,它也十分容易在Web端運行,能夠經過網頁可視化的進行數據模型的轉換。node
閒話少說,直接上源碼:ios
var fileManager = require('fs'); var gettype=Object.prototype.toString; String.prototype.firstUpperCase = function(){ return this.replace(/\b(\w)(\w*)/g, function($0, $1, $2) { return $1.toUpperCase() + $2.toLowerCase(); }); } var arguments = process.argv.splice(2); var path = arguments[0]; if (!path) { console.log("請傳入要轉換的JSON文件路徑"); return; } console.log('json文件路徑:', path); try{ var result = JSON.parse(fileManager.readFileSync(path)); }catch(error){ console.log("解析JSON文件失敗:"+error); return; } if (!result) { console.log("解析JSON文件無效"); return; } var classArray = new Array(); parseObject("MyObject",result); var stringAll=""; //輸出 for (var i = classArray.length-1; i >=0 ; i--) { let cla = classArray[i]; stringAll+="@protocol "+cla.name+" @end\r\n\r\n@interface "+cla.name+" : JSONModel\r\n\r\n"; console.log("@protocol "+cla.name+" @end\r\n\r\n@interface "+cla.name+" : JSONModel\r\n\r\n"); for (var j = 0; j < cla.property.length; j++) { stringAll+=cla.property[j]+"\r\n\r\n"; console.log(cla.property[j]+"\r\n\r\n"); } stringAll+="@end\r\n\r\n"; console.log("@end\r\n\r\n"); } stringAll+="===========m文件======================\r\n"; console.log("===========m文件======================\r\n"); for (var i = classArray.length-1; i >=0 ; i--) { let cla = classArray[i]; stringAll+="@implementation "+cla.name+"\r\n\r\n@end\r\n\r\n"; console.log("@implementation "+cla.name+"\r\n\r\n@end\r\n\r\n"); } let paths = path.split("/"); paths.pop(); let newPath = paths.join("/")+"/oc.txt"; fileManager.writeFileSync(newPath,stringAll); //核心解析函數 function parseObject(k,result){ let c = new Class(k); classArray.push(c); for (var i = 0; i < Object.getOwnPropertyNames(result).length; i++) { let key = Object.getOwnPropertyNames(result)[i]; let value = result[key]; let type = getType(value); if(type==null){ continue; } if (type=="Object") { //進行二次解析 if (Object.getOwnPropertyNames(value).length==0) { c.property.push("@property(nonatomic,strong)NSDictionary<Optional>*"+key+";"); }else{ parseObject(key.firstUpperCase(),value); c.property.push("@property(nonatomic,strong)"+key.firstUpperCase()+"<Optional,"+key.firstUpperCase()+">*"+key+";"); } continue; } if (type=="Array") { if (value.length>0) { let obj = value[0]; let t = getType(obj); if (t==null) { continue; } if (t=="Object") { c.property.push("@property(nonatomic,strong)NSArray<"+key.firstUpperCase()+"*><Optional,"+key.firstUpperCase()+">*"+key+";"); parseObject(key.firstUpperCase(),obj); }else{ c.property.push("@property(nonatomic,strong)NSArray<"+t+"*><Optional>*"+key+";"); } }else{ c.property.push("@property(nonatomic,strong)NSArray<Optional>*"+key+";"); } continue; } if (type=="id") { c.property.push("@property(nonatomic,strong)"+type+"<Optional>"+key+";"); continue; } c.property.push("@property(nonatomic,strong)"+type+"<Optional>*"+key+";"); } } //獲取要轉換的類型 function getType(obj){ if (typeof obj == 'number') { return "NSNumber"; } if (typeof obj == 'undefined') { return "id"; } if (typeof obj == 'null') { return "id"; } if (typeof obj == 'function') { return null; } if (typeof obj == 'string') { return "NSString" } if (typeof obj == 'boolean') { return "NSNumber" } if (typeof obj == 'object') { if (gettype.call(obj)=="[object Object]") { return "Object"; } if (gettype.call(obj)=="[object Array]") { return "Array"; } if (gettype.call(obj)=="[object Null]"){ return "id"; } } } //類 function Class(name){ this.name = name; this.property = new Array(); }
在終端使用以下指令直接運行此腳本:git
node Tool.js /Users/jaki/Desktop/json.json
命令後面所跟的參數爲JSON文件的路徑,JSON文件內容以下:github
{ "code": 0, "message": "", "result": { "aid": "be3bdab8-fbf5-4e89-97cb-56b00048b09b", "audios": [], "avatar_url": "https://www.google.com/a.jpg", "call_price": 0, "cid": "efad6549-be62-40d7-a425-40f9b7730192", "cover_url": "https://www.google.com/a.jpg", "created_on": "1528349104", "fields": [ { "key": "name", "value": "Mr.Wang" }, { "key": "company", "value": "TicTalk" }, { "key": "position", "value": "Senior Engineer" } ], "geo": { "description": "Shanghai, China", "latitude": 48.82694828196076, "longitude": 2.367038433387592 }, "id": 2, "message_price": 0, "photo_sets": [], "pid": "9b64395f-687c-4f34-9a5d-68d9adafa4cc", "rid": "578ff973-c707-42b2-bfc2-87e4dc8e0efd", "role_open": false, "sid": "8f560338-dfa5-48be-b44c-65fd87798543", "status": 0, "updated_on": "1528349104", "video_price": 0, "videos": [], "world_open": true } }
運行後,能夠看到在JSON文件同一目錄下生成了oc.txt文件,內容以下:json
@protocol Geo @end @interface Geo : JSONModel @property(nonatomic,strong)NSString<Optional>*description; @property(nonatomic,strong)NSNumber<Optional>*latitude; @property(nonatomic,strong)NSNumber<Optional>*longitude; @end @protocol Fields @end @interface Fields : JSONModel @property(nonatomic,strong)NSString<Optional>*key; @property(nonatomic,strong)NSString<Optional>*value; @end @protocol Result @end @interface Result : JSONModel @property(nonatomic,strong)NSString<Optional>*aid; @property(nonatomic,strong)NSArray<Optional>*audios; @property(nonatomic,strong)NSString<Optional>*avatar_url; @property(nonatomic,strong)NSNumber<Optional>*call_price; @property(nonatomic,strong)NSString<Optional>*cid; @property(nonatomic,strong)NSString<Optional>*cover_url; @property(nonatomic,strong)NSString<Optional>*created_on; @property(nonatomic,strong)NSArray<Fields*><Optional,Fields>*fields; @property(nonatomic,strong)Geo<Optional,Geo>*geo; @property(nonatomic,strong)NSNumber<Optional>*id; @property(nonatomic,strong)NSNumber<Optional>*message_price; @property(nonatomic,strong)NSArray<Optional>*photo_sets; @property(nonatomic,strong)NSString<Optional>*pid; @property(nonatomic,strong)NSString<Optional>*rid; @property(nonatomic,strong)NSNumber<Optional>*role_open; @property(nonatomic,strong)NSString<Optional>*sid; @property(nonatomic,strong)NSNumber<Optional>*status; @property(nonatomic,strong)NSString<Optional>*updated_on; @property(nonatomic,strong)NSNumber<Optional>*video_price; @property(nonatomic,strong)NSArray<Optional>*videos; @property(nonatomic,strong)NSNumber<Optional>*world_open; @end @protocol MyObject @end @interface MyObject : JSONModel @property(nonatomic,strong)NSNumber<Optional>*code; @property(nonatomic,strong)NSString<Optional>*message; @property(nonatomic,strong)Result<Optional,Result>*result; @end ===========m文件====================== @implementation Geo @end @implementation Fields @end @implementation Result @end @implementation MyObject @end
後面咱們只須要將類名調整成所須要的便可。網絡
下面是一個即用的網頁轉換器,採用的腳本代碼和上面的代碼基本一致:框架
http://zyhshao.github.io/JSONToOC.html
使用效果以下:
熱愛技術,熱愛生活中有趣的事務,互相交流,也在朋友 QQ:316045346
——琿少