iOS中如何做个代码生成器减少重复劳动?

代码生成器

前言

最近在为一个新项目搭建项目框架。网络层在iOS项目中的地位不言而喻,一个不可或缺的部分,它负责api请求,上传下载等通信功能。之前也曾在AFNetworking的基础上封装过网络库。但在发现了猿题库的网络库后,发现它提供了很强大的功能,比如链式请求,断点上传等功能,这次新项目决定尝试下。猿题库的地址:https://github.com/yuantiku/YTKNetwork
YTKNetwork虽然功能强大,但在使用过程中发现它的代码量比较大,到处是重复地复制粘贴。因为它是将每个网络请求都封装起来,即一个api对应一个网络请求类,而且将请求参数也作为成员变量封装起来。使用起来很不便。
最后尝试使用代码生成器的方式,配置好请求的各项参数,根据模板自动自成网络api类文件。
以下是具体实现方法和源码实例,也借此实例说明一下iOS中代码生成器的基本使用方法。

MGTemplateEngine

MGTemplateEngine是mac平台下的一个代码生成器工具,根据模板和数据自动生成结果。它的使用很简单,语法比较灵活。

NSString *name = @"zcj"

//Hellow {{ name }}!
//打印结果:Hellow zcj!

当然了,MGTemplateEngine也支持循环和条件判断,如下所示:

NSArray *arr = [NSArray arrayWithObjects:
                                @"matt", @"iain", @"neil", @"chris", @"steve", nil], @"guys"];

//{% for dude in guys %}
    Current dude is {{ dude | uppercase }}
{% /for %}
//打印结果:Current dude is matt
//Current dude is iain
//Current dude is neil
//Current dude is chris

Is 1 less than 2? {% if 1 < 2 %} Yes! {% else %} No? {% /if %}
//打印结果:Is 1 less than 2? Yes! 

这些是MGTemplateEngine基本的用法,MGTemplateEngine还提供更强大的规则和语法,详细信息请前往官方文档查询,地址:https://github.com/mattgemmell/MGTemplateEngine

代码生成器

我们看一下YTKNetwork的请求类是什么样的

// RegisterApi.h
#import "YTKRequest.h"

@interface RegisterApi : YTKRequest

- (id)initWithUsername:(NSString *)username password:(NSString *)password;

@end


// RegisterApi.m

#import "RegisterApi.h"

@implementation RegisterApi {
    NSString *_username;
    NSString *_password;
}

- (id)initWithUsername:(NSString *)username password:(NSString *)password {
    self = [super init];
    if (self) {
        _username = username;
        _password = password;
    }
    return self;
}

- (NSString *)requestUrl {
    // “ http://www.yuantiku.com ” 在 YTKNetworkConfig 中设置,这里只填除去域名剩余的网址信息
    return @"/iphone/register";
}

- (YTKRequestMethod)requestMethod {
    return YTKRequestMethodPOST;
}

- (id)requestArgument {
    return @{
        @"username": _username,
        @"password": _password
    };
}

@end

我们发现,这个类的内容格式比较固定,只有类名,成员变量名,url和请求类型是不固定的,这样我们就能使用代码生成器制作模板了。
先画个界面,放置一些需要输入的参数,包括类名,成员变量名,url和请求类型。
将用户输入的数据按一定的格式组织起来,放置到字典中。其中请求参数的数据结构是以键值对的格式放到数组中,具体请看源码。

    // Set up some variables for this specific template.
    NSDictionary *variables = [NSDictionary dictionaryWithObjectsAndKeys:
                               mArr, @"Param",
                               _classNameTF.stringValue, @"ClassName",
                               _urlTF.stringValue, @"Url",
                               [_typeCB objectValueOfSelectedItem], @"MethodType",
                               nil];

下面来做类的模板,这个类基本结构不变,将类名,成员变量名,url和请求类型等几处替换掉成变量形式,成员变量部分要根据输入的数据动态生成,代码如下:

//
//  {{ ClassName }}.m
//  ZCJNetworkCodeGenerateTool
//
//  Created by zcj on 2017/2/24.
//  Copyright © 2017年 zcj. All rights reserved.
//

#import "{{ ClassName }}.h"

@implementation {{ ClassName }} {
{% for p in Param %}
    {{ p.value }} *_{{ p.key }};
{% /for %}
}


- (id)init{% for p in Param %}With{{ p.key | capitalized }}:({{ p.value }} *){{ p.key }} {% /for %}{
    self = [super init];
    if (self) {
        {% for p in Param %}
        _{{ p.key }} = {{ p.key }};
        {% /for %}
    }
    return self;
}

- (NSString *)requestUrl {
    return @"{{ Url }}";
}

- (YTKRequestMethod)requestMethod {
    return {{ MethodType }};
}

- (id)requestArgument {

    return @{ {% for p in Param %}@"{{ p.key }}": _{{ p.key }}{% if Param.@lastObject.key equalsString p.key %}{% else %}, {% /if %}{% /for %}};
}
@end

总结

最后放上实例源码:https://github.com/superzcj/ZCJTemplateTool
代码生成器的实现还是比较简单的,了解一下MGTemplateEngine的语法和规则,很容易写出自己的代码生成器。利用MGTemplateEngine之类的工具可以帮助我们简化了大部分的重复性工作,节省大家的时间。
掌握了代码生成器的基本使用,我们就可以在遇到类似重复性任务场景,做出自己的自动化处理方法。
如果觉得我的这篇文章对你有帮助,请在下方点个赞支持一下,谢谢!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容