

开发一个简单的Pod Install 插件
source link: http://satanwoo.github.io/2016/02/27/pod-install-plugin/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

开发一个简单的Pod Install 插件
前几天刚刚粗略了学习了一下Xcode的插件开发,一时心痒,就准备做个简单的插件练练手。
哎哟我擦,正当我准备大展身手的时候,我突然想到我该做个啥呢? 我这真是有了程序员,只差一个好Idea了。
好吧,正巧这个时候,我发现我和朋友协作的一个iOS项目在两个分支上同步开发,每次要合并后拉下分支,都发现Pod.lock文件都产生了变化,无法编译成功。每当这个时候,我都要进入terminal
输入一大堆的cd ..
进入对应的文件目录执行pod install
命令,甚是繁琐。
当然啦,你可以通过alias
配置快速的执行命令,但是,你仍然得切换出Xcode的窗口,对于我们这种效率控来说不能接受。
所以,我就想到了,在Xcode中利用插件集成一下关于pod的一些功能,同时绑定快捷键提高操作效率。
说干就干。
首先我们利用Xcode的plugin template生成项目的一些基本流程结构。关于插件的具体思路可以参考我之前的一篇文章《DXXcodeConsoleUnicodePlugin源码解析》
在这里,我们着重介绍一下利用 NSTask
去执行诸如pod install
这样的命令。
在实现真正的Objective-C
代码之前,我们首先现在terminal
中随便找个安全的目录敲入pod install
来试试看结果,如下所说:
pod install
[!] No `Podfile' found in the project directory.
从这个错误提示中我们可以大致了解,pod install
的命令依赖于所谓的Podfile
。于是,我们输入pod install --help
查看其对应的帮助手册:
--project-directory=/project/dir/ The path to the root of the project
directory
--no-clean Leave SCM dirs like `.git` and `.svn`
intact after downloading
--no-integrate Skip integration of the Pods libraries
in the Xcode project(s)
--no-repo-update Skip running `pod repo update` before
install
--silent Show nothing
--verbose Show more debugging information
--no-ansi Show output without ANSI codes
--help Show help banner of specified command
从第一条帮助命令张,我们可以看到,我们需要通过–project-directory=来设置pod install
的根目录,也即Podfile
的所在。
好,事情到这里,我们在编写插件前需要的准备工作就基本完成了,我们现在只需利用NSTask
将我们在命令行中输入的命令执行即可。
让我们来看看实现的代码:
// 1.
[self searchMainProjectPath];
// 2.
NSTask *podInstallAction = [[NSTask alloc] init];
podInstallAction.currentDirectoryPath = self.mainProjectPath;
podInstallAction.arguments = @[@"install"];
podInstallAction.launchPath = @"/usr/bin/pod";
// 3.
NSPipe *pipeOut = [NSPipe pipe];
[podInstallAction setStandardOutput:pipeOut];
NSFileHandle *output = [pipeOut fileHandleForReading];
[output setReadabilityHandler:^(NSFileHandle * _Nonnull fileHandler) {
NSData *data = [fileHandler availableData];
NSString *text = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(@"text is %@", text);
}];
[podInstallAction launch];
[podInstallAction waitUntilExit];
- 我们首先要寻找到当前项目的主目录,也就是
Podfile
的路径 - 然后我们构建NSTask,将其的执行目录设置成我们的主目录,然后
/usr/bin
中调出pod
的可执行文件,执行pod install
。 - 我们利用NSPipe将默认的NSTask的输出(stdout)重定向到我们的指定的地方,这样有助于我们查看log或者进行流程工程。
到这里,基本上一个简单的小插件就完成了,但是我在这里想要强调一点关于主工程路径搜索的一些问题,我们首先来看代码:
NSArray *workspaceWindowControllers = [NSClassFromString(@"IDEWorkspaceWindowController") workspaceWindowControllers];
[workspaceWindowControllers enumerateObjectsUsingBlock:^(id controller, NSUInteger idx, BOOL *stop) {
if ([[controller valueForKey:@"window"] isMainWindow]) {
id workspace = [controller valueForKey:@"_workspace"];
NSString *filePath = [[workspace valueForKey:@"representingFilePath"] valueForKey:@"pathString"];
NSString *projectName = [[filePath lastPathComponent] stringByDeletingPathExtension];
NSLog(@"CocoaPodUI::ProjectName::%@", projectName);
NSString *text = [[filePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"Podfile"];
self.mainProjectPath = [filePath stringByDeletingLastPathComponent];
NSLog(@"pod ifle is %@", text);
}
}];
基于Xcode的插件开发实际上利用了大量的私有头文件。由于Objective-C著名的runtime特性,因此,很多时候,我们可以利用key-value-coding的方式获取我们普通途径下无法得到的结果。
同时,当有一个类的方法是私有方法的时候,你可以利用一个category
声明同样的函数签名,不需要实现,Objective-C
的runtime会自动帮你转发对应的message passing
。。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK