# 老司机 iOS 周报 #81 | 2019-08-26

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

## 新手推荐

### 🌟 🐎 [Modular Architecture in iOS](https://medium.com/flawless-app-stories/a-modular-architecture-in-swift-aafd9026aa99)

[@老峰](https://github.com/GesanTung)：在大型项目中，经常会有这样的场景：我们明明只修改了一部分代码，却把整个工程编译了一次。在这篇文章里作者通过使用 Cocoapods 实现模块化，将每部分模块编译为 Framework 动态库，宿主 App 依赖这些模块,从而实现模块化，文章给出了具体的操作过程，以及[示例](https://github.com/leandromperez/multiprojects)感兴趣的读者可以看看。

### 🐎 [UIDocument From Scratch](https://www.raywenderlich.com/1809473-uidocument-from-scratch?utm_campaign=rw-weekly-issue-231&utm_medium=email&utm_source=rw-weekly&__s=mppzsrcqwzmhtwhkt6vh)

[@极速男孩](https://github.com/ztlyyznf001)：UIDocument 是苹果提供给我们方便的管理文档的类。在这篇文章中，会从头开始叫你如何使用 UIDocument 去创建，取回，修改，更新 iOS 的文件系统。

## 新闻

### 🌟 [知识小集官网上线啦！](https://mp.weixin.qq.com/s/kOwf_xJOXHi2EIdj72N7eg)

知识小集官网正式上线。官网中的内容都来自于「知识小集公众号」。小集团队把公众号的内容分为「18个专题」，比如性能优化、模块设计、Web 与 NA 交互专题，几乎每个专题都有 10 多篇文章，甚至更多。还有部分文章未加入到官网中，后续会逐渐加入进来。这样的设计目的是为了能够更方便地学习相关专题的知识。赶紧收藏起来吧~

### 🐎 [App Store Today editorial stories are now available on the web in full](https://9to5mac.com/2019/08/15/app-store-today-web-browser/)

[@张嘉夫](https://github.com/josephchang10)：App Store 的编辑介绍文章之前可以通过链接进行分享，但 web 版本仅仅是一个标题以及一个“跳转至 App Store”的链接。8月9日到8月11日之间，Apple 更新了其 App Store 预览页面，用户现在可以通过桌面浏览器查看完整的编辑介绍文章，包括完整的图片、app 列表和段落，拥有和 App Store 完全一致的体验。

## 文章

### 🌟 🐎 [加载速度提升 15%，携程对 RN 新一代 JS 引擎 Hermes 的调研](https://mp.weixin.qq.com/s/BOeuLoZjCdi61P_MhaJT0g)

[@looping](https://github.com/looping)：Hermes 是 Facebook 在 Chain React 2019 大会上发布的新一代 JavaScript 执行引擎，用于提高 React Native 应用的性能。本文是携程在 CRN 项目中集成 Hermes 的深度调研总结，内容包括：

- 对 Hermes 的介绍，包括它的优化思路和集成使用
- 和 JavaScriptCore 以及 V8 的性能对比
- 引擎的动态性分析
- 集成使用过程中发现的一些问题和后续计划

由于 iOS 审核限制，目前该引擎仅用于 Android 平台。虽然携程调研完发现由于缓存问题还不能在线上版本直接引入 Hermes，但也表明 Hermes 通过预编译字节码的方式提升 JS 执行速度给了他们新的思路，比较期待他们之后在性能优化上会有新的实践成果输出。

### 🌟 🐕 [基于 Mach-O 符号重排减少缺页中断次数来提升 iOS App 启动速度的可行性分析](https://juejin.im/post/5d5a05255188251f4705fb8b)

[@Jimq](https://github.com/waz0820)：本文对 [「抖音研发实践：基于二进制文件重排的解决方案 APP 启动速度提升超 15%」](https://mp.weixin.qq.com/s/Drmmx5JtjG3UtTFksL6Q8Q) 提出的技术方案的可行性和价值进行分析和验证。

- **iOS 调页策略验证**：通过构造一些分散在不同页的符号并调用他们，然后分析缺页中断报告，最终验证了内核在处理缺页中断时并没有预载入相邻的页，程序的运行过程是由缺页中断驱动的。

- **重排方案验证**：创建一个 Order File，按顺序写入符号，验证了链接器会按照 Order File 中预设的顺序来排列符号。

- **分析启动链路上的符号**：这一块作者提出了三条思路：静态分析、堆栈采样和 Hook，但并没有做具体的验证。

### 🌟 🐕 [MTFlexbox 自动化埋点探索](https://mp.weixin.qq.com/s/aJcboLm5MYiGW-QC8AHHyQ)

[@红纸](https://github.com/nianran)：MTFlexbox 是美团基于 Flexbox 的规范实现的跨平台动态化解决方案，通过下发三端统一的 XML 布局文件达到动态化的目的。文中分析了三种业内自动化埋点的解决方案并提出了自己的解决方案：

1. [美团外卖前端无痕埋点实践](https://tech.meituan.com/2017/03/02/mt-mobile-analytics-practice.html)：其利用 AOP 的方式来达到业务与埋点的解耦，但是没法做到数据的自动上报。
2. [Mixpanel](https://mixpanel.com/)：成熟的可视化方案埋点方案，其通过截屏上报的元素和元素路径方式，达到圈选元素的功能，但是依旧无法支持数据上报，对于动态化布局也是支持有限。
3. [HubbleData](https://www.jianshu.com/p/f0c4e280357c)：其也是通过对于元素路径的把控进行埋点上报，对于动态化布局支持有限，业务数据获取不够。
4. MTFlexbox 的自动化解决方案：上传布局文件 -> APP 装机渲染页面同步服务端界面元素和页面数据 -> 前端 Web 渲染截图元素 -> 数据 RD 圈选元素埋点 -> 服务器生成带有埋点信息的布局文件。其基于自身有良好的 XML 布局文件的解决方式，为埋点添加唯一标识，插入到页面元素中，来达到元素定位的效果。

### 🐕 [Future-Proof Your Data Persistence](https://cutecoder.org/programming/future-proof-data-persistence/)

[@老驴](https://github.com/olddonkey)：如果同学们在自己或是公司的大型项目中实现过数据库，一定会知道数据访问对象（ DAO ）是什么。简单来说，它就是一个用于对隔离与限制外部对数据源的直接修改的中间层，用来提升数据库的安全性和稳定性。对于 iOS 开发来说，DAO 也是必不可少的。虽然在很多情况下，你所用到的数据库都已经写好了 DAO 这一层，但是如果能够在项目中进一步封装，或者是在了解原理的情况下，针对自己的需求进行改进，也能极大的帮助项目。如果你对 DAO 还不是很熟悉的话，建议了解一下。

### 🐕 [lldb 入坑指北（2）-​ 15行代码搞定二进制与源码映射](https://mp.weixin.qq.com/s/Bc8AJe7qRi2ED-otK0qPRA)

[@莲叔](https://weibo.com/aaaron7)：源码二进制化以及围绕二进制化之后的调试效率是 iOS 工程化难得的热点。之前美团的 zsource 方案较好的解决了调试效率的问题。本文作者基于 LLDB 的源码映射能力，以更简洁、易用的形式实现了该功能，整个过程由 Xcode 自动完成，不需要输入命令，同时作者也 share 了 python 的实现代码，有兴趣的同学可以仔细研究。

### 🐕 [The power of subscripts in Swift](https://www.swiftbysundell.com/posts/the-power-of-subscripts-in-swift)

[@四娘](https://kemchenj.github.io)：本周 SwiftBySundell 为我们带来的是 subscript 功能：

- subscript 和 method 的区别和各自的场景
- 如何自定义 subscript
- subscript 的重载
- subscript 的 getter 和 setter 写法以及泛型的使用
- Swift 5.1 中引入的 static subscript 

对于 subscript 功能还不熟悉的同学可以考虑通过这篇文章补充相关知识。

### 🐕 [iOS 的 Code Signing 体系](https://juejin.im/post/5d3feaf7e51d4561e224a2a7)
[@水水](https://www.xuyanlan.com)：iOS 中的 Code Signing 体系非常复杂，对新手非常不友好，虽然目前网上已经存在大量文章对此进行比较透彻的分析，最核心的部分已经讲解得非常清楚，但作者始终还是对 Code Signing 体系中很多相关的地方有着疑惑，于是决定认真地探究一番。本文会引用一些比较好的文章中的内容和图片，加上一些作者个人的理解进行分析，是比较全面和友好的一篇关于 Code Signing 的文章，想了解 Code Signing 的同学可以详细阅读哦。

### 🐕 [通过 Signal handling（信号处理）获取任意线程调用栈](https://juejin.im/post/5d5ab438f265da03af19d35b)

对于一些系统监控类的需求，如 crash 、性能指标收集、上报之类的工具库，常常会需要得到线程调用栈信息，本文提供了一种通过 Signal handling 来获取任意线程调用栈的方式，该方式解决了使用 StackPointer 在 Swift 下无法打印结果的问题。

## 工具

### [Why you should stop using Git rebase](https://medium.com/@fredrikmorken/why-you-should-stop-using-git-rebase-5552bee4fed1)

[@享耳先森](https://github.com/iblacksun): 文章作者认为现今大家使用 `git rebase` 的过程中过于追求 commit history 的线性，而忽略了 `git rebase` 相较于 `merge` 带来的隐患： 在一个长的 commit 链中使用 rebase 解决冲突是非常困难、易出错的。作者也给出了两种解决方案，详情请阅读原文。

### [KakaJSON](https://github.com/kakaopensource/KakaJSON)

[@AidenRao](https://weibo.com/AidenRao)：Swift 内置了一套 Codable 机制，可以用于 JSON 转 Model。对于一些简单的模型结构，还是挺好用，但一旦牵扯到复杂的模型结构、一些个性化的需求（比如 KeyMapping、类型不匹配时的转换处理、自定义解析规则等），Codable 就不太能友善地完成任务了。

为了解决上述问题，作者编写了一套纯 Swift 实现的 JSON 与 Model 互相转换的框架：KakaJSON。KakaJSON 通过了大量的单元测试用例，应对各种常用的数据场景，对外提供了一些友善易用、扩展性强、可高度个性化定制需求的接口，内置了 Metedata 缓存等机制，加快转换速度。

### [HackMan](https://github.com/Cosmo/HackMan)

[@AidenRao](https://weibo.com/AidenRao)：HackMan 是一个直接通过命令行生成样板代码的简单工具，几行命令，就可以帮你 run 起来一个简单的 APP。

## 代码

### 🐎 [CombineDataSources](https://github.com/combineopensource/CombineDataSources)

[@zvving](https://github.com/zvving)：基于 Combine 实现 Table&Collection view data sources，提供简明的声明式数据绑定方法，写法类似：

```swift
var data = PassthroughSubject<[Person], Never>()

data.subscribe(subscriber: tableView.rowsSubscriber(cellIdentifier: "Cell", cellType: PersonCell.self, cellConfig: { cell, indexPath, model in
    cell.nameLabel.text = model.name
}))
```

设计思路和 [RxDataSources](https://github.com/RxSwiftCommunity/RxDataSources) 基本一致，目前处于早期阶段，对 Combine 感兴趣不妨一读。

### [JXTheme](https://github.com/pujiaxin33/JXTheme)

[@anotheren](https://github.com/anotheren)：iOS 13 中 Apple 终于也将深色模式带到了手机端。但是如果要在更早的系统中使用深色模式/更换主题应该如何处理呢？JXTheme 带来了相关扩展，支持 iOS 9+，接口与 iOS 13 提供的相似，你可以在需要时方便快速切换。

> 本工具库由 [暴走的鑫鑫](https://github.com/pujiaxin33) 自荐，他热爱分享，喜欢钻研，目前已经在 Github 创建了 20 多个库，累计获得 5k star。

### [玩儿 Android flutter 版](https://github.com/CCY0122/WanAndroid_Flutter)

[@CrazyCoderShi](https://github.com/CrazyCoderShi)：玩儿 Android 这个应用有一系列的教程 app , 不例外也有 Flutter 版本的, 是一个完整的应用, 并且该应用中使用了不少官方推荐的开发模式, BloC 、Provider 等. 值得 Flutter 新手同学好好学习.

## 内推

老司机周报团队联合知识小集和 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）


