写点什么

Swift 在好大夫 APP 医患两端的打怪升级

  • 2020-09-23
  • 本文字数:3217 字

    阅读完需:约 11 分钟

Swift在好大夫APP医患两端的打怪升级

AI 大模型超全落地场景&金融应用实践,8 月 16 - 19 日 FCon x AICon 大会联诀来袭、干货翻倍!

swift 作为苹果的亲儿子,从 2014 年开始,在 6 年的发展过程中,终于在 2019 年 3 月份迎来了 ABI(Application Binary Interface)的稳定。

背景

ABI 的稳定意味着 Binary 接口稳定,也就是运行的时候只要是通过 swift 5 或者以上的编译器编译出来的 binary,就可以跑在任意的 swift 5.0 及以上的 runtime 上。这样,我们就不需要像以前那样在 app 里面放一个 swift runtime,Apple 会把相应的 ABI 整合到 iOS 或者 macOS 中。同时 App 的尺寸会变小,在 iOS12.2 以上系统,会预装 swift 5 runtime,所以不在需要swift的库,它们会从 app bundle 中被删除,对于 iOS12.2 以下的系统,还是照旧需要引入。同时因为系统集成了 swift,app 启动的时候也就不需要额外加载 swift,在新系统中会更加的节省内存空间。


对于好大夫的医患两端,在这时接入 swift 是一个不可多得的好机会。那么,从好大夫的 iOS 客户端团队角度出发,接入 swift 需要有哪些准备工作?基础框架如何设计?如何解决在 swift 开发中出现的问题?这些都会在下文中一一解答。

接入 swift 的准备工作

好大夫的 iOS 客户端代码年份非常久远,整体使用 Objective-C 编写,最早的代码可以追溯到 2011 年 8 月份,对于接入 swift 来说,首先需要进行技术调研,什么版本的 swift 适合好大夫客户端,而不是一味的追求最新的 swift 版本。其次,对于 swift 三方框架的调研,国内的 swift 社区活跃度并不是特别高,相反国外的 swift 社区反而更加的活跃,从 github 上的 Alamofire 网络库到Uber早已使用 swift 重构客户端,可见 swift 在过国外早已盛行已久。


通过调研,swift 在开发效率和性能上明显优于 Objective-C,苹果开发者官网上各种 Programming Guide 也已经以 swift 作为首要显示语言,从苹果对 swift 的推广来看,如果我们一直坚守 Objective-C 阵营,在未来苹果强制推进 swift,对我们来说冲击还是比较大的。WWDC2019 中,苹果同时推出了 swiftUI,正式统一了 Apple 全平台 UI 开发解决方案,未来属于 swift,可见好大夫 iOS 客户端接入 swift 刻不容缓。

基础框架设计

iOS 客户端整体采用组件化的架构,使用 cocoapods 导入各个组件,业务之间通过中间件进行通信,基础组件包括网路库、图片库、支付库等。在接入 swift 之后,虽然基础私有库可以通过修改 podspec 文件进行 swift 私有库调用,但是为了统一和壮大 iOS 客户端的 swift 生态系统,对于部分私有库进行了 swift 化重构,生成一套专供 swift 调用的基础库,当然不是所有的私有库都进行了重构,而是根据具体的业务需求以及公司未来发展综合考虑,对一些工程中经常用到的宏定义,遍历构造函数以及视图约束框架等进行了 swift 化。


对于 UI 常用控件,网络库,图片库,支付库等,如果进行重构,则会出现影响范围较大,测试耗时很长,影响项目迭代,拿 UI 控件库来说只是进行了 podspec 文件修改,使其支持了 swift 私有库的调用,同时如果有新增的基础控件,首选 swift 语言来编写,减少 Objective-C 代码的使用。


经过一年时间的沉淀,iOS 客户端目前全量 swift 业务有直播业务、留言板业务,其他的业务的主流业务也已经使用了 swift 和 OC 混编的方式进行开发。


推进工程 swift 化遇到的问题

传统 Objective-C 项目接入 swift 一些问题始终是绕不过去的,如:


  • 主工程或者模块化中 swift 和 Objective-C 的混编怎么实现

  • Module 系统

  • swift 代码的规范性怎么解决

一、swift 和 OC 混编

