写点什么

专访滴滴出行李贤辉:滴滴 iOS 客户端的架构演变之路

  • 2016-03-17
  • 本文字数:2994 字

    阅读完需:约 10 分钟

滴滴出行作为国内互联网出行平台的代表,短短几年时间就从一个小小的创业公司成为一线互联网公司,发 展速度令人瞩目,在如此快速的发展之下,滴滴 App 在架构上又经历了哪些演变?InfoQ 记者采访了滴滴出行平台产品中心 iOS 技术负责人李贤辉,了解了 滴滴 iOS 客户端的架构演变之路。

受访嘉宾介绍:

李贤辉,滴滴出行平台产品中心 iOS 技术负责人。多年客户端开发经验,2010 年加入百度日文输入法部门,2011 年从 C/C++ 的 PC 端开发转到百度音乐移动端的 iOS 开发,2013 年加入滴滴。

InfoQ:请向大家介绍一下您自己,您是何时加入滴滴的?

李贤辉:大家好,我是李贤辉,业余时间喜欢踢踢足球和旅行。我在 2013 年 5 月加入滴滴,目前是平台产品中心的 iOS 负责人,经历了滴滴的 2.0 到现在的 4.2.5 版本,并且随着滴滴的快速发展和业务增加,团队规模也不断扩大,业务上经历了拆分整合的过程。很幸运能进入一线互联网公司,选择了热门的技术方向,并且跟 随快速增长的创业公司一起成长。

InfoQ:在滴滴高速发展的过程中,iOS 客户端架构发生了哪些大的改变?

李贤辉:2013 年 5 月,我们启动了滴滴 2.0 ,主要是 UI 交互方式的改变,采用了 MVC 的方式,代码结构上做到了更清晰。

2014 年 5 月,新增了专车业务线,需要支持出租车、专车 2 个业务线,启动了滴滴 3.0 的开发;借鉴了游戏里的状态机,把订单中的阶段,例如:出租车的等待抢单、出租车的等待接驾、专车的等待抢单、专车的等待接驾,都当成一种独立的状态,每 个状态机只需要知道可能要导向的状态机,从而做到了相对独立,状态机满足了出租车、专车双业务线的需求。

2015 年 1 月,滴滴开启了多元化,需要快速上线顺风车、代驾、试驾、巴士等多项业务,代码耦合严重,功能开发和协同发版成为痛点;滴滴的技术团队分散在北京、杭州、上海,不在同一个城市,而需要在同一个 App 里进行发布,客观上增加了架构的难度。

2015 年 6 月到年底,滴滴进行代号为 The One 的组件化框架开发,为了实现“代码治理”,可以“分而治之”的目标,在各个业务线各自开发的情况下防止代码大面积腐化,方便未来再做更加细致的架构重构, 采用 CocoaPods 的方式进行拆分;组件化之后,公共部分拆分为技术组件、公用业务组件,每个业务线是单独组件,如出租车组件、专车组件、快车组件; 通过把不同功能的组件代码拆分到不同的 pod 里,实现了业务线仅依赖于公共就可以迭代开发,改善了功能开发和协同发版。组件化只是做了治理的第一步,后面的架构优化还任重而道远。

InfoQ:目前滴滴 iOS 采用的是哪种架构模式?在 controller 瘦身上有哪些实践?

李贤辉:目前滴滴的 iOS 架构采用 MVCS 和 MVVM 的架构方式。MVCS 的 S 是 Store 的意思,包括服务器访问接口控制、数据共享、数据缓存的能力,每个 Store 处理一类情况,例如:订单 Store 会包括发单、取消订单、结束订单、评价订单等,常用地址 Store 会包含编辑常用地址、删除常用地址、拉取常用地址等。MVCS 这种方式的思考逻辑是希望做到组件无状态,完全依赖于 Store 所返回的各种状态信息,这种思想是非常类似于 React Native + Redux 的思路。

