前言
最近在為一個新項目搭建項目框架惠拭。網(wǎng)絡(luò)層在iOS項目中的地位不言而喻,一個不可或缺的部分庸论,它負(fù)責(zé)api請求职辅,上傳下載等通信功能。之前也曾在AFNetworking的基礎(chǔ)上封裝過網(wǎng)絡(luò)庫聂示。但在發(fā)現(xiàn)了猿題庫的網(wǎng)絡(luò)庫后域携,發(fā)現(xiàn)它提供了很強大的功能,比如鏈?zhǔn)秸埱笥愫恚瑪帱c上傳等功能秀鞭,這次新項目決定嘗試下。猿題庫的地址:https://github.com/yuantiku/YTKNetwork
YTKNetwork雖然功能強大扛禽,但在使用過程中發(fā)現(xiàn)它的代碼量比較大锋边,到處是重復(fù)地復(fù)制粘貼。因為它是將每個網(wǎng)絡(luò)請求都封裝起來编曼,即一個api對應(yīng)一個網(wǎng)絡(luò)請求類豆巨,而且將請求參數(shù)也作為成員變量封裝起來。使用起來很不便掐场。
最后嘗試使用代碼生成器的方式搀矫,配置好請求的各項參數(shù),根據(jù)模板自動自成網(wǎng)絡(luò)api類文件刻肄。
以下是具體實現(xiàn)方法和源碼實例,也借此實例說明一下iOS中代碼生成器的基本使用方法融欧。
MGTemplateEngine
MGTemplateEngine是mac平臺下的一個代碼生成器工具敏弃,根據(jù)模板和數(shù)據(jù)自動生成結(jié)果。它的使用很簡單噪馏,語法比較靈活麦到。
NSString *name = @"zcj"
//Hellow {{ name }}!
//打印結(jié)果:Hellow zcj!
當(dāng)然了,MGTemplateEngine也支持循環(huán)和條件判斷欠肾,如下所示:
NSArray *arr = [NSArray arrayWithObjects:
@"matt", @"iain", @"neil", @"chris", @"steve", nil], @"guys"];
//{% for dude in guys %}
Current dude is {{ dude | uppercase }}
{% /for %}
//打印結(jié)果: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 %}
//打印結(jié)果:Is 1 less than 2? Yes!
這些是MGTemplateEngine基本的用法瓶颠,MGTemplateEngine還提供更強大的規(guī)則和語法,詳細(xì)信息請前往官方文檔查詢刺桃,地址: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 中設(shè)置,這里只填除去域名剩余的網(wǎng)址信息
return @"/iphone/register";
}
- (YTKRequestMethod)requestMethod {
return YTKRequestMethodPOST;
}
- (id)requestArgument {
return @{
@"username": _username,
@"password": _password
};
}
@end
我們發(fā)現(xiàn),這個類的內(nèi)容格式比較固定桃移,只有類名屋匕,成員變量名,url和請求類型是不固定的借杰,這樣我們就能使用代碼生成器制作模板了过吻。
先畫個界面,放置一些需要輸入的參數(shù)蔗衡,包括類名纤虽,成員變量名,url和請求類型绞惦。
將用戶輸入的數(shù)據(jù)按一定的格式組織起來逼纸,放置到字典中。其中請求參數(shù)的數(shù)據(jù)結(jié)構(gòu)是以鍵值對的格式放到數(shù)組中翩隧,具體請看源碼樊展。
// Set up some variables for this specific template.
NSDictionary *variables = [NSDictionary dictionaryWithObjectsAndKeys:
mArr, @"Param",
_classNameTF.stringValue, @"ClassName",
_urlTF.stringValue, @"Url",
[_typeCB objectValueOfSelectedItem], @"MethodType",
nil];
下面來做類的模板,這個類基本結(jié)構(gòu)不變堆生,將類名专缠,成員變量名,url和請求類型等幾處替換掉成變量形式淑仆,成員變量部分要根據(jù)輸入的數(shù)據(jù)動態(tài)生成涝婉,代碼如下:
//
// {{ 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
總結(jié)
最后放上實例源碼:https://github.com/superzcj/ZCJTemplateTool
代碼生成器的實現(xiàn)還是比較簡單的,了解一下MGTemplateEngine的語法和規(guī)則蔗怠,很容易寫出自己的代碼生成器墩弯。利用MGTemplateEngine之類的工具可以幫助我們簡化了大部分的重復(fù)性工作,節(jié)省大家的時間寞射。
掌握了代碼生成器的基本使用渔工,我們就可以在遇到類似重復(fù)性任務(wù)場景,做出自己的自動化處理方法桥温。
如果覺得我的這篇文章對你有幫助引矩,請在下方點個贊支持一下,謝謝!