自从蘑菇街的李忠老师在移动前线群里做了一次关于iOS组件化的分享之后,大家对于iOS客户端的架构非常感兴趣,展开了热烈的讨论。我很认同一句话,架构都是演变出来的,没有最好的架构,只有最合适的架构,刚好趁这个机会,我向滴滴的李贤辉老师请教了滴滴iOS架构的一些问题,包括它是如何演变的,如何应对数据传输和展示挑战,以及组件化、热修复等等。这应该是滴滴首次向外分享它的客户端架构,让我们一起来揭开它神秘的面纱,看看它是怎么做的。

嘉宾介绍李贤辉,滴滴出行平台产品中心iOS技术负责人,业余时间喜欢踢踢足球和旅行。多年客户端开发经验,2010年加入百度日文输入法部门,2011年从C/C++的PC端开发转到百度音乐移动端的iOS开发,2013年5月加入滴滴,目前是平台产品中心的 iOS 负责人,经历了滴滴的 2.0 到现在的 4.2.5 版本。滴滴的iOS客户端架构模式与演变

在滴滴高速发展的过程中,iOS客户端架构发生了哪些大的改变?李贤辉:2013年5月,我们启动了滴滴 2.0 ,主要是 UI 交互方式的改变,采用了MVC的方式,代码结构上做到了更清晰。

2014年5月,新增了专车业务线,需要支持出租车、专车2个业务线,启动了滴滴 3.0

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

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

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

目前滴滴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 瘦身的目的。

组件化

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

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

业务挑战

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

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

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

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

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

其它:热修复、代码共用、Swift

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

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

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

感谢您的分享。

滴滴android架构演进,滴滴出行iOS客户端架构演进之路相关推荐

  1. 精华阅读第 9 期 |滴滴出行 iOS 客户端架构演进之路

    「架构都是演变出来的,没有最好的架构,只有最合适的架构!」最近,滴滴出行平台产品中心 iOS 技术负责人李贤辉接受了 infoQ 的采访,阐述了滴滴的 iOS 客户端架构模式与演变过程.李贤辉也是移动 ...

  2. 移动周刊第 177 期:Android 新特性介绍、iOS 客户端框架演进

    写在前面 本期移动周刊第 177 期如约而至,聚焦 Android.iOS.VR/AR/MR.直播等前沿移动开发技术,收录一周最热点,解读开发技巧,我们希望从中能够让你有一些收获,如果你有好的文章以及 ...

  3. Nice是如何做iOS客户端架构的?

    一个创业产品的iOS客户端架构到底怎么做呢?现下最有活力的图片社交软件Nice的技术负责人刘诗彬将为我们解答创业产品如何实现iOS客户端架构. 分享人:刘诗彬,毕业于北京邮电大学电子信息科学与技术专业 ...

  4. 猿题库 iOS 客户端架构设计-唐巧

    序 猿题库是一个拥有数千万用户的创业公司,从20013年题库项目起步到2015年,团队保持了极高的生产效率,使我们的产品完成了五个大版本和数十个小版本的高速迭代. 在如此快速的开发过程中,如何保证代码 ...

  5. 实践干货!猿题库 iOS 客户端架构设计

    序 猿题库是一个拥有数千万用户的创业公司,从2013年题库项目起步到2015年,团队保持了极高的生产效率,使我们的产品完成了五个大版本和数十个小版本的高速迭代.在如此快速的开发过程中,如何保证代码的质 ...

  6. 新浪微博iOS客户端架构与优化之路

    随着Facebook.Twitter.微博的崛起,向UGC.PGC.OGC,自媒体提供平台的内 容消费型App逐渐形成了独特的客户端架构模式.与电商和通讯工具类App不同,微博客户端具有多信息流.内容 ...

  7. 猿题库 iOS 客户端架构设计

    推荐序 我几周前写过一篇文章,叫 <被误解的 MVC 和被神化的 MVVM>,其中的很多思想是和本文的作者 Lancy 交流获得的.当时很多人回复问:能直接上猿题库的代码吗?这次 Lanc ...

  8. Android自定义控件-仿淘宝ios客户端天猫商品详情界面

    仿照淘宝和聚美优品,在商品详情页,向上拖动时,可以加载下一页.使用ViewDragHelper,滑动比较流畅. scrollView滑动到底部的时候,再行向上拖动时,添加了一些阻力. 项目地址:htt ...

  9. Android自定义控件-仿淘宝ios客户端天猫商品详情界面动效

    效果图 源码和例子 github:https://github.com/teisun/Android-PullPushScrollView  csdn:http://download.csdn.net ...

最新文章

  1. COM 组件设计与应用(六)——用 ATL 写第一个组件(vc.net)
  2. Winsock异步模式I/O模型WSAEventSelect的使用
  3. ASP.NET Web API 路由对象介绍
  4. 送你9个常用的人脸数据库(附链接、报告)
  5. ORA-27125: unable to create shared memory segment的解决方法(转)
  6. erlang精要(30)-卫语句
  7. 基于SignalR实现B/S系统对windows服务运行状态的监测
  8. 电话光端机的电话业务不通问题,该怎么去检查?
  9. 儿童的身高标准对照表_2020“儿童身高标准”出炉,10岁身高140,你家娃达标吗...
  10. leetcode 1143. 最长公共子序列(dp)
  11. 洛谷 P2257 YY的GCD
  12. 【转】switch中case与default的情况
  13. Win7、Win10中Protel99se不能加载库文件解决方法
  14. docker端口映射失败解决方法
  15. Error: ErrorCodeERRPS008:SubStatusES0001:Error: Could not read installation path from registry.
  16. 人工智能辅助药物发现(5)药物属性预测
  17. Unity3d实现阿拉伯语适配,不规则特殊字符的处理。
  18. AdmExpress 国际仓储转运系统/海淘转运系统 1.0 正式版发布
  19. 爱立信中国总裁杨迈猝死 爱立信中国惊魂48小时
  20. 一招解决苹果签名包掉包问题,一年只需签一次

热门文章

  1. fastapi_No.19_静态文件
  2. 什么是SAP?一文了解SAP产品线
  3. 屁股决定脑袋的另外一层意思:走动式管理脑袋
  4. 安卓开发学习笔记1:简单控件
  5. 【redistemplate opsforvalue和boundValueOps】
  6. 第一讲 高数基本知识1
  7. 像外行一样思考,像专家一样实践——科研成功之道
  8. 应急响应流程以及入侵排查
  9. 结构化风险模型----转:沪深300指数的风格因子暴露度分析(一)
  10. 金额格式化,保留金额后两位小数点