20

京东商城订单模块Swift探索

 3 years ago
source link: https://mp.weixin.qq.com/s/iF5Jg17gQGSX_ngi0r4l-A
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

京东商城订单模块Swift探索

原创 京东刘欢 李卫锋 京东零售技术 5天前

ABI Stability & Module Stability 以及Swift优势

2019年Swift 5发布,标志这门语言迎来了一个重大的里程碑。与之前的版本相比除了一些基础语法的改变,更重要的是Swift5对Apple所有平台都是ABI(Application Binary Interface) 稳定的,即二进制接口兼容;对其他平台Linux,Windows等的ABI稳定,Swift核心团队在Swift官网上也明确表示会持续跟进。

ABI稳定带来的好处显而易见,使用Swift5构建的App将可以与Swift 6的标准库对话,如下图所示。

640?wx_fmt=png

对于开发者而言,ABI稳定更直接的效果就是Swift runtime 可以和Objective-C runtime一样被嵌入在系统OS中,不再像之前每一个App都要加入Swift的标准库。iOS系统从12.2版本嵌入Swift runtime,即iOS 12.2及以后的版本,AppStore会自动去掉APP中的Swift标准库。Swift标准库如下图所示,大致算了一下,这些库一共大概占到8、9M左右,这将极大的缩小Swift App的体积。

640?wx_fmt=png

基于ABI stability,同一个手机不同App在run time时期可以使用不同版本的Swift,那么compile time时期有没有其他问题呢?答案显然是有的。比如,一个第三方Framework是使用不同版本的Swift构建的,那么当前的应用是无法将其导入的,在编译时就会有如下报错: Module compiled with Swift 4.2 cannot be imported by the Swift 5.0。要解决这一问题就需要 Module stability了。好在官方Swift 5.1 release notes中说明这一点已经得到解决。

显然Apple对Swift在持续加大投入,可以预期会往越来越好的方向发展。从语言本身来讲,相对于Objective-C,Swift在设计上更注重类型安全,拥有更快的运行效率与更现代、更简洁的语法,等等这些,让Swift具有了明显的优势。在一些代表性的技术社区,如Github,StackOverFlow,也能很明显的感受到Swift的热度已经远远超过了Objective-C。

业务的增长必然导致APP安装包大小的增长,京东App也不例外,Swift APP的局限也在此(需要多引入相关lib)。无论从用户的角度,还是对技术的追求,也必然不能让安装包无限制的疯长。再加上其他等等原因,过去京东APP正式版本下掉了Swift的代码。如今iOS12.2以后Swift APP包大小可控, 有理由相信苹果对这方面的优化会持续加大力度。(小Tip: 苹果官方Reducing Your App’s Size一文中有说明,同一个包通过TestFlight发布的本身会比AppStore大,所以验证包大小时不要忽略掉这点。)

在苹果对Swift语言的持续改进与开源社区热度日益增加的背景下,重启对Swift的应用是有必要的。下文会介绍订单模块的改造方案以及在改造中遇到的问题。

创建Swift订单模块

我们期望的Swift方案是能和原有的业务完全隔离解耦,能够具备随时集成与取消集成的能力,这样也方便之后的落地与扩展,也鉴于商城App组件化已完成,因而选择创建一个独立的Swift版订单模块,先移植一些二、三级页面到Swift订单模块。整体结构如下图:

640?wx_fmt=jpeg

Swift Objective-c混编

早期使用过Swift的朋友可能都会有印象,在使用Cocoapods管理使用Swift的三方库时,必须要在Podfile里面加入指令use_frameworks!。这个指令的作用其实就是将包含Swift的三方库作为一种动态库来引入。但这样会拖累启动速度,同时目前Swift订单模块工程中Podfile文件是自动生成的,无法单独设置use_frameworks!。即使用动态库的方案不可取。好在苹果官方解决了这个问题,Cocoapods1.5也支持了引入Swift静态库。下图是Cocoapods1.5 release的官方说明。

