# 老司机 iOS 周报 #54 | 2019-01-28

![ios-weekly](https://github.com/SwiftOldDriver/iOS-Weekly/blob/master/assets/ios-weekly.png?raw=true)
老司机 iOS 周报，只为你呈现有价值的信息。

你也可以为这个项目出一份力，如果发现有价值的信息、文章、工具等可以到 [Issues](https://github.com/SwiftOldDriver/iOS-Weekly/issues) 里提给我们，我们会尽快处理。记得写上推荐的理由哦。有建议和意见也欢迎到 [Issues](https://github.com/SwiftOldDriver/iOS-Weekly/issues) 提出。

## 通知

各位读者大家好！首先欢迎我们的新编辑 - 热爱分享的爱奇艺 iOS 开发 [@J_Knight_](https://github.com/knightsj) 加入周报团队~另外春节临近，本期周报也将是我们年前的最后一期，年后我们再见！祝大家春节快乐！

## 新闻

### 🌟 [老司机翻车现场：一个业余程序员组织如何收到滴滴的侵权通知](https://mp.weixin.qq.com/s/9-vbYu71fPTxpGAv8EL_6w)

2019 年 1 月 23 日，这是一个值得所有老司机编辑铭记的日子，我们收到了来自滴滴法务团队的侵权通知。虽然我们完全不是一个实体组织，也毫无商业性质可言，和滴滴更不在一个行业，Logo 的颜色也完全不同。但是滴滴认为我们从 18 年 1 月开始使用的 Logo 和他们在 18 年 3 月登记的街兔 Logo “高度相似”，可能导致 APP 应用程序员的开发人员认为是街兔商标。对于这方面纠纷，我们也是大姑娘坐轿子头一遭，真谈不上老司机。于是我们选择按照对方要求第一时间替换掉所有可疑图片。在此期间，我们收到了很多读者和朋友的建议和帮助，非常感谢大家对老司机周报的关心和支持，我们全新的 Logo 也即将完成设计，很快会与大家见面。

我们愿称此次严肃而又哭笑不得的事件为『123 老司机翻车门』，为了其他同在技术社区做分享的朋友避免受此类事件的影响，『[知识小集](https://github.com/awesome-tips/iOS-Tips)』特地整理了一份指南给大家 - [老司机翻车现场 续：技术之外，程序员如何自我保护](https://mp.weixin.qq.com/s/nkdNE1Nh-FZgx05LVYcVLQ)。

### 🌟 [Swift 5 Release Notes for Xcode 10.2 beta](https://developer.apple.com/documentation/xcode_release_notes/xcode_10_2_beta_release_notes/swift_5_release_notes_for_xcode_10_2_beta?language=objc)

万众期待中，Swift 5.0 终于和 Xcode 10.2 Beta 以及 iOS 12.2 Beta，macOS 10.14.4 Beta 一起降临。虽然距离正式版还有大概一个月多一点的时间，但是各位 iOS Swift 开发者已经可以开始着手准备进行适配了。

Swift 5.0 应该能算是 Swift 从 1.0 以来的最大变革。不是因为语法变化多，而是因为从 5.0 开始，Swift 终于进入了 ABI 稳定时代，系统将自带 Swift 动态库，老版本 Swift 编译的库也将可以轻松的用到更新版本的 Swift 项目中。

除了上面苹果官方给出的链接，也可以参考知识小集团队的[翻译版本](https://juejin.im/post/5c4b3e91e51d452c8e6d6bcc)。

### [Upcoming Changes for Organization Teams](https://developer.apple.com/support/teams/)

从 2019-02-12 开始，苹果开发者网站（developer.apple.com）和 App Store Connect 将会共用一套成员管理系统，有些角色权限将合并。这是个期待已久的改动，简化我们的维护成本。

## 文章

### 🌟 🐎 [Server-provided animations in iOS apps](https://badootech.badoo.com/server-provided-animations-in-ios-apps-b51ce63beff3)

这篇来自 Badoo 团队的文章用一个例子介绍了如何将 Adobe After Effects（AAE）的动画导出为 iOS app 可以读取的格式（借助 Lottie 库），然后创建一种动画云存储服务，将动画存储在服务器上，然后按需传递给客户端 app。这种方法最显著的优点就是可以对动画更新流程进行解耦，也就是说如果要发布一个漂亮的新动画，设计师只要给服务器团队提供 JSON 就可以了，效率非常高！还有一个优点是不同的客户端平台（iOS、Android、Web）可以实现完全相同的功能而不需要调整现存的服务器端功能或原生动画。

### 🌟 🐎 [A RunLoop for your Swift script](https://alejandromp.com/blog/2019/01/19/a-runloop-for-your-swift-script)

上一期推荐里面有一篇关于 [swift-sh](https://nshipster.com/swift-sh/) 的介绍，如若未读，可以先跳转过去一看。
这一文章主要是给出一下 Tips，当你需要执行一个异步任务的时候会发现，脚本跑完就结束，异步任务自然也得不到调用了，这是不符合需求的。iOS App 启动后会进入 Runloop 当中不停的在休眠和执行状态循环，保证 APP 在没任务的状态也不会退出。同理，在脚本中，执行 `RunLoop.main.run()` 或者  `dispatchMain()` 会让脚本进入启动 Runloop，不会结束。当你异步任务 callback 后，调用 `exit(EXIT_SUCCESS)` 或 `exit(EXIT_FAILURE)` 退出当前 Runloop，并且结束脚本。

### 🌟 🐕 [2018，我们的组件化实施之路](https://juejin.im/post/5c39b9a8e51d457cb97b944a)

本篇文章是诸葛找房 iOS 技术团队近半年组件化实施之路的经验积累与沉淀，文章主要有 2 大部分。

第一部分主要讲了组件化可选用的方案、组件化的分层、业务组件的拆分步骤：
1. 组件预处理
2. 组件抽离、编译、运行
3. 组件引入

第二部分分享了在实施组件化过程中遇到的一些问题：
* 主工程中业务组件的引用方式问题
* 业务组件的开发时机问题
* 业务组件如何测试
* 组件后续的开发与维护和组件回滚
* 业务组件的粒度
* 关于业务组件中文件的命名规则
* 关于不同项目下同一业务组件的个性化差异解决方案
* 其他细节问题如如何处理组件之间的相互跳转、业务组件之间如何进行复用等
* 关于业务组件的评价标准

组件化是一个漫长、繁琐、复杂但有意义的过程，是一项团队性的工作，不管是正在打算实施，还是已经进行过组件化实践，都可以阅读本文，相信读者朋友阅读本文都会有一定收获。

### 🐎 [React Native vs Kotlin Multiplatform. How the Future of Multiplatform Development Will Look Like?](https://www.netguru.com/codestories/react-native-vs-kotlin-multiplatform)

作者对比了 React Native 和 Kotlin 在跨平台上各自的优劣，同时也谈了自己对跨平台的未来的思考，虽然不是针对 iOS 的，但是也值得阅读参考。

### 🐎 [Flutter vs React Native: A Developer’s Perspective](https://medium.com/flawless-app-stories/flutter-vs-react-native-a-developers-perspective-8914ca240a89)

老生常谈的话题，作者从十个方面去比较了 Flutter 和 React Native 的优劣，可供还在选型的同学们参考。

### 🐕 [How to use the coordinator pattern in iOS apps](https://www.hackingwithswift.com/articles/71/how-to-use-the-coordinator-pattern-in-ios-apps)

本文介绍了如何使用 Coordinator Pattern 这一设计模式来分离出本不属于 View Controller 的一些职责 ，避免导致 ``Massive View Controller`` 的形成。Coordinator Pattern 可以翻译为协作者模式，该设计模式并不在 ``GOF`` 的 23 个设计模式之中。

作者结合代码，从 Coordinator 的创建到应用，讲解了一个如何将跳转功能分离出 View Controller 的例子。读者通过阅读本文，可以了解到何为协作者模式，以及如何将该模式应用到我们自己的 APP 开发中。

相关阅读：[The Coordinator](http://khanlou.com/2015/01/the-coordinator/)

### 🐎 [Xcode tips and tricks – part two](https://www.hackingwithswift.com/articles/168/xcode-tips-and-tricks-part-two)

文接上回，Xcode tips and tricks 系列的第二个合辑来了！作者更新的速度很快，本期仍然是 10 个快捷使用 Xcode 的文本 + 小视频，你肯定能发现一些“原来还能这样操作”的点。作者也在搜集大家的建议，如果你有什么清奇的手法，也不妨[分享](https://twitter.com/twostraws)出来吧！

### 🐕 [WKWebView 实现浏览历史恢复](https://oldoldb.com/2019/01/16/Session-restoration/)

在使用 WKWebView 的时候，我们会发现，WKWebView 无法实现浏览历史的持久化。WKWebView 中 backForwardList 属性用来记录浏览历史，但这个属性是只读的，且在下次冷启动 App 的时候，backForwardList 是全新的，故而会有这个问题。

如何实现 WKWebView 浏览历史的持久化？本文作者通对 Firefox 的相关源码进行分析，借鉴了 Firefox 浏览器的实现方式。总结一下：

1. 当 App 启动需要恢复浏览历史的时候，启动一个本地的 Web server 并且加载一个特定的本地页面

2. 提取之前保存的所有 url 信息，构造本地 url 越过[同源策略](https://developer.mozilla.org/en-US/docs/Web/API/History_API)限制，传递到特定本地页面中，该页面通过调用 pushState 来达到修改 backForwradList 的目的

3. 当本地加载这些特殊 url 的时候，之前启动的本地 server 可以将其重定向到正确的url

### 🐢 [细说 iOS 代码签名](http://xelz.info/blog/2019/01/11/ios-code-signature/)

iOS 签名机制其实挺复杂，我们可以跟随作者的脚步，一点点的去了解 iOS 签名机制中每一步的含义，此外作者还贴心的帮助我们将文章拆分，有助于我们分步阅读。

- [细说 iOS 代码签名(一)：签名的作用及原理](http://xelz.info/blog/2019/01/11/ios-code-signature-1/)
- [细说 iOS 代码签名(二)：开发者证书、Entitlements、Provisioning Profile](http://xelz.info/blog/2019/01/11/ios-code-signature-2/)
- [细说 iOS 代码签名(三)：签名的过程及代码签名的数据结构](http://xelz.info/blog/2019/01/11/ios-code-signature-3/)
- [细说 iOS 代码签名(四)：签名校验、越狱、重签名](http://xelz.info/blog/2019/01/11/ios-code-signature-4/)

因作者篇幅比较长，讲解的比较深入，有兴趣的同学可以通篇读完收益更大。若时间有限，推荐缩略版的 [iOS App 签名的原理](http://wereadteam.github.io/2017/03/13/Signature/) 供大家参考。

> 推荐人：[xelzmm](https://github.com/xelzmm)

### 🐎 [Clear and searchable logging in Swift with OSLog](https://www.lordcodes.com/posts/clear-and-searchable-logging-in-swift-with-oslog)

苹果在 WWDC 2016 ([Unified Logging and Activity Tracing](https://developer.apple.com/videos/play/wwdc2016/721/)) 推出了新的统一日志系统（the new Unified Logging system）—— OSLog，它比以前的 print 或者 NSLog 功能要强大的多，苹果也是强力推荐使用新的统一日志系统。

本文主要介绍了新日志系统的三大特性：

1. 新日志系统能够按子系统 (subsystem) 和分类 (category) 进行筛选搜索
    
    ```
    let ui = OSLog(subsystem: "com.lordcodes.chat.ChatApp", category: "UI")
    os_log("Contact selected", log: ui)
    ```
    
2. 同时也支持指定日志级别 (Default, Info, Debug, Error, Fault)
    
    ```
    os_log("Contact selected", log: .ui, type: .info)
    ```
    
3. 默认不收集动态字符串 (dynamic strings) 和复杂对象 (complex dynamic objects) 的打印信息，确保用户敏感信息不会持久化到日志文件，需要收集的话要在格式化输出时指定为 `public`

    ```
    os_log("Contact %{private}ld selected", 2)
    os_log("HTTP response: %{public}@", responseCode)
    ```

*注：[CocoaLumberjack](https://github.com/CocoaLumberjack/CocoaLumberjack) 封装的日志系统是支持 os_log（DDOSLogger） 的。*

### 🐎 [以流的形式执行 Multipart 请求](https://swift.gg/2019/01/21/streaming-multipart-requests/)
Foundation 框架中的 URL 类提供了非常全面的功能，此后还在 iOS 7 中新增了 URLSession 类。尽管如此，基础库中仍然缺少 multipart 文件上传的功能。
本文介绍了怎样发起 multipart 请求，并为解决多文件传输的性能问题，通过 AFNetworking 和 Alamofire 的方式，将硬盘中数据以流的形式读取来执行 Multipart 请求解决此问题。

### 🐕 [Using protocols as composable extensions](https://mecid.github.io/2019/01/17/using-protocols-as-composable-extensions/)

面向协议是 Swift 推崇的一种编程范式，标准库里的基础类型也都是基于协议搭建起来的，利用 protocol extensions 的特性去达成复用和组合，但这些范式如何落实到业务上呢？这篇文章的作者就介绍了如何通过 protocol extension 去完成一个加载动画，并且对比了继承和协议的两种实现方式。

### 🐎 [使用 Flutter 一年后，这是我得到的经验](https://mp.weixin.qq.com/s/FmK0RMCNNJe68Aq7tOUROA)

过去一年开发者们对 Flutter 的热情有多高相信已经无需多言。Google 出品、跨平台、性能高等种种标签让越来越多的人加入其中。本文总结了作者一年来开发 Flutter 的一些心得，作者在 Flutter 上丰富的开发经验所进行的总结相信对于接下来想要尝试 Flutter 的同学是很实用的，这对我们做技术选型以及更多的考虑会很有帮助。

## 代码

### 🌟 [UIKitSwiftDSL](https://github.com/mecid/UIKitSwiftDSL)

迫于 StoryBoard 写布局带来各种协作上的问题，大型项目的布局一般都用纯代码来实现。纯代码布局最大的问题是可读性太低，有没有办法改善？
UIKitSwiftDSL 作者提供一个新思路：用区区 200 行代码实现一套布局 DSL（[Domain Specific Language](https://draveness.me/dsl)），通过提供声明式的写法提升布局代码的可读性。

建议通读源码，实现不复杂带来的使用体验却很有趣。或许我们也可以尝试设计一些 DSL 来优化特定问题。

### 🌟 [flutter-go](https://github.com/alibaba/flutter-go)

阿里出品，Flutter 组件演示 demo 和中文文档，同时包括了 iOS 与 Android，快上手试一试。

### [habbit](https://github.com/lzyy/habbit)

个人 Flutter 作品，演示了一个完整的习惯跟踪 App 。从完成度上看还可以，复杂度不够，主要是演示了 RxDart 的用法。

### [swift-algorithm-club-cn](https://github.com/andyRon/swift-algorithm-club-cn)

swift-algorithm-club 主要是 Swift 来实现算法和数据结构的源码和文章，对应文章都有对该算法的讲解，如果在学习或者复习算法的同学，不妨一看。

## 音视频

### [ggtalk | 广义跳槽论：简洁明了的方法论](https://talk.swift.gg/13)

这一期的 ggtalk 延续了上一次程序员比较关心的话题：跳槽。邀请来了老牌程序员、产品经理：Easy。相信经常刷微博的同学应该都知道他，Easy 之前在微博做过程序员和产品经理，也经历过独立开发。对于程序员的职场方法论有一套独特的心得，我听完之后感触颇深。比如作为程序员，不要只关注公司是否能出得起自己希望的薪水，更重要是要关注自己所能给公司带来的价值，不要被短期的供需不平蒙蔽了双眼。还有程序员如何提升自己的影响力？ 最重要是能给别人创造价值。除此之外，还有不少有趣的视角。推荐大家收听。

## 内推

- [北京-百度网盘 持续招 iOS 开发](https://talent.baidu.com/external/baidu/index.html#/jobDetail/2/102507)：社招、应届、实习均可。项目在技术上很有挑战性，团队技术氛围极好。诚心希望各路大神前来切磋，也欢迎计算机基础好的小白来共同学习。简历发邮箱 xuyafei01@baidu.com，暂不考虑的也欢迎微博私信 [@小非86](https://weibo.com/xuyafei86) 聊聊~

- [北京-蚂蚁金服 招iOS/安卓/前端开发](https://job.alibaba.com/zhaopin/position_detail.htm?trace=qrcode_share&positionCode=GP031268&from=timeline&isappinstalled=0)：负责支付宝会员及帐号业务线，地点北京国贸，金台夕照地铁站出口 100 米。有兴趣的同学欢迎将简历发送到：weijing.wdf@alibaba-inc.com / weijing.wdf@antfin.com （同一个邮箱）或者微博私信 [@折腾范儿_味精](https://weibo.com/agvicking) 了解情况。

- 上海即刻：如果你认识聪明勤奋、胆大心细、有追求的工程师，那就来加入我们吧！任何推荐或简历可直接发给 Jason（即刻 iOS leader）: jasy@okjike.com，或微博 [@JasonYuh](https://weibo.com/jasonyuh)。

- [杭州奇志科技招聘 iOS、前端](https://www.lagou.com/gongsi/34872.html)：奇志科技自 2016 年起通过行业无人机协同工作流 Mesh 进入物联网与人工智能领域， 并成功为房地产、建筑、测绘、电力巡检等行业提供无人机解决方案。感兴趣可以微博上私信 [@没故事的卓同学](https://weibo.com/u/1926303682) 了解。

- [深圳头条研发中心诚招各路 iOS 好手一起做取悦自己的项目](https://job.toutiao.com/2018/spring_referral/?token=alPR8WCv8nnnc5QqtsyKjw%3D%3D&key=MTY1MDMsMTg0MTQsMjA1MjAsMTk1NjEsMTU2ODksMTc0ODk%3D)：如想了解更多深圳头条的信息，可以加小T微信：tomtan，切磋技术和聊情怀都可以喔~~~~

- [北京字节跳动 iOS 团队持续招人中](https://job.toutiao.com/society)：简历可以发送到邮箱 raozhizhen@gmail.com，或者添加我（[@AidenRao](https://weibo.com/AidenRao)）的微信 jingmu1994 了解更多公司及岗位信息。

- [北京百度教育事业部招 iOS 开发](https://www.baidu.com/s?wd=百度)：百度教育事业部，地点：北京西二旗。部门下面有百度阅读，百度文库，百度爱听等 App 产品。团队技术氛围浓厚，有兴趣的同学欢迎将简历发送到我的邮箱：lizelei@baidu.com。

- [深圳 - 格隆汇 iOS / Android / 前端](https://www.lagou.com/gongsi/j84043.html)：公司方向是投研资讯，目前正在稳步扩张中，各个级别的工程师都有需求。任何推荐或者简历都可以发送到我邮箱：[chenkem@gmail.com](mailto:chenkem@gmail.com)，同时也欢迎大家[私信我](https://t.me/kemchenj)了解更多信息。

## 关注我们

我们开通了公众号，每期发布时公众号（OldDriverWeekly）会推送消息，欢迎关注。

![](https://github.com/SwiftOldDriver/iOS-Weekly/blob/master/assets/qrcode_for_wechat.jpg?raw=true)

同时也支持了 RSS 订阅：https://github.com/SwiftOldDriver/iOS-Weekly/releases.atom 。

## 本期编辑

[@四娘](https://kemchenj.github.io)，[@享耳先森](https://github.com/iblacksun)，[@Damonwong](https://weibo.com/damonone)，[@折腾范儿_味精](http://weibo.com/agvicking)，[@张嘉夫](https://weibo.com/2949394297)，[@Parsifal](https://weibo.com/parsifalchang)，[@aaaron7](https://weibo.com/aaaron7)，[@方秋枋](https://weibo.com/100mango)，[@kyo](https://github.com/KyoLi)，[@tom510230](https://xiaozhuanlan.com/u/6682065345)，[@anotheren](https://anotheren.com)，[@水水](https://www.xuyanlan.com)，[@looping](https://github.com/looping)，[@老老老老老老老驴](https://weibo.com/u/6090610445)，[@小非86](https://weibo.com/xuyafei86)，[@邦ben](http://weibo.com/linwenbang)，[@红纸](https://github.com/nianran)，[@含笑饮砒霜](http://chinafish.news)，[@JimQ](https://github.com/waz0820)，[@XanderXu](https://github.com/XanderXu)，[@老峰](https://github.com/GesanTung)，[@zvving](https://github.com/zvving)，[@J_Knight_](https://github.com/knightsj)

## 说明

🚧 表示需翻墙，🌟 表示编辑推荐

预计阅读时间：🐎 很快就能读完（1 - 10 mins）；🐕 中等 （10 - 20 mins）；🐢 慢（20+ mins）