针对上面的第一个问题,我们分为两种情况,第一种情况为 App Target 内部 swift 和 OC 混编,对于好大夫的医患两端来说之前一直使用 Objective-C 编写,所以在创建第一个 swift 文件时,会提示生成一个 bridging header 文件,点击 create 即可。



在 swift 文件中如果需要引入某个 OC 类,将需要使用的 OC 类在 bridging 文件进行 #import 即可。在 OC 类中如果需要引入 swift 文件,只需要在 OC 类中引入 import “ProductModuleName-Swift.h”,其中 ProductModuleName 表示当前 Target 的名称。ProductModuleName-Swift.h 文件为编译产物,可以看到该文件将 swift 文件中的代码生成为对应 OC 中的 interface 和 implementation。


第二种情况为模块内部进行 swift 和 OC 混编,或者 OC 私有库需要提供给外部的 swift 文件或者 swift 私有库使用,针对这种情况我们可以统一配置,好大夫客户端采用的 cocoapods 方式引入组件,所以通过对组件 podspec 进行配置,添加 s.pod_target_xcconfig = {‘DEFINES_MODULE’ => ‘YES’} 将组件模块进行 module 化,可以使用 cocoapods 自动生成的 umbrella.h 文件或者自己新建一个 umbrella header 将需要暴露给 swift 调用的 ObjC 头文件在这个 umbrella header 中导入,在需要调用的 swift 文件中直接 import Module 即可。

二、Module 系统

2.1 LLVM Module 系统

既然说到了 OC 和 swift 混编,那么不得不提苹果在 2012 年 11 月提出 LLVM 的 Module 系统,简单讲就是用树形的结构化描述来取代以往 #include,例如传统的 #include <stdio.h>变成了 import std.io,逼格更高,这样做的好处主要有:


  • 语义上完整描述了一个框架的作用;

  • 提高编译时的可扩展性,同一模块只需要编译或导入一次,避免了头文件的多次引用、解析;

  • 减少碎片化,每个模块只处理一次,环境的变化不会导致不一致;

  • 对工具友好,工具(语言编译器)可以获取更多关于 module 的信息,比如链接库,比如语言是 C++ 还是 C;

2.2 modulemap 文件

modulemap 文件就是对一个框架,一个库所有文件的结构化描述,默认文件名是 module.modulemap。如下图,可以看到使用 umbrellar header 关键字导入 HDFIMComponent-umbrella.h 中所有的.h 文件。



umbrellar header 关键字的意思为 Master Header File,可以使用


#import <UIKit/UIKit.h>
复制代码


替代


#import <UIKit/UIViewController.h>#import <UIKit/UILabel.h>#import <UIKit/UIButton.h>#import <UIKit/UIDatePicker.h>
复制代码

2.3 Swift Module

项目中的每一个 Target(无论是 framework 还是 app),就叫做一个 Swift Module。这是 Swift 分发代码的方式,我们可以通过 import 命令,来使用定义在其他 Module 中的代码,而每个 Module 意味着:


  • 一个和 Module 同名的命名空间

  • 一个独立的访问控制范围


对第一条来说,这也就是为什么在一个项目中,定义在不同 Swift 文件中的类可以在不同的文件中直接使用而不需要 include 的原因,因为它们本身就在同一个 namespace 里。


对于第二条来说,当我们通过 import 在项目中引入一个 module 时,就相当于打开了这个 module 对应的命名空间,就可以使用这个 module 中所有标记为 public 或者 open 的代码。


三、规范 swift 代码

不同的人有不同的编码习惯,导致了工程中代码风格的多样性,为了提供 swift 代码的可读性以及统一性,iOS 客户端引入了 swiftlint,swiftlint 是 Realm 开源的一个加强检查 swift 语言规范的库,可以满足强迫症的所有幻想,通过对 swift 代码进行扫描,统一编码风格,从每一个文件到每一个函数,甚至每一个变量都进行规范,将 swiftlint 扫描后的结果接入到 SonarQube,使用网页进行展示,方便分类修改,将具体的代码分配给对应的负责人,严格按照要求进行修改,保证客户端 swift 代码坏味道为 0。


未来规划

swift 是一门优秀的编程语言,就目前苹果主推 swift 语言以及编程语言排行榜上 swift 已经从 18 位上升到 12 位,可见未来国内 swift 语言也将会盛行。接入 swift 简单,但是如果想要完美的兼容当前工程并非一件容易的事,只有选择正确的方式,合适的解决方案才能将 swift 与原工程成功融合在一起。