项目启动时,原计划用 Objective-C / Java 这种原生代码做一个类似于 React Native 的框架,但是工作量过于巨大且不成熟,不适合在 The One 这种量级项目中使用,后来没有开发该框架。采用 MVCS 的同时也采用 MVVM,用 VM 为 Controller 减肥,但 VM 要通过 Store 处理数据层逻辑,达到了为 Controller 瘦身的目的。

InfoQ:滴滴 iOS 客户端的组件化是如何划分的,采用什么技术实现?

李贤辉:我们在 15 年后半年实施了组件化,组件包括技术组件和业务组件,技术组件是可以跨 App 使用的,例如:网络组件(长连接和短连接)、界面导航管理组件(统一界面转场方式,模块间界面转场,通过 openURL 方式解耦);根据业务功能,已经实 现了支付、登录、消息、定位、广告 SDK、数据统计、分享等组件,每个组件是独立的 CocoaPods。

组件采用私有 CocoaPods 来实现,并采用了 Local Pods 的方式,可以在本地不提交代码的情况下,组件与调用方实现调试。组件间的页面间跳转支持 openURL 的方式,由 ONERoute 模块进行管理,页面在 +(void)load 方法中完成注册,ONERoute 内部保存一份 URL 与 Class 的对应表,当调用 openURL 时,会查找到对应的类,然后生成对应的实例对象。这种方式可以通过 URL 解耦具体的类名称,方便从 H5 拉起 Native 页面,未来还可以实现流程的可配置化。在设置页面里,还是直接依赖类的方式,避免过度使用 openURL。为了增加安全性,每个页面会设置是否允许外部打开,仅有允许外部打开的页面才可以通过系统的 openURL 方式打开。

InfoQ:从客户端展现来看,滴滴需要同时获取快车、的士、专车等的实时数据,在数据的传输、展示上有哪些挑战?滴滴是如何应对的?

李贤辉:挑战如下:

(1) 消息不及时:如乘客发单后,有司机抢单了,需要尽快知道。后来采用了 socket 长连接,使服务端具备主动通知客户端的能力。

(2) 流量过大:我们和服务器交互较多,流量消耗较大。我们现在在用 protobuf 作为数据载体,有效的减少了流量消耗。

(3) 数据易被修改:共享业务数据多,最初没有限制修改数据的权限,出现一些莫名其妙的问题;后来一方面减少共享的业务数据,并且共享数据对外,尽量是只读,如 果某个状态来源于服务器,则只能在模块内部,在收到服务器结果时,修改接口数据,即 MVCS 的 Store 内部可以修改数据。

(4) 共享地图是另外一个挑战,为减少内存占用,业务线之间切换流畅,在滴滴首页只能有一份地图实例。首页作为主页面,包括导航栏、地图、多个业务线子页面。为 了降低对业务线代码的侵入性,业务线首页从系统的 UIViewController 派生,由首页来设置业务线首页的背景色为透明色;业务线首页的 UI 元素,会在业务线内部完成处理;而在地图模块的操作,首页会收到手势,通过把手势传递给地图模块,使地图得到响应;此外,为了使业务线之间的地图元素互不 干扰,每个业务线的都包括一块独立画布,所有地图元素都在独立画布里处理,当切换业务线时,移除原画布上的所有元素,切换回来时,再恢复画布内容。

InfoQ:你们是否使用了热修复技术,目前实践情况如何?

李贤辉:滴滴采用了 Lua 和 JSPatch 两种热修复技术,由于 JSPatch 更加被苹果官方认可,目前在线上主要使用 JSPatch。我们还在开发一套 JSPatch 发布平台,内部使用者可以通过后台可以下发和管理脚本,并且处理传输安全等部署工作,提供了脚本后台管理、版本管理,并保证传输安全等功能。

InfoQ:滴滴 iOS 团队和 Android 团队的代码共同情况如何?

