# 老司机 iOS 周报 #64 | 2019-04-22

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

## 新手推荐

### 🐎 [Designing Swift APIs](https://www.swiftbysundell.com/posts/designing-swift-apis)
[@zvving](https://twitter.com/zvving)：如何写出可读性更高的代码？本文提供一些示例：参数标签可以帮助我们定义清晰易读的 API，嵌套类型能提供辅助的上下文关系，强类型为代码增添必要的仪式感，可扩展的 API 设计能同时满足便捷调用和丰富定制。

作者认为：『人人都是 API 设计师，当我们在设计非私有属性或方法时，我们都在设计 API』，你认为呢？

## 文章

### 🌟 🐕 [Humble Asset Catalog](http://lingyuncxb.com/2019/04/14/HumbleAssetCatalog/) & [Assets Catalogs 与 I/O 优化](https://juejin.im/post/5cb74d786fb9a068773948fc)

[@looping](https://github.com/looping)：这两篇文章分别从各自的角度解释了在使用 Asset Catalogs 后，读取图片资源的速度变快的原因。

通过仔细阅读这两篇文章，我们能够更清晰地了解到：
- Asset Catalogs 和 car (Compiled Asset Catalogs) 文件的相关内容以及它们的作用
- CoreUI 框架对图片资源加载过程的一些逻辑细节

从而明白使用 Asset Catalogs 后，在加载资源上速度更快的原因：
- Asset Catalogs 会对图片进行分类压缩存储，减少在目标机型上的资源文件大小，提高读取速度
- 通过内存映射 (mmap)，减少 I/O 操作，加速读取 car 文件内容
- car 文件实际上是一种特殊的 BOM 文件，能够在加载图片时直接获取 rendition、renditionKey 以及 attribute 这些信息，不同于从文件夹 (bundle) 中读取，需要执行耗时的 `-[CUIMutableStrucetedThemeStore canGetRenditionWithKey:]` 操作来读取 rendition 和 renditionKey

除了文章带给我们的结论，以及我们今后可以做的事情 (将常规资源文件都迁移到 xcassets 中) 之外，两位作者对问题的探寻和思考的方式也是非常值得学习借鉴的。

### 🌟 🐢 [Let’s write Swift code to intercept SSL Pinning HTTPS Requests](https://medium.com/@kennethpoon/lets-write-swift-code-to-intercept-ssl-pinning-https-requests-12446303cc9d)

[@含笑饮砒霜](http://chinafish.news)：现在几乎绝大部分的 iOS App 都使用了 HTTPS 请求，这极大提升了我们使用的安全性，但也不意味着这就是绝对安全的。

如果想检查 iOS 应用中的 HTTPS 请求，最常用的方法就是中间人（MITM）攻击，这种技术需要使用某台主机作为代理服务器，为客户端提供服务。为了保证攻击成功，客户端需要将代理服务器的证书安装到设备的全局信任存储区中。这样处理后，客户端就会将证书添加到白名单中，允许与代理服务器之间的 HTTPS 通信。

如果想保护应用免受 MITM 攻击影响，可以使用 SSL 校验证书绑定，此时受信任服务器的证书副本会打包到 iOS 应用中，还有一些附加代码可以确保应用只与使用特定证书的服务器通信。当 SSL 证书绑定处于激活状态时，应用不会将任何请求发送到不受信任的服务器上。

即便如此，也依然可以绕过 SSL 证书绑定。也就是在具体请求通过受保护的 HTTPS 通道发送之前，尝试拦截这个请求，这需要将代码植入到应用中，这里会用到代码注入的相关知识。

如果想更细致的了解如何拦截 HTTPS 请求，本文不可错过，绝对深度好文。

### 🌟 🐢 [干货 | 近万字长文详述携程大规模应用RN的工程化实践](https://mp.weixin.qq.com/s?__biz=MjM5MDI3MjA5MQ==&mid=2697268025&idx=1&sn=2d197c4cf7a338246abe0d3111e16002)

[@Damonwong](https://github.com/Damonvvong): 如果谈起 React Native 在国内的业务落地，我可能第一个会想起的就是携程和赵辛贵老师。在上次听完赵兴贵老师分享的专题《携程无线持续交付平台工程实践》之后，意犹未尽，一直想更加深入了解一下携程在 RN 方面的技术探索。今天终于等到了携程的 RN 建设及他们设计的 CRN 的分享。这篇文章主要讲了下面几个事情：

1. RN 在携程中的使用情况
2. 携程基于 RN 优化的 CRN 框架的设计及使用
3. CRN 做了哪些性能优化及实际效果比较
4. 如何发布及运维

比较可惜的是没有看到这套系统相比较于原生开发，对业务增长，开发效率有哪些优化，所以比较期待后续能有这方面的分享。

最后，在文中提到将要开源的 CRN，也已经开源了，感兴趣的同学移步 [携程开源RN开发框架CRN](https://mp.weixin.qq.com/s/r6mB5Zq3jIf-K2YQi_AS8Q) 查看。

### 🐎 [JSON as configuration files: please don’t ](https://arp242.net/weblog/json_as_configuration_files-_please_dont)

[@olddonkey](https://github.com/olddonkey)：这是一篇 2016 年的老文章，但是其中的观点直到今天依然具有参考价值。

很多公司，很多团队使用 JSON 文件作为 App 的配置文件，不论是从远程下发，还是本地加载。

但是，在实际的项目中，用 JSON 来作为配置文件解决方案并不是个完美的方案，它存在的很多问题，这些问题会在实际中逐渐暴露。

文章作者围绕这他心中的几个缺点展开论述：

1. 注释容易缺失。
2. 可读性差。
3. 过分严格的格式。
4. 缺乏可编程性。

本文虽本意是针对 Web 开发提出观点，但是对 Mobile 开发也一样适用。

### 🐎 [Swift 5 Frozen enums](https://useyourloaf.com/blog/swift-5-frozen-enums)

[@没故事的卓同学](https://weibo.com/1926303682/profile)：在 Swift 5.0 中编译器针对使用 C style 枚举增加了一类提醒（即使 `switch` 已经覆盖了所有的 `case` 依然会有这样的警告）：

> Switch covers known cases, but 'XXXXX' may have additional unknown values，Handle unknown values using "@unknown default"

提醒用户虽然现在你已经覆盖了所有的 `case`，但是未来这个枚举值有可能会增加新的值，我建议你还是处理一下这样的情况。

不过有的枚举值作者可以保证未来不会新增值，针对这个场景苹果增加了 `NS_CLOSED_ENUM`。如果枚举用 `NS_CLOSED_ENUM` 声明而不是 `NS_ENUM`，Swift 使用这个枚举编译器就不会产生建议使用 `@unknown default` 的警告。

### 🐎 [Asynchronous completion handlers with Result type](https://mecid.github.io/2019/04/17/asynchronous-completion-handlers-with-result-type/)

[@邦Ben](https://github.com/linwenbang)：Swift 5 中的标准库中加入了 Result Enum (success / failure)，该文作者通过一个 URLSession 的请求例子，演示了使用 Result Enum 改造过程。使用 Enum 会让你的程序看上去更为简洁以及意思明确，详细请看文章内容。

### 🐕 [Improve your iOS team’s productivity by building features as frameworks](https://medium.com/flawless-app-stories/improve-your-ios-teams-productivity-by-building-features-as-frameworks-9d2a64cbcab5)

[@老峰](https://github.com/GesanTung)：如果你使用 Swift 开发过大一点的项目，那么你可能会有这样的感受，明明只是修改了一行代码，但却把整个 App 重新编译了一次，花费了很多时间。

本文作者针对这一痛点提出一种优化方案，通过把功能独立的业务代码改为 Framework 动态库，这样就不会每次重新编译整个 Project，从而减少编译时间，文中结合[示例](https://github.com/akfreas/SimpleCounter)代码给出了详细的优化过程。

尽管作者这一方案可以缩短编译时间，但如果 Framework 粒度太小，太多动态库反而会引起其他问题如增加 APP 启动时间、App 安装包变大；粒度太大，每次修改代码又会涉及多个 Framework ，编译时间优化又不会很明显，感兴趣的读者可以借鉴这一思路，做些有益的尝试。

### 🐕 [How to deploy a Swift backend on Amazon AWS](https://medium.com/@gianpispi/how-to-deploy-a-swift-backend-on-amazon-aws-ea9213518c43)

[@小非86](https://weibo.com/xuyafei86)：目前 Swift 的后端框架主要有 Perfect、Vapor、Kitura 和 Zewo 等。[往期周报](https://github.com/SwiftOldDriver/iOS-Weekly/blob/59bfdf3859a67d5667319000e4ee70f8f9cd6f76/Reports/%2329-2018.07.30.md) 推荐过使用 [Perfect](http://blog.yuusann.com/posts/article/18014) 开发后端的经验。本期推荐大家这篇使用 Kitura 开发后端的另一种尝试。

### 🐕 [Disjoint-set union in C++ and Swift](https://medium.com/flawless-app-stories/disjoint-set-union-data-structure-in-c-and-swift-a52703b01fcb)

本文使用 C++ 与 Swift 实现了简单的并查集。大家可以借此对比同一个数据架构在不同语言的实现。

## 工具

### [Accio](https://github.com/JamitLabs/Accio)

Accio 是一个基于 SwiftPM 和 Carthage 的包管理工具，其有以下特点：

- 依赖预编译，也就是二进制化。
- 自动集成到项目文件里，不像 Carthage 那样需要手动集成，这也解决了 Carthage 项目中最麻烦的部分。
- 基于 SwiftPM 的依赖管理系统，只要第三方库使用 Package.swift 声明即可，不需要去跟 xcodeproj 和 Cartfile 打交道。
- 基于 SwiftPM 的缓存管理，可以减少不必要的重复的下载和编译。

## 代码

### [Markdown Playgrounds for Swift](https://github.com/objcio/markdown-playgrounds)

[@莲叔](https://weibo.com/aaaron7/)：Markdown Playgrounds for Swift 是 objc.io 基于 Swift5 开发的一款 markdown 编辑器，最大的特性就是在你 markdown 中的 Swift 代码可以被执行。对比传统 markdown 编辑器，核心就是实现了 Swift 语法的高亮以及将 Swift 代码提取出来后用 Swift REPL 程序去执行并拿到返回的结果（Swift REPL 程序就是终端中的 Swift 命令)。整个工具是开源的，并且 objc.io 有一整套配套的教学视频（第一章是免费的）一步步的教你如何写一个类似的工具出来，从工具的属性可以看出从中可以学到各种高级的字符串处理(如符号高亮、代码提取等)，算是非常不错的 Swift 学习材料。

## 音视频

### 🌟 [深入了解 Flutter 的高性能图形渲染](https://mp.weixin.qq.com/s/RNhdYtoQ8RQcjIXJReGZWA)

[@CrazyCoderShi](https://github.com/CrazyCoderShi)：本视频为 Google Flutter 团队的软件工程师 Yuqian Li 在 2018 谷歌开发者大会做的演讲，内容包含 Flutter 介绍，Flutter 的工作原理（对比原生开发和其他跨平台框架），[Skia](https://skia.org/index_zh) 介绍，分析常见的性能瓶颈等，通过解决 Flutter 样例 App - Flutter Gallery 的性能问题（[Issue #13736](https://github.com/flutter/flutter/issues/13736)），与大家分享如何通过 Flutter 工具定位、调试和解决性能问题。

视频主要讨论点：

- Flutter 为何能够拥有媲美原生的高性能图形渲染
- 如何通过 Skia 调试来分析 Flitter 应用
- 关于 saveLayer 和 clipPath 的注意点
- 使用 flutter screenshot 截取 skp 来单步调试绘图指令

### [ggtalk | 向架构进发](https://talk.swift.gg/26)

[@J_Knight_](https://github.com/knightsj)：本期 ggtalk 邀请的嘉宾是 Casa Taloyum，他所写的 iOS 架构系列文章在社区非常受欢迎。本期主要围绕“架构”这一主题，主要讨论了以下几点：

- 做架构到底是在做什么
- 架构师和工程价值观
- 架构师和高级工程师的区别在哪里
- 如何定义真正的问题
- 如何看待新技术和旧技术

除此之外，Casa 还分享了对跨平台技术以及区块链的一些看法。

推荐阅读：

- [《iOS 应用架构谈》](https://casatwy.com/iosying-yong-jia-gou-tan-kai-pian.html)

## 内推

老司机周报团队联合知识小集和 SwiftGG 翻译组收录了一份靠谱的内推职位。

如果你想**找工作**，点这里：https://www.yuque.com/iosalliance/article/bhutav

如果你想**招人**，点这里：https://www.yuque.com/iosalliance/article/ycyhf3

当然，也欢迎你关注我们每一期的周报，我们会在每期周报底部及时更新编辑内推岗位。

## 关注我们

我们开通了公众号，每期发布时公众号（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 。

## 说明

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

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


