InjectionIII神器-讓代碼所見即所得

前言: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):測試代碼和腳本

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。