python 代码生成器 oc_iOS 移动端生成工具开发
原標題:iOS 移動端生成工具開發
之前有寫過一個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的文件并不會進行編譯, 僅作為資源文件存儲.
選擇設計模式
對于設計模式來說, 確實是看過不少相關類型的書籍, 一些常用的設計模式也是手到擒來, 這不, 對于代碼生成工具, 立馬能夠想到生成器模式, 哈哈, 是工廠模式和裝飾模式.
其實對于這些設計模式的命名其實感覺挺誤導人的, 什么責任鏈咯, 原型什么的, 其實看一遍代碼就懂得東西被吹的神神道道, 也是醉了.
通過設計模式的選擇后我們創建了SQBuilder和SQFileParser, 前者為工廠模式, 后者為裝飾模式.
@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層, 其他的都不需要操心啦~~
具體說明可以下載SQTemplate來進行共同探討.(https://github.com/coderZsq/coderZsq.project.oc)
鏈接:http://www.jianshu.com/p/cb36b36f90dd
iOS開發整理發布,轉載請聯系作者授權返回搜狐,查看更多
責任編輯:
總結
以上是生活随笔為你收集整理的python 代码生成器 oc_iOS 移动端生成工具开发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 辽宁舰过海峡 歼-11护卫轰-6K绕飞
- 下一篇: python requests超时时间_