代码地址如下:
http://www.demodashi.com/demo/11284.html

一、准备工作

编译环境 xcode

用于生成冗余架构代码, 实现生成零耦合架构

二、程序实现

上个月的一篇移动端面向文档开发一文久违的被编辑推荐到了首页, 也引来了饿了么大神的关注, 虽然最后实力不济未被录用, 但也指明了我前进的方向. 从4月到现在从一个想法到一步步的实现, 感觉自己还是有充足的长进的, 今天我们继续来完善这个项目.

之前有写过一个python脚本的生成工具, 通过读取json文件进行代码的生成, 实际操作中部分使用者反映, json文件的可读性不是很好(明显是不熟悉json语法导致的), 以及需要生成多平台代码, 所以python并不是很熟练的我, 考虑再三还是写一个oc项目一劳永逸. 本文会涉及到一些平时开发并不会特别关注的知识点, 以及该生成工具的代码设计和使用方法.

选择项目类型

第一个脑中闪现的想法就是使用Command Line Tool命令行工具了, 不就是代码生成吗, 还要开启模拟器? 这不是逗咩...

但我们需要读取Template模板文件, 由于模板文件是不可编译的文件, 所以我们并不能直接将其拖入项目中来, 然后我想那就通过相对路径的方法来读取文件吧, 可惜的是我找了一圈都没有获取当前路径的api, 只有sandbox, 沙盒...

我想命令行工具还有沙盒这玩意? 好吧, 我试试通过Bundle进行获取吧, 试了很久获取到的都是null, 无语... 到Stack Overflow上一问, 命令行工具不支持自制Bundle的读取, 好吧, 我认了. 但我感觉这只是一个链接的问题, 应该是可以读取的, 可惜找不到可执行的方法, 无奈只有放弃.

被迫我们只能够选择Single View Application了, 只是万般无奈啊, 好吧, 对世事的妥协不也是生活中的一部分嘛...

选择配置文件

在配置文件上的选择其实比较简单, 既然是oc的项目, 选择读取最为简单的plist是最好的选择. 同时也比较容易配置.



进行了一些简单的配置, 这部分不是很清晰的同学可以前往 http://www.jianshu.com/p/47d565bf200e 进行了解.

配置完plist后我们将之前的模板一起放入bundle并引入工程.

知识点: 放入bundle的文件并不会进行编译, 仅作为资源文件存储.

选择设计模式

对于设计模式来说, 确实是看过不少相关类型的书籍, 一些常用的设计模式也是手到擒来, 这不, 对于代码生成工具, 立马能够想到生成器模式, 哈哈, 是工厂模式和装饰模式.

其实对于这些设计模式的命名其实感觉挺误导人的, 什么责任链咯, 原型什么的, 其实看一遍代码就懂得东西被吹的神神道道, 也是醉了.

通过设计模式的选择后我们创建了SQBuilderSQFileParser, 前者为工厂模式, 后者为装饰模式.

@interface SQBuilder : NSObject

@property (nonatomic,copy) NSString * user;
@property (nonatomic,copy) NSString * prefix;
@property (nonatomic,copy) NSString * module;
@property (nonatomic,strong) NSDictionary * parameter;
@property (nonatomic,strong) NSDictionary * dataList;
@property (nonatomic,strong) NSArray * actionList; + (void)runWithFileParser:(NSDictionary *)config success:(void (^)())success failure:(void (^)())failure; - (void)build; @end
+ (SQBuilder *)builderWithType:(SQBuilderType)builderType {

    switch (builderType) {
case SQBuilderTypeiOS:
return [SQBuilder_iOS new];
break;
case SQBuilderTypeAndroid:
return [SQBuilder_Android new];
break;
case SQBuilderTypeNone:
return [SQBuilder new];
break;
default:
break;
}
}

SQBuilder的头文件暴露了和plist中需要配置的属性以及加载SQFileParser文件解析类的方法. 通过工厂模式可以分配创建不同的类.

@interface SQFileParser : NSObject

+ (NSDictionary *)parser_plist_r;

+ (void)parser_rw:(NSString *)path code:(NSString *)code filename:(NSString *)filename header:(NSString *)header parameter:(NSMutableArray *)parameter;

@end
[SQBuilder runWithFileParser:[SQFileParser parser_plist_r] success:^{
title = @"Build Finished"; message = @"please view the floder on the desktop";
} failure:^{
title = @"Build Error!!!"; message = @"please enter the right builder type!!";
}];

SQFileParser的头文件暴露了读取不同文件类型的接口, 后续读取Excel表格类型仅需添加新的类型接口即可.

