Swift 和 OC 实现“热加载”

2018/6/20 posted in  iOS

众所周知,Google 推出的跨平台框架Flutter 有着很好的编译优势Flutter Hot Reload,每次改变之后,点击 reload 就会实现实时编译。那么其实我们也可以实现SwiftOC的实时编译。

InjectionIII

通过这个工具可以实现类似Flutter 的快速编译。

实现思路:

Injection 会监听源代码文件的变化,如果文件被改动了,Injection Server 就会执行 rebuildClass 重新进行编译、打包成动态库,也就是 .dylib 文件。编译、打包成动态库后使用 writeSting 方法通过 Socket 通知运行的 App。

安装方式

  1. Mac App Store下载安装

    屏幕快照 2019-03-27 下午4.26.20

  2. Github

    这个工具开发作者是John Holdsworth,作者已经开源了这个工具,地址是https://github.com/johnno1962/InjectionIII

我使用的是在Mac App Store安装的方式,这样比较方便一些,如果你想专研源码,可以去到 GitHub 去研究。

使用指南
  1. 打开工程

    安装之后打开会出现在 mac 的 menubar 点击打开你目标的工程文件的根目录。

    屏幕快照 2019-03-27 下午5.57.39

  2. 在 applicationDidFinishLaunching加载Injection包

    Xcode 10.1:

    #if DEBUG
    Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/iOSInjection10.bundle")?.load()
    //for tvOS:
    Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/tvOSInjection10.bundle")?.load()
    //Or for macOS:
    Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/macOSInjection10.bundle")?.load()
    #endif

    Xcode 10.2 and later:

    #if DEBUG
    Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/iOSInjection.bundle")?.load()
    //for tvOS:
    Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/tvOSInjection.bundle")?.load()
    //Or for macOS:
    Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/macOSInjection.bundle")?.load()
    #endif

上面是swift版本的NSBundle加载包,下面的代码是oc的实现方法

[[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/iOSInjection10.bundle"] load];
  1. 运行工程

    选择模拟器,cmd+R启动编译

  2. 修改文件注入代码

    每当对代码进行修改之后,一定要cmd+S保存(不然Injection不会分析变动以及替换符号)实现快速编译。不用重新 cmd+R。

注意事项

屏幕快照 2019-03-27 下午5.56.38

还有一点就是如果你在 menubar 打开了这个程式的File Watcher那么就只需要cmd+S 如果你没有开启这个功能,还要多一步命令control+=(同时按住 control 和 =)。

还有就是由于沙盒机智,这个方法只能使用在模拟器上,对真机无效。