zoukankan      html  css  js  c++  java
  • HokeyPokey — WWDC讲师特供XCode插件高仿版的设计与实现

       在我们使用XCode IDE做iOS技术分享的时候,经常会涉及到多个方案的运行效果比较。切换不同的演示方案通常有如下三种方法:1.分成多个XCode项目;2.分成多个版本Branch 3.手动去注释掉非本次运行方案的代码块。这三种方案在灵活性和操作速度及方便性上,或多或少有些差强人意。那么,有没有更好的方法呢?看多了WWDC视频的童鞋或许会注意到这个名字:Hokey Pokey, 中文是变戏法的意思,WWDC讲师在切换不同的演示方案时,快捷键唤起一个浮窗,在浮窗中勾选不同的演示代码块。笔者编码实现的正是这样一款WWDC讲师特供XCode插件的高(简易)仿(山寨)版(货)。

      在线维护:https://github.com/1962449521/HokeyPokey

    一、HokeyPokey插件的效果演示

      HokeyPokey菜单项安装在Xcode View -> HokeyPokey中。有[Hide/Show]、[Make]、[Resume]三个功能项,分别用于展示/销毁HokeyPokey工作窗口、将当前操作文件编译至hokey pokey 管理数据库、撤销当前文件的所有hokey pokey操作及数据库。工作窗口右上角放有按钮,用于切换窗口是否永远在最前面。相同运行方案名的分散代码块将被归为一个列表行。对某个方案的选择通过双击列表项来实现。三个功能项的快捷键、工作窗口的表头提供了方案定制,稍后介绍。

     

    二、使用该插件目前版本需注意的地方

      1. 尽量只打开一个XCode窗口、在一个XCode窗口中只打开一个Tab项。这里存在的问题是在切换XCode窗口或Tab项时,HokeyPokey窗口没有同步更新,双击其中列表项时,会将最初文件操作结果写入到新的代码编辑区。

      2. 撤销HokeyPokey操作需逐个文件进行(第三个功能项Resume)。当只打开一个Xcode窗口一个Tab项时,HokeyPokey窗口会根据文件的切换自动更新。操作粒度为一个文件而不是一个工程,因此当需要撤销所有HokeyPokey操作时需逐个切换到操作过的文件,逐个撤销。

      3. 编辑文件时,需先撤销该文件的HokeyPokey更改(部分代码被隐藏),然后修改后,再编译至HokeyPokey数据库(第二个功能项Make)。

      4. 右上角的dock/normal可以切换HokeyPokey窗口是否永远保持最前面

    三、关于插件的安装和自定义设置

      该插件运行即安装,从github下载插件工程到本地,使用默认设置或更改设置文件后,运行XCode项目即可。自定义设置涉及的文件为HPKConst.h,具体如下图。可以更识别标志、案、快捷键等。该插件作为开源欢迎及希望童鞋们更改、使用、传播和多提意见。但本着尊重出发请不要修改插件名、作者声明等,

    #ifndef HPKConst_h
    #define HPKConst_h
    
    // ------------ hokeypokey识别的开始和结束标志
    #define HPKStartStringTag             @"//hokey"
    #define HPKEndStringTag               @"//pokey"
    
    // ------------ 表头和窗口状态切换的UI文案
    #define HPKHeaderTitle4Show           @"SHOW"
    #define HPKHeaderTitle4Identifier     @"IDENTIFIER"
    
    #define HPKLabel4WindowDock           @"dock"
    #define HPKLable4WindowNormal         @"normal"
    
    // ------------ 快捷键设置
    #define HPKRequireKey4HideShow        @YES
    #define HPKKeyEquivalent4HideShow     @"h"
    #define HPKKeyMask4HideShow           NSShiftKeyMask | NSCommandKeyMask
    
    #define HPKRequireKey4Make            @YES
    #define HPKKeyEquivalent4Make         @"w"
    #define HPKKeyMask4Make               NSShiftKeyMask | NSCommandKeyMask
    
    #define HPKRequireKey4Resume          @YES
    #define HPKKeyEquivalent4Resume       @"x"
    #define HPKKeyMask4Resume             NSShiftKeyMask | NSCommandKeyMask
    
    // ------------ 以下请勿更改
    #define HPKIsShownKey                 @"isShow"
    #define HPKTitleKey                   @"identifier"
    #define HPKPockyResultsKey            @"pockyResultsKey"
    #define HPKFileURLKey                 @"fileURLKey"
    
    #endif /* HPKConst_h */

    四、插件的需求和功能分析

      1. 使用场景和需求分析

      在技术分享或授课时,用于Xcode项目的运行方案区分与切换。需要与文章开始时提到的三种方法作比较,达到更加易用,省时的目的。

      2. 功能分析

      首先要求用户给出格式化的textView并触发hokeypokey编译。用户使用格式化的标志,即用识别开始标志(如//hokey) 和识别结束标志(//pokey)将一个TextView内容分隔成若干块。开始标识和结束标识之间用于存放不同方案的特有代码块,其它隔断为共用的代码块。

      在这个格式前提下,插件开发的最基本功能,可以细化至以下几项:

      a. 提取出方案特有代码块。给定格式字符串,提取出方案特有代码块的字符串、所在初始字符串中的Range,以及各代码块的方案名(标识) ;

      b. 运算得出对应方案的可运行代码。给定格式字符串和hokeypokey提取结果,给定不同的方案名选择时,能运算得出对应方案的可运行代码;

      c. 当前方案选择可视化。给出GUI显示,将提取结果绘制至列表控件,并在UI上给出提示各块显示与否的提示;

      d. 提供方案切换方法。GUI允许用户交互,在列表项双击时,能够切换方案选择状态、XCode代码编辑区显示和物理文档。

     

    五、插件的设计与实现

      功能点a、b的实现通过给NSString添加Category方法,类设计如下,对应功能a、b分别提供了两个实例方法,并设计了HPKSearchResult模型用于存放分块结果。

    @interface HPKSearchResult : NSObject
    
    @property (nonatomic, strong) NSString *title;
    @property (nonatomic, assign) NSRange  range;
    @property (nonatomic, strong) NSString *string;
    
    -(instancetype) initWithRange:(NSRange)aRange string:(NSString *)aString title:(NSString *)aTitle;
    
    @end
    
    
    @interface NSString (HPKTextGetter)
    
    - (NSArray<HPKSearchResult *> *) HPK_textResultsWithPairOpenString:(NSString *)open
                                                           closeString:(NSString *)close;
    
    - (NSString *) HPK_stringBySubtractSearchResults:(NSArray<HPKSearchResult *> *) searchResults;
    
    @end

      功能c、d主要通过一个自定义窗口以及Cocoa Binding来实现,类设计如下。窗口的标题windowTitle和列表内容cotentArray需要随着当前操作文件的变化而变化。数据源由管理类HPKPluginMain提供,这里简单起见,直接将tableView、windowTitle、contentArray等属性暴露出来,由管理类HPKPluginMain直接操作。该窗口类绑定了用户对列表的双击动作,从而更新HokeyPokey窗口列表及将操作提交到管理类HPKPluginMain作实质操作。

    #import <Cocoa/Cocoa.h>
    
    @class HPKPluginMain;
    @interface HPKWindowController : NSWindowController
    
    @property (weak) HPKPluginMain *pluginMain;// 插件管理对象
    @property (weak) IBOutlet NSTableView *tableView;// 插件窗口主控件
    
    // 文案内容绑定
    @property (strong)  NSString *windowTitle;
    @property (strong)  IBOutlet NSArrayController *contentArray;
    
    // 用户双击事件绑定
    - (void) inspect:(NSArray *)selectedObjects;
    
    @end
    
    @interface HPKWindowController () <NSTableViewDelegate>
    
    // 文案内容绑定
    @property (strong)  NSString *headerTitle4Show;
    @property (strong)  NSString *headerTitle4Identifier;
    
    // 切换窗口显示是否悬浮按钮
    @property (weak) IBOutlet NSButton *btnDock;
    
    @end

       管理类的设计,首先是作为HokeyPokey窗口的数据源为其提供显示数据,第二是作为HokeyPokey窗口的委托,处理交互引起的业务逻辑。数据源方面主要用了两个字典来实现,其key值都是物理文件的url,originalTextDic存放其在编译HokeyPokey时的原始字符串,contentArrDic存放各文件对应的HokeyPokey提取结果。

    #import <Cocoa/Cocoa.h>
    
    @interface HPKPluginMain : NSObject
    
    /**
     *  根据用户对hokey pokey窗口的点击更新XCode显示和物理文档
     *
     *  @param editedTitle 要操作的方案名
     *  @param isShow      该方案是否显示
     */
    - (void) refreshEditorAndFileAtTiltle:(NSString *)editedTitle shouldShow:(BOOL)shouldShow;
    
    @end
    
    
    
    @interface HPKPluginMain() <NSWindowDelegate>
    
    // hokey pokey数据库
    @property (nonatomic, strong) NSMutableDictionary *originalTextDic;
    @property (nonatomic, strong) NSMutableDictionary *contentArrDic;
    
    // 代码编辑窗口
    @property (nonatomic, strong) DVTSourceTextView  *ideSourceTextView;
    @property (nonatomic, strong) IDEWorkspaceWindow *ideWorkspaceWindow;
    
    @property (nonatomic, strong) HPKWindowController *windowController;// 持有hokeypokey窗口
    @property (nonatomic, strong) WHUKVOController    *documentKVO;     // facebook的KVO类
    
    - (void) createHokeyPokeyMenu;  // 创建菜单
    - (void) createHokeyPokeyWindow;// 创建hokeypokey窗口
    - ( NSURL *) activeDocumentURL; // 返回当前编辑文档的地址
    - (void) refreshHokeyPokeyWindowWithURL:(NSURL *)url;// 刷新hokeypokey窗口的数据库源
    
    @end

    六、注意点和未完成的工作

      不要在平时开发中打开HokeyPokey窗口,以免误操作。

      只在技术分享、方案演示时使用,使用前一定要备份,以免忘记撤消,XCode关闭导致代码的丢失。

      使用时只打开一个XCode工程,一个Tab项。

      目前的文件切换是未支持Undo Manager的,可以用粘贴板和虚拟键值来实现。在关闭窗口之前,我们很可能忘记了HokeyPokey窗口有隐藏内容,是否需要在XCode退出时自动撤销所有HokeyPokey操作?同时打开多个XCode工程或Tab时是否需要做同步?这些问题将在以后的版本维护中逐渐解决。

  • 相关阅读:
    关于oracle的导入数据流程,以及错误解决
    解决 lombok 和 freemarker 下载慢问题 以及安装方法
    解决maven项目没有Maven Dependencies
    将maven仓库改为阿里仓库
    Dos攻击和校网渗透
    KaliLinux切换python版本
    Kali国内更新源
    linux安装jdk(.rpm)
    Centos 关于 mysql 命令
    Linux删除命令
  • 原文地址:https://www.cnblogs.com/hushuai-ios/p/5402037.html
Copyright © 2011-2022 走看看