关于
关于
Xcode
的插件已经层出不穷了。但笔者凭着兴趣也小有研究了一下。
由于Xcode
的控制台不支持数组和字典里的中文的值输出(更准确的说是输出为Unicode
编码),这让开发者(至少是我)在打印数据进行调试的时候很不方便也很不爽。故此写了一个Category
来解决这个问题(github地址点此)。只要把分类拖入到项目里就能让数组和字典里的中文打印正常。
不过,至少笔者觉得还是挺麻烦的。所以凭着兴趣研究了一下插件开发,并打算把这个小需求整成一个插件。然后装在Xcode
里一劳永逸。
开发
关于插件开发入门教程网上也有很多。总之大体就是先安装Xcode-Plugin-Template
然后再新建一个project
的时候选择xcode plugin
这样就把插件开发的基本框架给搭好了。(Xcode-Plugin-Template传输门)
但是,插件开发是不开放的,而苹果官方文档也没有。而网上给出大部分建议都是获取所有的通知名,然后根据名字去猜这些通知是做什么的。这样在开发过程中也是很大的阻碍,而我的需求是让控制台把Unicode
编码转成中文,所以我直接去看了别人写的开源,找我需要相关的代码。而核心代码则是参考的MCLog
插件(过滤控制台区域的插件)。
其中核心代码是叫一个IDEConsoleItem
的类,这个类是每次控制台输出信息的时候调用的,实例化的方法是initWithAdaptorType:content:kind:
。一开始我是写了method_exchangeImplementations
交换实现,然后在切入一套逻辑,根据KVC
取出content
里的内容(控制台的内容),然后在进行Unicode转码
,转码过后的字符串在利用KVC重新赋值content
即可。
但是...不尽人意,崩溃了。还不知道为什么,然后我尝试了一下method_getImplementation
先把IDEConsoleItem
的initWithAdaptorType:content:kind:
的IMP实现给保存起来,然后在method_setImplementation
重新设置它的IMP,在新的IMP里调用原有IMP,然后在Unicode
转码,既然就没报错了。。。核心参考代码如下:
//保存原有的IMP
IMP_IDEConsoleItem_initWithAdaptorType = method_getImplementation(class_getInstanceMethod(NSClassFromString(@"IDEConsoleItem"), @selector(initWithAdaptorType:content:kind:)));
//设置新的IMP method_setImplementation(class_getInstanceMethod(NSClassFromString(@"IDEConsoleItem"), @selector(initWithAdaptorType:content:kind:)), class_getMethodImplementation([P_ZXP_IDEConsoleItem class], @selector(initWithAdaptorType:content:kind:)));
IMP代码
- (id)initWithAdaptorType:(id)arg1 content:(id)arg2 kind:(int)arg3
{
id (*execIMP)(id,SEL,id,id,int) = (void *)IMP_IDEConsoleItem_initWithAdaptorType;
id item = execIMP(self, _cmd, arg1, arg2, arg3);
if (kZXPIsDecodeInConsole) {
NSString *logText = [item valueForKey:@"content"];
NSString *resultText = [ZXPUnicodeDecodePlugsForXcode convertUnicode:logText];
[item setValue:resultText forKey:@"content"];
}
return item;
}
最后
总之目前关于插件开发也没任何知识可分享的,就目前而言,笔者感觉需要实现那些需求,然后找拥有类似需求的插件直接去看源码,比去看通知名字猜想来的更实际一些。如果有关于插件开发这一块的大神指点,我也很乐意受教。最后附上插件(让Xcode支持中文的输出)地址以供学习,代码很简单,就一百行左右的代码https://github.com/biggercoffee/ZXPUnicodeDecodePlugsForXcode