iOS plus

InjectionIII神器-让代码所见即所得

2019-12-09  本文已影响0人  hj的简书

前言:iOS发开过程中,经常需要cmd+r进行编译、运行,然后跑到模拟器(手机)上。这在一个稍微大的项目上,是一个非常费时费力的操作。如果能够在项目编写完后,立刻看到目标效果,该是一件多么节约成本的事情。下面我将介绍InjectionIII,让iOS开发更简单~

在工程中使用InjectionIII

其实InjectionIII安装非常简单,只需要在app store中搜索InjectionIII即可下载

InjectionIII

有兴趣的可以到 github 查看更多文档。

在app工程中使用:

1.启动InjectionIII,并选择要检测的项目

Open Project 选择工程

2.在AppDelegate中的didFinishLaunchingWithOptions方法中,添加如下代码:

#if DEBUG
    [[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/iOSInjection.bundle"] load];
#endif

项目运行后,在xcode中会看到如下文字打印即表示监听成功


console打印

3.在UIViewController中,添加- injected方法,可以看到,在使用cmd+s的时候,模拟器会根据- injected中的修改,立刻更改界面。

技巧

可以创建一个InjectionIIIHelper(.gitignore中可以添加该文件),用来专门做拦截操作 :

+ (void)load {
#if DEBUG
    //注册项目启动监听
    __block id observer =
    [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidFinishLaunchingNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
        //bundlePath
        [[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/iOSInjection.bundle"] load];
        [[NSNotificationCenter defaultCenter] removeObserver:observer];
    }];
    class_addMethod([NSObject class], NSSelectorFromString(@"injected"), (IMP)injected, "v@:");
#endif
}

可以看到,在文件被载入到内存(+load)的时候,就进行了上述步骤2的操作。并且,在每个类对象添加了无返回值、无参数的injected方法(至于为什么是需要添加到类对象中,这个和OC运行时有关系,这里就不进行阐述了)。再进行如下代码拦截控制器和view,在cmd+s时响应loadView、viewDidLoad...等方法。

/**
 InjectionIII 热部署会调用的一个方法,
 runtime给VC绑定上之后,每次部署完就重新viewDidLoad
 */
void injected (id self, SEL _cmd) {
    //vc 刷新
    if ([self isKindOfClass:[UIViewController class]]) {
        [self loadView];
        [self viewDidLoad];
        [self viewWillLayoutSubviews];
        [self viewWillAppear:NO];
    }
    //view 刷新
    else if ([self isKindOfClass:[UIView class]]){
        UIViewController *vc = [InjectionIIIHelper viewControllerSupportView:self];
        if (vc && [vc isKindOfClass:[UIViewController class]]) {
            [vc loadView];
            [vc viewDidLoad];
            [vc viewWillLayoutSubviews];
            [vc viewWillAppear:NO];
        }
    }
}

如果不使用远程本地私有库的形式进行开发,上面的方法已经可以实现你的需求的。但是,如果使用到私有库开发环境,那么上面配置步骤还是需要进一步的修改。

在私有库中开发

通常,项目很大的时候,会通过远程本地私有库的形式,进行项目分发。但是,如果通过私有库方式编程时,我们会发现,尽管已经按了cmd+s,项目依然没有进行刷新。这是因为,项目路径和和私有库路径并不在同一个位置。

路径划分

我们需要做的就是将私有库内容和它的podspec复制一份,放到项目路径中。并且修改项目的Podfile指向改为_pod中的podspec

私有库路径配置 Podfile配置

但是,如果在git同步开发的时候,如果将_pod中的内容提交到git,只会增加git中的代码量,并不会更改私有库路径下的代码。因此,我们需要将_pod目录添加到.gitignore,并且将_pod目录里的修改的内容,自动同步到私有库目录下。那,怎么将_pod目录下的内容,自动同步到私有库中呢?

这里介绍一个工具fswatch,可以监听文件的修改:
安装方法如下

安装方法

创建一个脚本,监听修改、同步的内容:

watch_file=/Users/gtja/Documents/LocalLib/Example/_pod/LocalLib/
target_file=/Users/gtja/Documents/LocalLib/LocalLib/

# 将watch_file修改的内容,同步到target_file中
fswatch ${watch_file} | while read file;
do
    rsync -trl --delete ${watch_file}/ ${target_file}/
    echo "This file ${file} has changed."
done &

# 将从git拉取的内容同步到watch_file中
fswatch ${target_file} | while read file;
do
    rsync -trl --delete ${target_file}/ ${watch_file}/
    echo "This file ${file} has changed."
done &

在运行脚本后,可以看到,在私有库中开发的脚本,不仅可以运行到模拟器中,而且修改的代码,也自动添加到sourcetree(虽然修改的不是同一个文件)。

自动监听和同步

最后,分享一下我的测试代码和脚本(sync.sh):测试代码和脚本

上一篇下一篇

猜你喜欢

热点阅读