iOS 模板模式封装shell 解压、拷贝、删除命令
最近在开发一款Mac App的小工具,业务也很简单;公司有一套代码块的模板,需要给每个人使用。如果手动操作就是解压zip模板包,拷贝至/Users/$USER/Library/Developer/Xcode/UserData/CodeSnippets目录下,重启XCode就Ok。大佬说,我们要简化步骤,给你个zip包,拖入再点击按钮就Ok了,替换手动解压再拷贝到XCode路径下,做到自动化。
场景很简单:拖入文件拷贝至缓存->解压Zip包并拷贝至XCode的缓存路径->删除缓存。
为什么不直接拷贝到XCode路径下?我的想法是不随便在XCode的路径下操作文件,万一误删了呢,所以解压好再拷贝。
在XCode种的需要调用NSTask才能调用命令,代码如下:
NSTask * task = [[NSTask alloc] init];
task.launchPath = @"/bin/sh";//文件路径
task.arguments = runParam;
task.currentDirectoryPath = [[NSBundle mainBundle] resourcePath];
NSPipe *outputPipe = [NSPipe pipe];
[task setStandardOutput:outputPipe];
[task setStandardError:outputPipe];
NSFileHandle *readHandle = [outputPipe fileHandleForReading];
[task launch];
NSData *outputData = [readHandle readDataToEndOfFile];
NSString * outputString = [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding];
return outputString;
下面是命令的结构目录:

ClearCommand、UnzipCommand、CpCommand是继承自TaskCommand,每个命令都需要调用executeTask模板的方法,而每条命令的参数却不同。

getParams是抽象方法,在executeTask调用,要在子类中实现,以达到每条命令的参数不同
- (NSString *)executeTask{
NSArray * runParam = [self getParams];
NSString * result = [self executeTask:runParam];
NSLog(@"%@",result);
return result;
}
每个子类都需要实现getParams方法

命令调用也很简单,使用业务的分离
_cpTask = [CpCommand new];
_clearTask = [ClearCommand new];
[_cpTask executeTask];
[_clearTask executeTask];
总结:1.模板模式简单实用,对于一个复杂的业务逻辑,能清爽的抽出重复的逻辑,每个类的职责清晰。
2.对于一些重复的代码逻辑,写成模板模式真是太好不过。之前有个主题业务,有主题列表和主题详情页;在主题列表和主题详情页有下载和使用按钮,涉及登录、下载、使用、进度条、鉴权等逻辑,跳转会员订购的逻辑,跳转指定书籍订购,但又有点差异在详情页时下载并使用,而在列表页是下载。这个时候写成两份是灾难性的,你改bug的时候需要修改两份。这个时候把业务逻辑封装成模板在父类实现,更新不同的UI可放至子类实现。
3.工具的demo,有任何问题欢迎留言评论。