# 老司机 iOS 周报 #48 | 2018-12-17

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

## 福利

🌟 [我们发福利啦~](https://www.wjx.top/jq/32164990.aspx)

周报已经快陪伴大家走过一年的时间，非常感谢各位朋友的支持和厚爱。为了在 2019 年能更好地为大家服务，我们举办了一个问卷调查活动。在 12 月 27 日，我们会在参与问卷的朋友中选取合适的几个人赠与学习大礼包和现金奖。至于奖品是什么，大家可以在[这条微博](https://weibo.com/3165754627/H6t1EmqRh)中了解，转发还有额外的抽奖~我们渴望听到你们的声音！

## 新闻

[2018 App Store 年度颁奖典礼](https://mp.weixin.qq.com/s/rd3flwSuuXpHeKgtnwXnfg)

Apple 的年度 app 精选又出炉了，为了介绍和表彰获选 app，这是 App Store 和 Apple 官方微信联合呈献的 2018 App Store 年度颁奖典礼，欢迎围观下载。

[Perfect 4 将会使用 SwiftNIO](https://github.com/PerfectlySoft/Perfect-NIO)

[SwiftNIO](https://github.com/apple/swift-nio) 是一个跨平台、异步、事件驱动的网络应用框架，可用于快速开发和维护高性能的网络协议服务器和客户端。对比同样是 Swift 服务端的框架的 Vapor，已在今天 5 月发布的 Vapor 3 中全面使用了该框架。当然作为一个底层框架，你一般不会直接和它打交道。

## 文章

### 🌟 🐕 [解密 Runloop](https://mp.weixin.qq.com/s?__biz=MzI5MjEzNzA1MA==&mid=2650264704&idx=1&sn=c32d676f7c8a7803ac795442cd5fc377&chksm=f40685b5c3710ca3c2dc022e6703d3fd5e66545977c9e9fdc63ee71714123f8698639fe6f0a2)

很显然，`Runloop` 是一个很熟悉的名词，熟悉到每次面试都会碰到有人问你，请说说你对 `Runloop` 的理解。`Runloop` 是开源的，因此本文作者通过精简后的源码示例来解释 `Runloop` 的基本执行顺序。

- 基本流程：循环执行（执行任务->通知外部->休眠）。
- `Runloop` 依赖 `mach_msg` 进行进程间通信，也就是消息接收发送。
- `Runloop` 里面会执行 `source0`（可调用 `CFRunLoopAddSource` 创建），`source1`（仅系统调用）。
- `Runloop` 会执行5类任务 `timer, mainQueue, source0, source1, block`。
- `Runloop` 通过注册 `observer` 的方式来通知外部当前的任务执行状态，而5类任务中 `mainQueue，source1，block` 不支持注册 `observer`，也就是你无法通过 `obsever` 来得到准确的执行时间。
- `Runloop` 的 `Activity` 也是通过 `observer` 来通知外部当前处于哪个 `Activity`，当 `source0` 被执行的情况下，`kCFRunLoopBeforeWaiting`  和 `kCFRunLoopAfterWaiting` 会被跳过，意味着单纯通过对 `Activity` 的回调进行分析业务代码的执行状态是不可靠的。
- `Runloop mode` 分为 `common mode` 和 `private mode`，作者通过捕获 `mode` 得到了很多陌生的 `private mode`，分别用来处理不同的场景，例如 `_kCFStreamBlockingOpenMode` 用来调度网络任务。因此，`NSTimer` 在设置 `kCFRunLoopCommonModes` 的时候，也有可能因为 `private mode` 的调用从而导致延时。
- `Runloop mode` 可以中途切换，有以下几种切换位置：
    - sleep 之前
    - 执行 mainqueue 任务前
    - exit 之后
- `Runloop` 的运用场景：
    - 执行自己的任务，如 timer
    - 用于观测主线程的运行状态

延展阅读

- [深入理解RunLoop](https://blog.ibireme.com/2015/05/18/runloop/)

### 🌟 🐢 [一个 Demo 入门 Flutter](https://limboy.me/tech/2018/12/07/flutter-demo.html)

最近，已经有许多的公司开场尝试使用 Flutter 进行开发。就在前两天，Google 刚刚在北京举办了 Flutter Live  大会，可以说，Flutter 的生态已经越来越庞大。今年，如果对 Flutter 还是一无所知的话，是不是有点 out 了呢？没关系，这不，就有一篇教大家入门的文章。文章不仅讲了 Flutter 的基本结构，还用实际的代码编写了一个 Demo，想学 Flutter 的同学不妨跟着做一遍，相信比单单看文章更有效果哦。


### 🐕 [A modular analytics layer in Swift](https://www.lordcodes.com/posts/a-modular-analytics-layer-in-swift)

在公司里撸业务的开发同学对数据打点应该都不陌生，很多需求甚至一半的时间会花在实现打点逻辑上面，本文提出了一种抽象打点层的设计，用很 Swifty 的方式实现了可扩展（无痛添加新的 event），和后端解耦（切换打点 backend 不需要重构客户端打点代码）以及易配置（不同的打点携带不同的参数）。本文所体现的设计方面的思考对打点之外的一些公共组件的设计也能起到一定的指导作用，值得学习。

### 🐢 [Seemingly Impossible Swift Programs](https://www.fewbutripe.com/2018/12/05/seemingly-impossible.html)

本文借助 “Swift 中判断函数相等性” 的命题极力使用简单的描述和循序渐进的过程来讲解复杂的拓扑数学。

在建设性数学中，任何命题都可以转化为类型，任何证据都可以转化为这种类型的值。这使得我们能够将函数抽象成计算过程和返回值。在拓扑数学中，无限多数据的行为也会表现得像有限集合。 这使得我们可以证明这些计算过程的相等性。

虽然论证的过程和结果对于日常的 Swift 开发并没有用，但希望它们可以让你对数学燃起兴趣并感到敬畏。要知道数学已经能够产生这样一个违反直觉的结果，并对其原因进行极其简洁的解释。你甚至可以相信数学是指导你如何更好完成编程的灯塔。这些简单的数学结构（Functions, Monoids）构成了抽象的强大基础，而不像项目中的那些设计模式，过于复杂且只解决特定问题。

### 🐕 [使用 Metal 和 Core ML 评价照片质量](http://yulingtianxia.com/blog/2018/11/30/Photo-Assessment/)

文章展示了常规算法+机器学习来评价照片质量的方法，常规算法使用 Metal 处理图片，根据饱和度、亮度、模糊度和颜色分布得出客观评分，机器学习则使用 Core ML 加载 NIMA 模型预测主观评分。得到照片评分后，再检测相似照片，最终挑选最优的照片推荐给用户。
 
demo 中给出了 Metal 版边缘检测滤镜与图片特征向量提取的代码，可供学习参考。文章还总结了开源模型转化为 mlmodel 过程踩的坑。

### 🐢 [Why should we use Swift over Objective-C?](https://medium.com/@chungbkhn87/why-should-we-use-swift-over-objective-c-78b71725e63f)

Swift vs Objective-C，到底该怎么选？如果你正在纠结这个问题，请细读此文。

Objective-C 有着几十年的历史，更稳定；Swift，更现代化的语言，有许多先进特性，文章从多个角度对比了两种语言的优势和劣势。

### 🐕 [Strategy pattern in Swift](https://medium.com/flawless-app-stories/strategy-pattern-in-swift-1462dbddd9fe)

文章作者提出了一种用 Strategy pattern 思路来统一代码接口的做法。如果你对 Strategy pattern 不是很熟悉的话，可以看一下 Wiki 中[这里](https://zh.wikipedia.org/wiki/%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F)的介绍。

这种模式在现实场景中有时候还是能起到一定的作用的，有兴趣的同学不妨读一读文章，说不定以后就用上了呢？

### 🐕 [Using errors as control flow in Swift](https://www.swiftbysundell.com/posts/using-errors-as-control-flow-in-swift)

本文重点集中在使用 errors 上，主要介绍了一些用 errors 来进行处理能有明显优势的场景，而这些场景主要包括了函数输出结果的错误的处理，输入参数验证和测试中错误的抛出等。

由于 Objective-C 或多或少的影响，很多同学在写 Swift 的时候依然没有习惯用 errors 来进行错误处理。如果存在这样的情况的话，不妨可以从下一次小 refactor 中出发去寻找有没有可以使用的场景，多尝试，逐渐就能习惯使用。

### 🐕 [Xcode UI Testing Cheat Sheet](https://www.hackingwithswift.com/articles/148/xcode-ui-testing-cheat-sheet)

文章列出了 UI Testing 常用的代码片段，除了对 API 的梳理，还有对各种常见问题的解决方案，可以作为 UI Testing 的快速入门，也可以作为知识库以备日后查阅。

### 🐢 [质量监控-图片减包](http://www.sindrilin.com/2018/12/11/image_subtraction.html)

本文作者提供了三种方法，通过对图片资源的处理以达到减小包大小的目的。这三种方法分别是：

- 使用工具压缩图片
- 查找删除重复图片
- 查找复用相似图片

作者不仅详细讲解了具体的实现原理，还提供了相关实现代码。有兴趣的同学可以参考作者提供的方法，对自己的项目进行改造优化。

### 🐢 [Metal 专辑](https://www.jianshu.com/c/ac17a2f93445)

Metal 官方文档的中文翻译和 Metal 相关技术博客，适合英文不太好的同学。

### 🐎 [【AR 开发】ARKit 和 ARCore 功能对照表与定位场景总结](https://zhuanlan.zhihu.com/p/47839718)

ARKit 和 ARCore 功能对照表与定位场景总结，如果您同时开发 ARKit 和 ARCore，可能会用得上。

## 设计

### 🐎 [Animations in iOS: 30 beautiful examples](https://medium.com/flawless-app-stories/animations-in-ios-30-beautiful-examples-80cb2663c559)

有一些 iOS 动画真的很神奇，顺滑和友好的过渡动画能够指引流程，让用户理解下一步操作，即使盯着进度条也能感觉愉悦。下面请欣赏文中列出的 30 个动画杰作。

## 代码

### [Kingfisher 5.0 发布](https://github.com/onevcat/Kingfisher/releases/tag/5.0.0)

喵大的 `Kingfisher` 迎来了5.0的大版本更新，更新日志中的 `Reborn` 一词意味着重大更新。

`Kingfisher` 是一个轻量级的、纯 `swift` 网络图片加载库。虽然是大版本更新，但是 `API` 的变化不大，如果你从4.0升级到5.0或许只需要几分钟处理一下警告和错误。其中最大的变化就是提供了更好的缓存策略。因此，同学们可以考虑升级一番。

- 加入 `Result` 类型取代原来的 `tuples` 回调
- 为了方便调试追查错误，返回错误信息增加了错误原因和必要的关联信息
- `ImageCache` 重写，提供内存和硬盘缓存策略，`API` 兼容旧版本，同时提供了控制缓存最大值，是否预缓存等等配置
- 缓存策略：先搜索内存，没命中则搜索硬盘
- 支持 `ImageDataProvider` 协议加载本地图片

更新详情请参考：

- [Kingfisher 5.0 更新要点](https://github.com/onevcat/Kingfisher/wiki/New-In-Kingfisher-5)
- [Kingfisher 5.0 迁移指南](https://github.com/onevcat/Kingfisher/wiki/Kingfisher-5.0-Migration-Guide)

### [Swift 官方 Docker 镜像](https://github.com/apple/swift-docker)

苹果维护的 Swift 镜像，现在已经被[ Docker 官方](https://hub.docker.com/_/swift/)收纳。因此只需要执行 `docker pull swift` 即可方便搭建 Swift 的各个版本环境。目前来看苹果对于此镜像的维护程度还是蛮高的，最新支持到 Swift4.2.1 版本，与开发版本同步。

## 音视频

### 🌟 [Functional Swift Conference 2018](http://2018.funswiftconf.com/)

Swift 从诞生之日起，就具备了海量的函数式编程特性，无论是 enum 和 optional 的实现，或者是函数被当做一类公民，整个语言能看到不少 Haskell 的影子。自然，Swift 在实现一些函数式的思想和特性也非常的得心应手。Swift 的函数式编程，目前最经典的应用场景主要还是构建响应式的 viewmodel。如今，越来越多的人开始探索其他场景。Functional Swift Conf 是一个在纽约举行的，专门探讨函数式 Swift 的技术大会，如今已经放出所有的 presentation，其中除了一些 reactive view model 这样耳熟能详的话题之外，还有关于 state 管理、可组合 UI 等很有趣的内容。对函数式编程感兴趣的同学不容错过。

### [ggtalk | 要不要买 HHKB？我问了七位用户，听听他们怎么说](https://talk.swift.gg/7)

键盘，尤其是机械键盘，一直是程序员们居家旅行最重要的单品。甚至对于大多数程序员来说，键盘可能是极少数不多的可以让自己愿意一直花钱的东西，这就牵涉出一个话题：对于大多数程序员而言，什么键盘才是自己的最后一把键盘呢？本期 ggtalk，几个程序员针对这个话题，聊了聊自己使用 hhkb 的感受，有兴趣的同学可以听听。

PS：节目里没有严谨客观的评测。主观感受居多，比较轻松。

### 🚧 [MVC is Not Your Problem - Joachim Kurz - UIKonf18](https://www.youtube.com/watch?v=A1vzcxR-Ss0)

近年来，MVC 开发模式饱受争议，还经常被人抱怨说在这种模式下写出来的代码太多，耦合太重。于是就有很多人力图通过不断分解和改良 MVC 模式来解决它带来的问题。

UIKonf 上的这场分享就是从 MVC 切入来讲架构设计的。一开始先是介绍 MVC 模式，随后指出了很多人都误解以及用错了 MVC（分享中引用了很多参考资料，调研很充分），继而引出了大家容易忽视的点：有问题的不是架构模式，而是使用方式。即使是其他的架构也会带来其他的问题，如何通过 MVC 以及其他架构来达到开发目的才是重点。

本场分享者 Joachim Kurz，他的观点很明确，做架构设计，不需要刻板的遵循和套用规范，可以通过寻找合适的分解维度（分享的最后有介绍，27 分钟之后），让架构变得合理易懂即可。架构设计适可而止这个度是比较难把握的，需要深入具体需求场景（分享中举了几个例子，其中有介绍一个页面用到 10 个 ViewController 的），在平时的开发过程中不断实践和总结。

## 内推

- 小红书北京/上海招聘 iOS/Android 开发者：负责开发小红书 APP，APP 改变了大多数人的生活方式，我们改变了大多数女生看待生活的方式，加入我们，与一群年轻有趣的小伙伴一起打造下一个亿级用户产品。邮箱：cli2@xiaohongshu.com

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

## 关注我们

我们开通了公众号，每期发布时公众号（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)，[@张嘉夫](https://weibo.com/2949394297)，[@AidenRao](https://weibo.com/AidenRao)，[@Parsifal](https://weibo.com/parsifalchang)，[@aaaron7](https://weibo.com/aaaron7)，[@tom510230](https://xiaozhuanlan.com/u/6682065345)，[@anotheren](https://anotheren.com)，[@水水](https://www.xuyanlan.com)，[@looping](https://github.com/looping)，[@老老老老老老老驴](https://weibo.com/u/6090610445)，[@邦ben](http://weibo.com/linwenbang)，[@红纸](https://github.com/nianran)，[@含笑饮砒霜](http://chinafish.news)，[@JimQ](https://github.com/waz0820)，[XanderXu](https://github.com/XanderXu)

## 说明

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

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