# 老司机 iOS 周报 #44 | 2018-11-19

![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) 提出。

## 文章

### 🐢 [Implementing features with ReactiveFeedback](https://ilya.puchka.me/implementing-features-with-reactivefeedback/)

本文作者通过一个实例演示来介绍他们团队写的单向数据流应用框架 [ReactiveFeedback](https://github.com/Babylonpartners/ReactiveFeedback)。由于作者所在团队用的是 `ReactiveCocoa`，所以他们就基于 `ReactiveSwift` 自己实现了一套类似 `RxFeedback` 的框架。

虽然是教程类的文章，而且还是写自家框架的，但是阅读本文还是会有三层收获：
- To 普通开发，了解应用开发还能这么玩。如果大家对 `Redux`, `ReSwift`, `RxFeedback` 这些比较熟悉的话，文中介绍的框架结构和用法还是很好理解的。即使不熟悉，认真看也是能懂的，因为文章写得真是超级详细；
- To 框架维护，理解他们做类似架构演进的思路。单向数据流应用框架的可维护、可预测以及可测试性等这些特点可以较好地解决一个复杂应用工程会面临的臃肿混乱难以管理的问题。文中也提到 `ReactiveFeedback` 没有设计全局的应用状态，但是每个功能模块与外部交互时都有明确的主入口，内部只有自己独立的状态，使用起来非常简单灵活和方便；
- To 技术管理，通过技术手段来提高工程质量和效率是非常有意义的，特别是大家一起维护一套开发框架。能对应用架构和编程模式不断地进行探索，也是工程师文化的很好体现。经常做这类技术输出的团队肯定也是大部分人所向往的有技术氛围的团队。

### 🐢 [Docker ❤️ Swift & Vapor](https://theswiftdev.com/2018/11/15/docker-loves-swift-and-vapor/)

Docker 作为近几年来服务端最重要的技术创新之一，解决了无数配置与运维的噩梦。而另一边，Server-side Swift 的蓬勃发展，似乎和 Docker 拥抱已经是一个必然。本文既是一篇非常棒的 docker 入门文章，用很简洁的篇幅讲了 docker 是什么，能做什么，并且给出了相应的学习路径，同时，也是一篇介绍如何使用 docker 技术来提升 Server-side Swift 的开发与配置效率的文章。作者生动的介绍了如何制作 Swift 的 docker image，如何实时修改 docker image 中的代码，最后还提出基于 docker compose 来实现基于 Vapor 的微服务架构，非常酷！ 推荐大家阅读。


### 🚧 🐕 [Assertions in Production](https://medium.com/device-blogs/assertions-in-production-e587fef5bfbc)

作者围绕断言的使用展开了以下探讨：

- 如何上报断言（Assertion）？

    首先作者分享了将断言上报的代码片段。作者认为相较于 Property Testing（性质测试），断言等于真正的用户产生的 Property Testing，更加随机、多样和不可预测，而且不需要写任何测试用例。

- 何时加断言？

    作者一般的规则是，在没有 `else` 的情况下，应该加断言。以下情况下也会加断言：确保方法传参正确的时候；从字典里用已知的 key 取值的时候（如 `NSNotification``userInfo`）；确保必须在主线程进行的操作当前是否在主线程的时候；打开关键的数据库或者文件失败的时候。

- 对于线上的产品，是否应该让断言处 Crash?

    作者认为没有必要。断言可以当做错误上报，但不应该造成闪退。

### 🐕 [Avoiding race conditions in Swift](https://www.swiftbysundell.com/posts/avoiding-race-conditions-in-swift)

Race condition, 即竞争条件。我们都知道，当多个线程同时访问相同的资源，就可能会出现意想不到的问题。对此，线程安全一直是开发中需要额外关注的一个问题。本文讲了在 Swift 中，race condition 可能存在的场景，以及在平时的编码中，如何尽可能避免这种问题。

### 🐕 [What's .self, .Type and .Protocol? Understanding Swift Metatypes](https://swiftrocks.com/whats-type-and-self-swift-metatypes.html)

`Swift Metatypes`，可能每天都在用，却很难解释清楚到底是什么东西，Apple 文档对此描述也比较晦涩，只说 `type of a type`。

文章从最简单的 `String` 开始，讲 `String.Type`、`string.self` 之间的关系，串起 `.Type` `.self` `type(of:)` `Protocol`，最后还介绍了一些 `Metatypes` 使用场景。

### 🐕 [用 Swift 解读 React/React Native: Part 1 - React Element & React Component](https://tech.glowing.com/cn/react-native-explained-in-swift-part-1-element-and-component/)

本文系列文章第一部分，作者希望将 `React/ReactNative` 中的主要编程思想，应用在 `Swift` 中，以此提高提升开发效率和代码质量。作者认为 `React` 的核心概念为，将数据转化成视图描述数据，也就是 `Data` 到 `React Element` 的过程。在这个过程中，无形中引入了单向数据流，提升了代码的规范性和开发效率。文中介绍了如何用 `Swift` 实现 `Componet, Element, Node` 这几个关键部分。

### 🐢 [Mirror / Custom​Reflectable / Custom​Leaf​Reflectable](https://nshipster.com/mirror/)

相对于 `Objective-C` 来说，Swift 没有 `Runtime` 不能实现类似 `swizzing` 功能。但得益于 `Mirror` 的`反射`功能，我们可以得到对象信息的只读访问，`Playground` 就是 `Mirror` 的一个主要场景。文章介绍了 `Mirror` 及相关的 `Custom​Reflectable` `Custom​Leaf​Reflectable` 两个 `protocol`  使用细节。

### 🐕 [分析实现-倒计时设计](http://sindrilin.com/2018/01/06/count_down_design.html)

倒计时器是一个日常开发中很常见的需求，通过 `NSTimer`、`GCD` 或者 `CADisplayLink` 都可以轻易实现。本文作者在看到一个基于 `NSOperation` 的全局计时器方案后，引发了如何完成一个更高效、接口设计更合理的倒计时器轮子的思考。从选择存储结构出发，到最后的逻辑封装，作者一步步完成了自己的倒计时器。

虽然是一个很小的需求，但却很考验开发人员的编码能力，希望各位读者都能够从作者这种软件设计思维中有所得。

### 🐕 [在 Flutter 中嵌入 Native 组件的正确姿势是...](https://www.jianshu.com/p/82bb88d1ffe5)

闲鱼团队的新文章，他们算是最早用上 Flutter 重写自己 App 的大厂团队，趟过的坑一定不会少，也值得其他人学习经验。

Flutter 最近也在各个国内大厂掀起了应用浪潮，如果有打算应用 Flutter 或者是已经在尝试应用 Flutter 的同学们，不妨考虑先读一读闲鱼团队的系列文章，可以让你少踩很多坑。本文就介绍了闲鱼团队在项目中嵌入 Native 代码的做法和背后的源码中的原理，虽然 iOS 中还暂时没有出现和 AndroidView 对应的控件，但是相信之后一定会有对应的控件跟上。目前在 Android 端有需求的同学们不妨先学习参考。

### 🐕 [Custom​Playground​Display​Convertible](https://nshipster.com/customplaygrounddisplayconvertible/)

本文介绍了我们熟悉的 `Playground`，它通过 `PlaygroundLogger` 框架来实现实时反馈。文章前半部分花了大篇幅介绍这个框架支持展现的类型和 `Custom​Playground​Display​Convertible` 协议的用法。文章后半部分则从 `Playground` 自身的特殊性展开，总结了 `Custom​Playground​Display​Convertible` 跟 `CustomStringConvertible`、`CustomDebugStringConvertible` 以及 `Debug Quick Look` 之间的关系。读完全文，不仅能让我们知道了 `Custom​Playground​Display​Convertible` 怎么用的，而且也清楚了它的具体使用场景。

### 🐕 [Debugging a subtle Swift bug that will make you facepalm](https://www.jessesquires.com/blog/debugging-subtle-swift-bug-facepalm/)

Jesse Squires 在修复一个 UI 测试的崩溃时，发现是因为 json 序列化时使用了 `[String: Any]` 作为容器，赋值时少写了一对括号导致的问题：

```swift
func toDictionary() -> [String: Any] {
    var dict: [String: Any] = [:]

    // code setting other keys and values...

    dict[JSONKeys.dateClosed] = self.dateClosed?.toMongoDate

    return dict
}

extension Date {
    func toMongoDate() -> [String: Any] {
        // return date in expected mongo date format
    }
}
```

这段代码是 Codable 之前就存在的，从这方面也印证了 Codable 的好处。


### 🐕 [支付宝客户端架构解析：iOS 客户端启动性能优化初探](https://mp.weixin.qq.com/s/ewYBMdqrjVJUthRxkFW_3g)

支付宝 mPaaS 团队又向大家带来了一篇启动性能优化的实践，本片文章主要从另一个角度探索启动性能优化，利用苹果的 Background Fetch 让 App 在后台的时候就能处理一些预加载任务，来解决真正启动性能中比较耗时的图片加载问题。我们也可以借此了解一下 iOS 的这种 Background Fetch 伪后台的作用机制


## 工具

### [Commander](https://github.com/devedbox/Commander)

`Commander` 简单而言，就是你通过 `Decodable & Decoder` 协议的规则书写 `struct` 来描述 `cli` 参数的输入，该库会进行解析检查，并且提供对应的描述帮助信息，也提供自动补全的机制。

### [Code Friend](https://qvcodefriend.github.io)

自 Xcode 8 开始，苹果提供了 `XcodeKit` 用于开发 Xcode Extensions，但是开发者们似乎并不买账。Code Friend 通过 `JavaScriptCore` 封装了 `XcodeKit` 的原生方法，并提供了使用 JavaScript 接口来快捷地开发 Xcode 插件。你可以直接在 Mac App Store 中找到它，但是还是建议你先读一读[这篇文章](https://mp.weixin.qq.com/s/oQJXtZYcO4u6m4SCHZUT_w)。

## 音视频

### ["Promises everywhere", with special guest Max Howell](https://www.swiftbysundell.com/podcast/36)

15 年的时候，有位牛人，曾经在 Twitter 上吐槽自己去 Google 面试被拒经历。Google 说 90% 的工程师使用他写的软件，但是因为他不能在白板上翻转二叉树，so fuck off...这个事情相信很多人都听过，而这个人，正是大名鼎鼎的包管理软件 HomeBrew 的作者  Max Howell 。就在近期，Sundell 邀请了他作为嘉宾，在这期播客里讨论了包管理器的设计、异步编程、面试流程以及 Swift Package Manager 是如何诞生的。

## 内推

- [北京-百度网盘 持续招 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。

## 关注我们

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

![](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)，[@AidenRao](https://weibo.com/AidenRao)，[@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)

## 说明

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

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