640?wx_fmt=png

由上述官方说明可知,使用Swift静态库的条件已经具备。但上面同样也提到了一个问题点,如果Swift库依赖某Objective-C库,那就需要为这个Objective-C库开启“modular header”。这就是说,要么修改Swift订单模块引用的所有Objective-C的第三方库的Podspec文件,为其添加 ‘DEFINES_MODULE’=> ‘YES’,要么修改Swift订单模块的Podfile文件,添加use_modular_headers!或者在该Podfile文件中为某个单独的库配置 :modular_headers => true。这样Cocoapods会为涉及到的Objective-C的库生成module map。前面已经提到过,在商城组件化过程中Podfile文件都是自动生成的,要改动Podfile文件的生成规则可能会影响商城的所有业务。而改动第三方的Objective-C库,也将是巨大的工程。好在经过多方尝试我们发现,使用Objective-C包装一层入口即OC入口类,对外提供router路由方法调用,router方法内调用具体Swift实现,在OC入口类中引入所有需要引用的第三方Objective-C库。在这种情况下,我们的Swift模块调用Objective-C便没有了问题。在苹果官网中也找到了相对应的印证,如下图所示。

640?wx_fmt=png

过程中遇到的问题

确定了基础方案后,剩下的就是具体的执行过程了。具体的业务按照Swift的编码习惯来实现就好。这里主要记录了遇到的几个问题。

在引入Swift库后,Swift订单工程可能会报错:Could not find or use auto-linked library 'swiftObjectiveC'。链接器找不到这个library,在Library search paths 手动设置上 "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)",

"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)" 可以解决。

同时,Always Embed Swift Standard Libraries需要设置为YES,因为只有在iOS12.2以后的版本,系统才会包含Swift的标准库。当然即便这里设置为YES,AppStore也会自动为包含Swift标准库的系统做App Thinning优化

另外iOS12.2及以后系统有内置的Swift runtime,需要在 Runpath search path添加路径 /usr/lib/swift,为动态库运行时指定路径。

期望或规划

商城APP目前支持iOS9.0及以上的用户,iOS系统用户如下表已大多升级到12.2以上,也就是说绝大多数用户对Swift引入的变化是无感知的,当然我们也要兼顾低版本系统用户的体验。同时我们也要关注,业界已有为数不小的团队完全在使用Swift开发,对我们来说可以预期Swift应用是可行的且必要的。

640?wx_fmt=png

商城部分团队之前也做过Swift的尝试,但因为ABI不稳定而被各种折磨,与商城快速迭代的实际情况不契合,再加上等等其他原因,和最初的大多数体验者一样,最后被迫转回OC;目前许多阻碍已不存在,可以从以下几个方面推动:

1.工作环境、工具支持,开发、发布、打包、集成 swift环境流程打通。

2.Swift工程架构规划,开发Swift基础组件,如网络、图片等,搭建纯Swift环境架构,同时上线切量验证。

3.业务共建,商城已完全组件化,架构层的推进不影响业务侧的储备和应用。

1、apple Importing Objective-C into Swift:  https://developer.apple.com/documentation/swift/imported_c_and_objective-c_apis/importing_objective-c_into_swift

2、CocoaPods 1.5 release notes:  http://blog.cocoapods.org/CocoaPods-1.5.0/

3、swift5.0 release notes:  https://swift.org/blog/swift-5-released/

4、swift ABI Stability:  https://swift.org/blog/abi-stability-and-more/

5、swift5.1 release notes:  https://swift.org/blog/swift-5-1-released/

6、reducing your App’s size: https://developer.apple.com/documentation/xcode/reducing_your_app_s_size#//apple_ref/doc/uid/DTS40014195-CH1-GET_SIZE_REPORT

7、京东iOS客户端组件管理实践 https://www.infoq.cn/article/jd-ios-component-management 

8、iOS操作系统用户分布数据检索 https://gs.statcounter.com/os-market-share/mobile/asia



About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK