在上一篇文章中,我们主要谈了这两件事情:
如何使用 CocoaPods 引入寄生在
Mobile-SDK-iOS中的DJIWidget项目;如何利用 Runtime 的手段来 hook 住
DJIVideoPreviewer的关键函数从而获取解码后的 pixelBuffer;
而后来发生了两件事情,促使这篇文章诞生:DJIWidget 项目被抽出独立管理,
1. DJIWidget 项目被抽出独立管理
DJISDK 团队将 DJIWidget 抽出来独立管理,并为添加了 CocoaPods 支持,这一举措非常值得肯定。但是,现在只能以 static lib 的方式引入,也就是说项目 podfile 里面的 use_frameworks! 要去掉。
2. DJI-UXSDK 中包含了 DJIWidget
这点是在根据 Xcode 控制台输出的调试信息猜测的:
objc[1155]: Class DJIVideoPreviewer is implemented in both/private/var/containers/Bundle/Application/4BA27205-28B7-4EDE-9A31-0FAC7635165D/Mesh.app/Frameworks/DJIWidget.framework/DJIWidget (0x10572b750)and/private/var/containers/Bundle/Application/4BA27205-28B7-4EDE-9A31-0FAC7635165D/Mesh.app/Frameworks/DJIUXSDK.framework/DJIUXSDK (0x1054ec138).One of the two will be used. Which one is undefined.
如果项目中同时引入 DJI-UXSDK 以及 DJIWidget 的话,使用我们在 DJIWidget 通过 Category 为 DJIVideoPreviewer 新增的方法会发生 Unrecognized Selector 的问题而导致闪退。问题的原因应该与 DJI-UXSDK 中包含了 DJIWidget 的代码有关系,但还没清楚弄透,敬请等待后面更新。
3. 再度高效并充分使用 DJIWidget
有鉴于上面两点,我们再度开始「对 DJIWidget 的高效并充分利用」的探索。
3.1 Podfile 中的 DJIWidget 指定方式
由于原仓库中 Podspec 的编写有限制,不能以 use_frameworkds! 的方式引入,所以我们自己重新写了一份 Podspec。其内容大体上还是参照上一篇文章中阐述的编写方式,只不过对一些路径的指定进行了更新,以适应 DJIWidget 的项目结构,具体内容可以在 Kiwi Repo 下看到。
另外还是由于 pod lib lint 时的编译问题,没能顺利将这份 Podspec 推到私有 spec repo,这里暂未投入时间研究,因此项目中对 DJIWidget 的引入方式仍然需要采用 git + tag 的方式:
pod 'DJIWidget', :git => 'git@github.com:gzkiwiinc/DJIWidget.git', :tag => 'kw1.0.1'pod 'DJIWidget/DJIVideoPreviewerExtension', :git => 'git@github.com:gzkiwiinc/DJIWidget.git', :tag => 'kw1.0.1'
同样,为了避免后面维护的时候,拉取原仓库的代码时可能发生的 tag 冲突,也为了清晰起见,所有由 kiwi 打的 tag 前面都加上 kw 前缀。
3.2 取回解码后的图像 buffer
由于上面提到的 DJI-UXSDK 内包含 DJIWdiget 的问题,这里转而使用子类化的方式来回避这个问题:
声明
KWVideoPreviewer并继承DJIVideoPreviewer;KWVideoPreviewer内部增加delegate属性;重写
videoProcessFrame方法,加入 buffer 的转换以及调用 delegate 的逻辑;外部项目使用
DJIVideoPreviewer的地方全都改为使用KWVideoPreviewer;
KWVideoPreviewer 的全部代码可以在 Kiwi Repo 中的 DJIVideoPreviewerExtension 文件夹里面看到。
当然这里的 best practice 可能是
DJI-UXSDK的 podspec 中声明对DJIWidget的依赖,而不是直接将DJIWidget的代码包含在其内部。
