本地版接入文档

SOT热更补丁生成是高度自动化的,设想一下,生成差异补丁是需要两个版本的代码,一个是已上线APP的代码,一个是本地修改过的代码,更准确地说是依赖它们编译的中间结果,所以需要对编译工具和流程做一些改变,这个只需要做一次。另外对于项目,需要特殊的编译设置,没有设置的Target不会受到任何影响,也无法对它热更,对需要热更的Target,需要添加一些编译选项。以示例工程「 ShipOTDemo 」为例,该工程可从github下载,包含两个Target,一个是主Target名为ShipOTDemo,一个是Swift代码的Framework,按下面步骤修改:

Step1: 下载SDK

「 下载SOT的SDK 」,解压至随意目录,如本例是/Users/sotsdk-1.0


Step2: 工具链修改

安装Xcode 12,替换clang, libtool, swift编译工具,选择自动 / 手动的方式,对所有项目通用,只需要做一次:

  • 自动: 在terminal运行命令:sh /Users/sotsdk-1.0/compile-script/install.sh, 会把SDK目录compile-script下的clang, libtool, swift等脚本安装到本地编译工具链里,需要输入root密码。 ...

    如果有报错,则可能是xcrun命令错误,需要先运行一下xcode-select --install安装xcode命令行工具,然后运行 sudo xcode-select --switch Xcode.app的路径,把”xcode.app的路径“改成你mac上的xcode的路径,例如我的是/Applications/Xcode.app。再运行install.sh脚本即可。

    可以自己检查一下是否安装成功,命令行运行:xcrun --find sot_link.sh,例如我的会得到结果 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/sot_link.sh,进入到该目录还能看到其余安装进去的脚本: ...

  • 手动:
    • 在terminal运行命令:xcrun --find clang 得到clang的路径,clang所在目录即为编译工具链目录;
    • 把目录下的clang重命名为clang_origin,swift重命名为swift_origin(如果是xcode12.5以上,则把swift-frontend重命名为swift-frontend_origin),libtool重命名为libtool_origin;
    • 把sdk的compile-script目录下的clang,swift,libtool,sot_link.sh,sot_setup.sh,sotcall_exec.sh,sotcall_origin.sh拷贝到工具链目录下;
    • 在terminal里cd到工具链目录下,分别调用下面几个命令给它们添加可执行权限:
      • sudo chmod +x clang
      • sudo chmod +x clang_origin
      • sudo chmod +x swfit
      • sudo chmod +x swfit_origin
      • sudo chmod +x libtool
      • sudo chmod +x libtool_origin
      • 如果是xcode12.5以上则多加两条:
      • sudo chmod +x swift-frontend
      • sudo chmod +x swift-frontend_origin

修改编译工具链不会影响正常项目的编译,假如不想接入SOT SDK了,运行compile-script下的uninstall.sh就能恢复,如在命令行输入sh /Users/sotsdk-1.0/compile-script/uninstall.sh


Step3: 复制sotconfig.sh

将sdk里project-script/sotconfig.sh复制一份到项目根目录下: ...


Step4: 修改编译选项

添加热更需要的编译选项,添加SOT虚拟机静态库等,步骤如下:

  1. 选中ShipOTDemo,选择Build Settings: ... ...
  2. 在Other Linker Flags添加-sotmodule $(PRODUCT_NAME) /Users/sotsdk-1.0/libs/libsot_free.a -sotsaved $(SRCROOT)/sotsaved/$(CONFIGURATION)/$(CURRENT_ARCH) -sotconfig $(SRCROOT)/sotconfig.sh,每个选项的意义如下:
    • -sotmodule是module的名字,可以直接用$(PRODUCT_NAME),也可以自定义名字;
    • -sotsaved是编译中间产物保存的目录,补丁自动化生成需要对比前后编译的产物来生成补丁;
    • -sotconfig指定了项目sotconfig.sh的路径,该脚本控制sot编译器的工作,本例该脚本放到了项目根目录,所以用$(SRCROOT)引用到
    • /Users/sotsdk-1.0/libs/libsot_free.a是SOT虚拟机静态库的路径,例子的Debug模式下链接的是本地版的虚拟机
  3. 在Other C Flags和Other Swfit Flags添加-sotmodule $(PRODUCT_NAME) -sotconfig $(SRCROOT)/sotconfig.sh,假如Target没有swift代码,则不需要往Other Swfit Flags添加。最终结果如下: ...
  4. 因为SDK库文件编译时不带Bitcode,所以需要把Target的Enable Bitcode设为No ...
  5. 选中SwiftTest Target,把它的Mach-O Type改为Static Library(这里推荐对静态库热更比较好,动态库也可以,但需要每个动态库都链接libsot)。重复跟ShipOTDemo差不多的步骤设置,区别是对于非主Target,是在Other Librarian Flags配置,而不是Other Linker Flags,并且不需要链接libsot_free.a,结果如下: ...
  6. 如果有别的Target需要热更,按照这样配置一下。