李贤辉:iOS 和 Android 团队在 socket 长连接库使用了同一份代码,iOS 和 Android 底层都是 Unix 系列的内核,对于网络操作是一致的,可以使用同一套系统接口,其次,这套代码的稳定性要求很高,功能与系统无关,一份代码可以降低人力消耗,并保证一致 性。对于和系统相关的功能,都采用设计思路一致,iOS 和 Android 分别开发的方式。

InfoQ:在对新技术的应用上,滴滴目前是否有用过 Swift?或者准备何时采用?

李贤辉:滴滴目前还没有用 Swift,因为在 iOS 8 及以下的平台上,使用 Swift 需要将 Swift 运行时打包到 App,会增大 App 体积。滴滴的乘客端由于受限于即将超过 100M 的包体积,目前还没有采用 Swift 的计划。滴滴的出租车司机端预计在下一季度会小范围尝试 Swift 。

2016-03-17 09:4411200
用户头像

发布了 164 篇内容, 共 106.2 次阅读, 收获喜欢 392 次。

关注

评论

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

移除数组中的数字,不用额外空间, 实战RxSwift中的Observable, subscribe, dispose, 吴军老师态度读后感 John 易筋 ARTS 打卡 Week 39

John(易筋)

ARTS 打卡计划 吴军的态度 态度读后感

如何有效改变别人的认知和行为?

数列科技杨德华

28天写作

程序员成长第十二篇:做好项目计划

石云升

项目管理 程序员 28天写作 2月春节不断更

优雅编程 | javascript代码优化的4个小技巧

devpoint

递归 命名空间 闭包 函数绑定

工作多年,如何找到自己更好的职业方向

一笑

28天写作

专治小学生作业拖沓

Ian哥

28天写作

感性赢了理性那一面——浅谈峰终定律

Justin

心理学 28天写作

高手来啦!十八般武艺保护你的Web应用

浪潮云

云计算

腾讯位置服务开发应用

我是哪吒

28天写作 2月春节不断更 腾讯地图 腾讯位置服务开发应用 腾讯位置

厘清 I/O 模型

sakila

网络编程 I/O

揭开《钢铁侠》AI管家贾维斯神秘面纱的扛鼎之作!

博文视点Broadview

Kafka.07 - 性能优化介绍

insight

kafka 2月春节不断更

谁手握账本?趣讲 ZK 的内存模型

HelloGitHub

Java zookeeper ZooKeeper原理

基于matlab的控制系统与仿真4-判断系统稳定性

AXYZdong

matlab 2月春节不断更

翻译:《实用的Python编程》02_05_Collections

codists

Python

(28DW-S8-Day5) 区块链如何防伪

mtfelix

比特币 区块链 非对称加密 28天写作 防伪技术

处理XML数据应用实践

华为云开发者联盟

xml 数据库 数据 XML文档 GaussDB(DWS)

揭秘京东城市时空数据引擎—JUST如何助力交通流量预测

京东科技开发者

JUST 流量预测

新思科技静态应用安全测试帮助Cryptsoft公司提高软件安全和质量水平

InfoQ_434670063458

为您收录的操作系统系列 - 进程管理(下篇)

鲁米

方法论 操作系统 进程

Linux 入门篇 —— 重定向与管道符

若尘

Linux 管道符 linux开发

工作日志2-23

技术骨干

科大讯飞发布全新一代智能办公本X2

XYZ

火山翻译:工业级应用与研究

DataFunTalk

别再这么写代码了,这几个方法不香吗?

楼下小黑哥

Java 重构

【LeetCode】转置矩阵Java题解

Albert

算法 LeetCode 28天写作 2月春节不断更

产品0期 - 第五周作业

曾烧麦

产品训练营

阿里粗排技术体系与最新进展

DataFunTalk

28天瞎写的第二百四十三天:正念冥想可以解决什么问题?

树上

冥想 28天写作 正念

伊卡洛斯象征了什么?「Day 5」

道伟

文化 28天写作

批量下载,我有妙解~

Viktor

JavaScript iframe 跨域

专访滴滴出行李贤辉:滴滴iOS客户端的架构演变之路_移动_徐川_InfoQ精选文章