创建文件夹 Api

NSFileManager * manager = [NSFileManager defaultManager];
NSString * path = [NSString stringWithFormat:@"/Users/%@/Desktop/%@", self.user, self.module];
[manager createDirectoryAtPath:path withIntermediateDirectories:NO attributes:nil error:nil];

oc中创建文件夹的方式, 能找到的就只有这个了, 而且只能读取绝对路径, 但又不能读取当前文件路径, mac机的user每台机器都不一样, 真是坑啊, 像文件读写这种东西还是python写最为稳妥.

SQFileParser 代码分析

+ (NSDictionary *)parser_plist_r {

    NSBundle * bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"builder.bundle" ofType:nil]];
return [NSDictionary dictionaryWithContentsOfFile:[bundle pathForResource:@"config/config.plist" ofType:nil]];
}

通过子bundle进行读取/config.plist配置文件, 知识点: 当读取bundle深层结构时需要添加文件路径.

+ (NSString *)parser_r:(NSString *)filename code:(NSString *)code {

    NSBundle * bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"builder.bundle" ofType:nil]];
return [NSMutableString stringWithContentsOfFile:[bundle pathForResource:[NSString stringWithFormat:@"template/%@/%@", code, filename] ofType:nil] encoding:NSUTF8StringEncoding error:nil];
}

Templete文件的读取, 和上面的读取plist相同, 并没有什么不同之处.

static NSString * code;

+ (NSString *)replaceThougth:(NSString *)templete parameter:(NSMutableArray *)parameter {

    __block NSString * temp = templete;
[[parameter firstObject] enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) {
temp = [templete stringByReplacingOccurrencesOfString:key withString:obj];
}];
[parameter removeObjectAtIndex:0];
if (parameter.count) {
[SQFileParser replaceThougth:temp parameter:parameter];
} else {
code = temp;
}
return code;
}

写入新文件, 这个就要好好讲讲了, NSString的stringByReplacingOccurrencesOfString方法是会返回一个新的更改后的字符串但并不会改变原指针. 但如果需要替换很多处的话就需要链式调用多次, 真是丑, 一个字概括了所有的观点, 所以我在想有什么方法能够避免这个问题呢? 马上想的就是上述递归调用的方法啦, 哈哈.

+ (void)parser_rw:(NSString *)path code:(NSString *)code filename:(NSString *)filename header:(NSString *)header parameter:(NSMutableArray *)parameter {

    NSString * arch = [[filename componentsSeparatedByString:@"."]firstObject];
NSString * suffix = [[filename componentsSeparatedByString:@"."]lastObject];
NSString * filename_r = [NSString stringWithFormat:@"%@Template.%@", arch,suffix];
NSString * filename_w = [NSString stringWithFormat:@"%@/%@%@.%@", path,header,arch,suffix];
NSString * template = [SQFileParser parser_r:filename_r code:[code lowercaseString]];
[[SQFileParser replaceThougth:template parameter:parameter] writeToFile:filename_w atomically:YES encoding:NSUTF8StringEncoding error:nil];
}

这个方法是读写一体的, 根据拿到的配置参数, 拼接出输入文件名和输出文件名, 并进行文件的读取和写入.

SQBuilder

这个其实就没什么好讲的了, 自己去看代码即可, 仅是读取配置参数并动态生成方法的逻辑代码了.

如何使用?



打开终端输入pwd获取user信息,并填入plist配置文件, 并输入其他参数, 进行Run即可将代码生成至桌面. 以后开发的时候只需要关注View层, 其他的都不需要操心啦~~

三、运行效果

四、其他补充

项目代码结构图

就是上面的使用截图,另外也这里也补充项目截图:

iOS 移动端生成工具开发

代码地址如下:
http://www.demodashi.com/demo/11284.html

注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