好大夫 iOS 客户端目前已经全量使用 swift 进行开发,计划每年做新系统适配时会升级 swift 版本,紧跟时代的发展。后续接入 swift package manager 替代 cocoapods、声明式 UI 替代现有命令式 UI。


作者介绍:


陶庆玮:好大夫 iOS 开发工程师,主要负责组件化工程、基础库开发和客户端稳定性相关工作,以及 Swift 语言落地。


公众号推荐:

AIGC 技术正以惊人的速度重塑着创新的边界,InfoQ 首期《大模型领航者AIGC实践案例集锦》电子书,深度对话 30 位国内顶尖大模型专家,洞悉大模型技术前沿与未来趋势,精选 10 余个行业一线实践案例,全面展示大模型在多个垂直行业的应用成果,同时,揭秘全球热门大模型效果,为创业者、开发者提供决策支持和选型参考。关注「AI前线」,回复「领航者」免费获取电子书。

2020-09-23 08:004336

评论

发布
暂无评论
发现更多内容

Django 配置夯实,再补充几个配置项,够够的了

梦想橡皮擦

9月日更

奉若神明!阿里技术专家开源ApacheDubbo核心源码笔记

Java~~~

Java spring 架构 面试 dubbo

阿里技术专家亲码:满干货“Redis核心笔记”,全篇无尿点

Java~~~

Java redis 架构 面试 中间件

Neon 支持

Changing Lin

9月日更

Redis核心原理与实践--字符串实现原理

binecy

redis 书籍推荐 源码学习

k8s garbage collector源码分析(2)-处理逻辑分析

良凯尔

Kubernetes 源码分析 Kubernetes源码 #Kubernetes#

微信朋友圈高性能架构

Geek_db27b5

【架构实战营作业】模块二——朋友圈高性能架构

聆息

Go- 接口-1

HelloBug

interface Go 语言

Go- 接口-2

HelloBug

interface Go 语言

模块2-作业

笑看风雨情

阿里进阶专用:Mycat权威指南,不怕从零开始,只怕从未启程

Java~~~

Java MySQL 数据库 架构 面试

极客时间【架构实战营】第二期 模块二作业

Geek_91606e

架构实战营

设计微博系统中”微博评论“的高性能高可用计算架构

架构0期-Bingo

阿里技术专家,紧跟潮流,解读spring微服务架构技术的演进

Java~~~

Java 架构 面试 微服务 Spring Cloud

ShardingSphere LogicSQL 的生成探索

源码 ShardingSphere

k8s garbage collector源码分析(1)-启动分析

良凯尔

Kubernetes 源码分析 Kubernetes源码 #Kubernetes#

Go- 接口-3

HelloBug

interface Go 语言

万字长文说透分布式锁

多颗糖

redis zookeeper 分布式 分布式锁 etcd

Java + opencv 实现老照片特效滤镜

张音乐

OpenCV 图像处理 9月日更 特效 老照片

Python开发篇——添加mysqlclient

DisonTangor

Python MySQL

惊讶!阿里大佬总结的图解Java小册火了,完整版笔记开放下载

Java~~~

Java 架构 面试 微服务 JVM

激动!阿里技术官纯手打,1263页并发编程全系笔记,限时开源

Java~~~

Java 架构 面试 多线程 并发

面试题 -- 如何设计一个线程池

秦怀杂货店

线程 线程池 并发

Go- 反射

HelloBug

reflect Go 语言

【8月书单】

姬翔

9月日更

🌏【架构师指南】带你彻底认识Paxos算法、Zab协议和Raft协议的原理和本质

洛神灬殇

ZAB raft协议 paxos协议 9月日更

架构师实战营 附一作业(按接口隔离原则优化设计无人机引导直升机攻击的类图)

代廉洁

架构实战营

Prometheus relabel 透析与实战

卓丁

Prometheus relabel_config

双非本科跨专业5面京东,8600小时后收到通知,流下喜悦泪水

Java~~~

Java 架构 面试 微服务 JVM

香!阿里技术官甩我一份283页Java核心笔记,竟含9大核心

Java~~~

Java 架构 面试 JVM 多线程

Swift在好大夫APP医患两端的打怪升级_AI&大模型_好大夫在线技术团队_InfoQ精选文章