Step5: 增加script

SDK里提供了一个便利脚本,路径在sdk目录的project-script/sot_package.sh,它会把生成的补丁拷贝到Bundle文件夹下。如果有多个Target需要生成补丁,像示例工程有两个Target,都配置了热更,则会为两个Target分别生成补丁放到sotsaved对应目录下,sot_package.sh脚本会把两个补丁合并成一个再拷贝。添加步骤如下:

...

脚本内容为:sh /Users/sotsdk-1.0/project-script/sot_package.sh "$SOURCE_ROOT/sotconfig.sh" "$SOURCE_ROOT/sotsaved/$CONFIGURATION" ShipOTDemo SwiftTest sot_package.sh脚本的第一个参数是项目的sotconfig.sh的路径,第二个参数是配置的sotsaved的目录,从第三个参数开始,是前面设置的sotmodule的名字,如果有多个则空格隔开,如本例有ShipOTDemo和SwfitTest。


Step6: 链接C++库

链接libz.tbdlibc++.tbd

还是在这个页面下,打开Link Binary With Libraries页,加入下面这两个库 ...


Step7: 调用SDK API

在代码里调用API:[SotWebService ApplyBundleShip],该代码被调用后,会去Bundle里找到补丁文件并加载补丁,实现热更。如本例子是在点击了按钮后,在ViewControler.m文件的SotUpdate函数里加载补丁,需要引用SDK头文件,本例是#import "/Users/sotsdk-1.0/libs/SotWebService.h",至此项目配置完成。 ...


热更编译和生成补丁

按上面配置完之后,还需要控制sotconfig.sh的开关,否则编译出来的APP是无法热更的,SOT热更流程分为两部分,一部分是热更注入,一部分是生成补丁。

Step1: 热更注入

打开sotconfig.sh,里面有两个开关,EnableSot和GenerateSotShip:

  • 如果EnableSot=0,那么编译出来的APP跟原来是没有区别的,无法使用SOT热更,平时开发可以保持EnableSot=0;
  • 等到要发布APP到商店时,设EnableSot=1,GenerateSotShip=0,表示要对APP进行热更注入
  • clean项目后build项目,如果成功的话,这个app就具备了热更能力了,这时去看编译的.m文件的日志,能看到run sot clang compile字样的输出,如果看Target的link日志,会有更多详细内容,提示了哪些函数可以被热更等信息,详细解释看「 热更配置 」
  • 同时可以发现之前配置的sotsaved目录里也多了很多文件,这些文件不能删除,需要保留


Step2: 生成补丁

如果项目出现了BUG,那么需要生成热更补丁,步骤如下:

  1. 设置sotconfig.sh里EnableSot=1,GenerateSotShip=1;
  2. 然后修改源代码,不需要clean项目;
  3. Build项目,没有任何报错的话,就能在Bundle目录下得到热更补丁了,找到它的步骤如下,对Products的.app右键,选择Show In Finder ... 然后对APP右键选择Show Package Contents,进到Bundle目录里: ... 补丁文件就是sotship_xxxx.sot,xxxx是它的编译架构,本例是模拟器所以是x86_64: ...
  4. 这时启动APP,调用ApplyBundleShip接口之后,APP使用的就是补丁里的代码。
  5. 如果未来想重新生成包并提交苹果商店,记得把GenerateSotShip=0,因为GenerateSotShip=1的话,会一直使用上一次GenerateSotShip=0时候的代码出包


Step3: 测试补丁

本地版只支持加载Bundle里的补丁,用于本地测试开发是没有问题的。启动APP,首先点击下面的Run按钮,可以看到下面文本框输出hello SOT, ... 回到Xcode修改RunDemoCode函数里的此处代码,例如改成别的文本,hello world: ... 生成补丁。启动APP,点击run按钮,还是输出hello SOT。此时点击Sot Sync按钮则会ApplyBundleShip接口,控制台会看到类似日志输出: ... 如图表明有1个module成功加载了补丁,是ShipOTDemo这个module,此时再点击run按钮,发现文本框输出的是hello world: ... 测试通过后,如果使用了网站版SDK,就是把这个补丁上传到本网站,已上线APP通过网络下载补丁,具体看「 网站版 」的接入。

特别说明:

不是所有新加的代码都能够生效,举个例子来说,如果调用了老代码没有调用过的函数,就可能不会生效。这个Demo工程只是用来演示的,原本的代码量很少,不用对其做过多测试。具体什么能热更生效,什么不能,参看文档「 热更能力 」

有任何问题可以到「 github发issue 」,我们会统一解答,也方便其他人看到。