iOS 移动端生成工具开发的更多相关文章

  1. H5类似易企秀/编辑器/页面制作/开发/生成工具/软件/源码/授权

    代码地址如下:http://www.demodashi.com/demo/14960.html 项目简介 H5DS (HTML5 Design software) 这是一款基于WEB的 H5制作工具. ...

  2. ChaosTool,iOS添加垃圾代码工具,代码混淆工具,代码生成器,史上最好用的垃圾代码添加工具,自己开发的小工具

    最近在H5游戏项目中需要添加垃圾代码作混淆,提高过审机率.手动添加太费时费力,在网上并没有找到合适的比较好的工具,就自己动手写了一个垃圾代码添加工具,命名为ChaosTool. 扣扣交流群:81171 ...

  3. Web 开发人员必备的随机 JSON 数据生成工具

    在 Web 开发中,经常会需要一些测试数据来测试接口或者功能时候正确.JSON Generator 就是这样一款生成随机 JSON 数据的在线工具,Web 开发人员必备,记得收藏和分享啊. 您可能感兴 ...

  4. 微信开发中access_token,js_ticket,时间戳,签名生成工具

    Access_token生成工具 工具地址:https://mp.weixin.qq.com/debug 这个工具主要用来验证和生成微信公众号access_token,主要有正确的app_id和app ...

  5. 基于 React 开发了一个 Markdown 文档站点生成工具

    Create React Doc 是一个使用 React 的 markdown 文档站点生成工具.就像 create-react-app 一样,开发者可以使用 Create React Doc 来开发 ...

  6. 移动端使用rem同时适应安卓ios手机原理解析,移动端响应式开发

    rem单位大家可能已经很熟悉,rem是随着html的字体大小来显示代表宽度的方法,我们怎样进行移动端响应式开发呢 浏览器默认的字体大小为16px 及1rem 等于 16px 如果我们想要使1rem等于 ...

  7. iOS:崩溃统计工具Crashlytics的使用

    一.介绍 随着苹果在世界火热起来,移动端app的开发如火如荼,同时催生出了一批对app进行统计的开发工具,诸如:国内的友盟统计.国外的Flurry移动端统计.国外的Crashlytics统计等,Cra ...

  8. iOS应用内付费(IAP)开发步骤列表

    iOS应用内付费(IAP)开发步骤列表 前两天和服务端同事一起,完成了应用内付费(以下简称IAP, In app purchase)的开发工作.步骤繁多,在此把开发步骤列表整理如下.因为只是步骤列表, ...

  9. python测试框架&&数据生成&&工具最全资源汇总

    xUnit frameworks 单元测试框架frameworks 框架unittest - python自带的单元测试库,开箱即用unittest2 - 加强版的单元测试框架,适用于Python 2 ...

随机推荐

  1. 安卓 内容提供者 sql 区别

    韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 内容提供者 用户只需关心 操作数据的url 就可以了. 实现 了 应用间 数据共享.可以操作数据 ...

  2. [BZOJ5248][九省联考2018]一双木棋(连通性DP,对抗搜索)

    5248: [2018多省省队联测]一双木棋 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 43  Solved: 34[Submit][Status ...

  3. 【高斯消元】CDOJ1785 曜酱的线性代数课堂(三)

    高斯消元求行列式板子. #include<cstdio> #include<cmath> #include<algorithm> #include<cstri ...

  4. 【推导】【找规律】【二分】hdu6154 CaoHaha's staff

    题意:网格图.给你一个格点多边形的面积,问你最少用多少条边(可以是单位线段或单位对角线),围出这么大的图形. 如果我们得到了用n条边围出的图形的最大面积f(n),那么二分一下就是答案. n为偶数时,显 ...

  5. 【组合计数】UVA - 11538 - Chess Queen

    考虑把皇后放在同一横排或者统一纵列,答案为nm(m-1)和nm(n-1),显然. 考虑同一对角线的情况不妨设,n<=m,对角线从左到右依次为1,2,3,...,n-1,n,n,n,...,n(m ...

  6. 【费用流】hdu5988 Coding Contest

    从源点向每个点连接容量为该点人数,费用为1的边, 把原图中的每条边拆成两条,一条容量为1,费用为1,另一条容量为ci-1,费用为1-pi 从每个点向汇点连接容量为该点面包数量,费用为1的边. 跑的费用 ...

  7. [转]java框架spring中的opensessioninview有什么作用

    在hibernate中使用load方法时,并未把数据真正获取时就关闭了session,当我们真正想获取数据时会迫使load加载数据,而此时 session已关闭,所以就会出现异常. 比较典型的是在MV ...

  8. Mac下的MySQL修改默认连接字符集

    进入命令行执行以下命令: sudo vim /etc/my.cnf [client] default-character-set=utf8 [mysqld] character-set-server= ...

  9. .net中的泛型

    泛型把类或方法的类型的确定推迟到实例化该类或方法的时候 ,也就是说刚开始声明是不指定类型,等到要使用(实例化)时再指定类型 泛型可以用于  类.方法.委托.事件等 下面先写一个简单的泛型 public ...

  10. 在Ubuntu Server上源码安装OpenERP 8.0,并配置wsgi和nginx运行环境

    原文: How to install OpenERP 8.0 Alpha on a fresh Debian / Ubuntu server. OpenERP的安装,可以有多种方式,通过添加源,到 h ...