iOS:JSON转OC属性小工具

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: iOS:JSON转OC属性小工具

在iOS开发中,只要有网络模块,就需要数据模型的编写。在进行数据模型的解析和映射时,JSONModel是一个非常常用且优秀的第三方框架,之前有有过博客对其分析,地址如下:

JSONModel源码分析:https://my.oschina.net/u/2340880/blog/1787561

  无论使用什么第三方的JSON数据解析框架,我们都需要手动来编写数据模型类,这是一个十分机械性的体力活,本篇博客将介绍一个配合与JSONModel使用的自动生成属性脚本(支持类的嵌套)。

  本脚本采用的语言为JavaScript,采用JavaScript编写有两个好处,首先其可以在node环境运行,可以十分方便的操作文件,使用它可以直接将JSON文件转换成OC数据模型类。其次,它也十分容易在Web端运行,可以通过网页可视化的进行数据模型的转换。

  闲话少说,直接上源码:

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();

}
在终端使用如下指令直接运行此脚本:

node Tool.js /Users/jaki/Desktop/json.json
命令后面所跟的参数为JSON文件的路径,JSON文件内容如下:

{
"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文件,内容如下:

@protocol Geo @end

@interface Geo : JSONModel

@property(nonatomic,strong)NSString*description;

@property(nonatomic,strong)NSNumber*latitude;

@property(nonatomic,strong)NSNumber*longitude;

@end

@protocol Fields @end

@interface Fields : JSONModel

@property(nonatomic,strong)NSString*key;

@property(nonatomic,strong)NSString*value;

@end

@protocol Result @end

@interface Result : JSONModel

@property(nonatomic,strong)NSString*aid;

@property(nonatomic,strong)NSArray*audios;

@property(nonatomic,strong)NSString*avatar_url;

@property(nonatomic,strong)NSNumber*call_price;

@property(nonatomic,strong)NSString*cid;

@property(nonatomic,strong)NSString*cover_url;

@property(nonatomic,strong)NSString*created_on;

@property(nonatomic,strong)NSArray<Fields><Optional,Fields>fields;

@property(nonatomic,strong)Geo<Optional,Geo>*geo;

@property(nonatomic,strong)NSNumber*id;

@property(nonatomic,strong)NSNumber*message_price;

@property(nonatomic,strong)NSArray*photo_sets;

@property(nonatomic,strong)NSString*pid;

@property(nonatomic,strong)NSString*rid;

@property(nonatomic,strong)NSNumber*role_open;

@property(nonatomic,strong)NSString*sid;

@property(nonatomic,strong)NSNumber*status;

@property(nonatomic,strong)NSString*updated_on;

@property(nonatomic,strong)NSNumber*video_price;

@property(nonatomic,strong)NSArray*videos;

@property(nonatomic,strong)NSNumber*world_open;

@end

@protocol MyObject @end

@interface MyObject : JSONModel

@property(nonatomic,strong)NSNumber*code;

@property(nonatomic,strong)NSString*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

使用效果如下:

目录
相关文章
|
4月前
|
JSON 网络协议 JavaScript
站长在线工具箱网站JSON网页工具加解密编码制作网站源码
站长在线工具箱网站JSON网页工具加解密编码制作网站源码
71 2
|
1月前
|
JSON 数据格式
用来返回Json数据格式的工具--通用类
用来返回Json数据格式的工具--通用类
19 1
|
2月前
|
JSON Java fastjson
java小工具util系列3:JSON和实体类转换工具
java小工具util系列3:JSON和实体类转换工具
27 2
|
2月前
|
iOS开发 UED 开发者
iOS 手势中cancelsTouchesInView delaysTouchesBegan delaysTouchesEnded 三种属性的使用
iOS 手势中cancelsTouchesInView delaysTouchesBegan delaysTouchesEnded 三种属性的使用
93 9
|
2月前
|
iOS开发 Python
6-8|如何使用Python语言开发IOS混淆工具
6-8|如何使用Python语言开发IOS混淆工具
|
3月前
|
JSON Java 数据格式
【IO面试题 七】、 如果不用JSON工具,该如何实现对实体类的序列化?
除了JSON工具,实现实体类序列化可以采用Java原生序列化机制或第三方库如Protobuf、Thrift、Avro等。
|
3月前
|
Swift iOS开发
iOS开发-属性的内存管理
【8月更文挑战第12天】在iOS开发中,属性的内存管理至关重要,直接影响应用性能与稳定性。主要策略包括:`strong`(强引用),不维持对象生命期,可用于解除循环引用;`assign`(赋值),适用于基本数据类型及非指针对象属性;`copy`,复制对象而非引用,确保对象不变性。iOS采用引用计数管理内存,ARC(自动引用计数)自动处理引用增减,简化开发。为避免循环引用,可利用弱引用或Swift中的`[weak self]`。最佳实践包括:选择恰当的内存管理策略、减少不必要的强引用、及时释放不再使用的对象、注意block内存管理,并使用Xcode工具进行内存分析。
|
4月前
|
Java Android开发 iOS开发
探索安卓与iOS开发的差异性:平台、工具和用户体验的对比分析
【7月更文挑战第30天】在移动应用开发的广阔天地中,安卓和iOS两大平台各自占据着不可忽视的地位。本文将深入探讨这两大平台在开发环境、工具选择以及最终用户体验上的根本差异,并分析这些差异如何影响开发者的策略和用户的偏好。通过比较安卓的开放性与iOS的封闭性,我们将揭示不同平台下的开发哲学及其对生态系统的影响。
45 4
|
4月前
|
JSON 文字识别 数据格式
文本,文识11,解析OCR结果,paddOCR返回的数据,接口返回的数据有code,data,OCR返回是JSON的数据,得到JSON数据先安装依赖,Base64转换工具网站在21.14
文本,文识11,解析OCR结果,paddOCR返回的数据,接口返回的数据有code,data,OCR返回是JSON的数据,得到JSON数据先安装依赖,Base64转换工具网站在21.14
文本,文识11,解析OCR结果,paddOCR返回的数据,接口返回的数据有code,data,OCR返回是JSON的数据,得到JSON数据先安装依赖,Base64转换工具网站在21.14
|
4月前
|
开发工具 Android开发 数据安全/隐私保护
探索iOS与安卓应用开发的异同:技术、工具和市场趋势
在移动操作系统的广阔舞台上,iOS和安卓两大主角各自演绎着怎样的精彩?本文将深入剖析这两大平台在应用开发过程中的技术差异、开发工具的选择以及面对的市场环境。通过数据支撑和案例分析,我们将一窥这两个系统如何影响开发者的决策,并探讨它们未来的发展方向。