# 老司机 iOS 周报 #67 | 2019-05-13

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

## 新闻
### [19 年老司机周报定制 T 恤上架啦](https://item.taobao.com/item.htm?id=592379266013)

只订做一批，错过不再有。![只要钱到位](https://user-gold-cdn.xitu.io/2019/5/9/16a9a4d3e9dca8ff?w=1000&h=668&f=jpeg&s=88292)

### 🚧 [Google I/O for Flutter](https://developers.googleblog.com/2019/05/Flutter-io19.html)

[@CrazyCoderShi](https://github.com/CrazyCoderShi)：伴随着 Google I/O 大会召开，Flutter 这几天又刷屏一波，一个好消息和一个坏消息：

- [好消息 | 全平台支持](https://developers.googleblog.com/2019/05/Flutter-io19.html): Flutter 1.5 稳定版发布，并为我们带来了 Flutter for web - Hummingbird 以及可供嵌入式设备使用的 Flutter for Embedded。自此，也正如官方宣称的 Flutter 已经支持全平台。
- [坏消息 | 暂时无热更新](https://github.com/flutter/flutter/issues/14330): Flutter 官方开发团队宣布暂时不会开发热更新(Code Push)功能，原因如下：
  - Code Push 在 Android 和 iOS 平台上各有不同的限制
  - 出于安全方面的考虑，可能会被滥用

### 🐕 [MongoDB 宣布收购 Realm](<https://realm.io/blog/mongodb-to-acquire-realm-the-future-is-bright/>)

[@xiaofei86](https://weibo.com/xuyafei86)：MangoDB 宣布3900万美元的价格收购 Realm ，通过收购弥补了 MongoDB Mobile 在移动端的不足。 Realm 作为一款成熟的移动端数据库框架有着数十万的用户，并且在github上有着1w + 的star。

## 文章

### 🐕 [泛型语法改进第一弹 —— Opaque Result Types](https://kemchenj.github.io/2019-05-05/)

[@享耳先森](https://github.com/iblacksun)：Swift 5.1 将包含针对范型的一个重要改进 —— `Opaque Result Types`：简单来讲，用 `some` 修饰的方法返回值或属性，其具体类型在编译时就能确定，并且是由被调用方去决定。

### 🐕 [What should I learn if I want to contribute to the Swift compiler?](https://forums.swift.org/t/what-should-i-learn-if-i-want-to-contribute-to-the-swift-compiler/18144)

[@莲叔](https://weibo.com/aaaron7/)：Compiler 相关的工作一直处于鄙视链的顶端，这篇帖子的楼主在 2018 年 11 月的时候给自己定了一个看起来有点梦幻的目标：2019 年末能够参与到 Swift compiler 的开源工作中去（即便是楼主自己也认为很梦幻）。但有爱的 Swift 社区告诉楼主这并不梦幻，可以实现。首先 codafi 提出事实上在 Swift 编译器源码中的 C++ 并不是 Raw C++，而更多是 LLVM C++（LLVM C++并不是一门语言，而是 LLVM 工程规定的一系列 API和规范），是复杂，但没有那么复杂, 所以从 LLVM 代码规范是最佳的入门材料，不用被 C++ 吓到。然后 Aljandro 甚至给出了编译器各个环节如 Lexer、Parser、Sema 到 SIL，LLVM IR 分别对应在哪些编译器的源文件中实现，简直不要太良心。除此之外，还分享了自己很多在 compiler 相关的大型项目中如何挖到合适的点切入的经验。

整个帖子有不少优质的回复，都是既具备专业性，又照顾了对 compiler 技术陌生的新人，不容错过。

### 🐕 [大侦探福老师——幽灵Crash谜踪案](https://mp.weixin.qq.com/s/lmqeS6f3DSNsOJGywGsSsg)

[@邦Ben](https://weibo.com/linwenbang)：该文闲鱼技术小编描述了出现 BUG 到分析 BUG，到如何最终艰难地找到 BUG 的过程，非常值得一看。最后也得出了结论：Flutter 在用户启动辅助功能（如阅读屏幕）的情况下会出现 Crash（新版本已经 fix，同学们都升级一下。）例外这里面还提及到两个有意思的点，线上 Zombie 野指针监控和 UI 自动化重现。另外有一个很重要的点：保持和用户的良好沟通，最后直接上门现场 DEBUG，没准还可以帮妹子顺手修修电脑 >_<。

参考链接：
- [Let's Build NSZombie](https://www.mikeash.com/pyblog/friday-qa-2014-11-07-lets-build-nszombie.html)
- [The Inner Life of Zombies](https://www.mikeash.com/pyblog/friday-qa-2011-05-20-the-inner-life-of-zombies.html)

### 🐕 [LLVM 编译器中的内置 (built-in) 函数](https://juejin.im/post/5cce3955e51d453b440236ce)

[@looping](https://github.com/looping)：以 `__builtin_` 开头的函数声明或者调用其实是一些编译器内置的函数或者编译优化处理的开关，其作用类似于宏，只不过这些内置函数并不是真实的源代码，而是一段指令块，起到编译时的内联功能。本文就介绍了八个特殊的内置函数及其用法，熟练使用这些内置函数可以提升我们程序的运行性能，也可以扩展一些编程的模式技巧。

### 🐕 [What's new in RxSwift 5](https://medium.com/@freak4pc/whats-new-in-rxswift-5-f7a5c8ee48e7)

[@olddonkey](https://github.com/olddonkey)：RxSwift 5 终于和大家见面了。RxSwift 5 带来了一些不算小的变化，比如有拆分 Relay 出 RxCocoa，成为独立框架，转用 DispatchTimeInterval 以对更小时间间隔的更好支持，舍弃 Variable，新增 do(afterNext:) 以及允许绑定多个观察者等变化。对于现有的 RxSwift 开发者来说，不算是根本上的变化，但是需要在一些使用习惯和语法上进行相对应的改变。

如果对英文版不是很有信心的话，也可以看看小集团队发布的[中文翻译版](https://mp.weixin.qq.com/s/ag7z-w3J52sTxhjzibvnww)。

### 🐢 [深入iOS系统底层之映像文件操作 API 介绍](https://juejin.im/post/5c6a976ae51d451eb711a90f)

[含笑饮砒霜](https://weibo.com/chinafishnews/)：所谓的映像可以理解为将一个程序文件的内容加载到进程虚拟内存中的内容，也就是说进程的映像就是程序磁盘文件在内存中的一个副本。程序文件和映像之间的关系就如程序和进程之间的关系是一样的。那关于进程映像操作的 API 有哪些呢：

- 获取当前进程中加载的映像的数量
- 获取某个映像的 Mach-O 头部信息结构体指针
- 获取进程中某个映像的名称
- 获取某个库链接时和运行时的版本号
- 注册当前线程结束时的回调函数
- ...

相关操作的 API 有很多，在  `<mach-o/dyld.h>` 都有声明。通过相关 API 的使用，可以检测程序中某个类的某个方法是否被非法 HOOK 了。可执行程序中定义的类的实例方法的实现地址总是在可执行程序映像的地址区间范围内，即使是这个方法被可执行程序中的其他方法 HOOK 了，这个 HOOK 的方法地址仍然是在可执行程序的映像地址区间范围内，我们仍然认为这是一个合法的 HOOK 。如果这个实例方法被恶意攻击者通过动态库注入并以方法交换的形式来 HOOK 原有方法的实现时，因为HOOK 的方法地址是在恶意注入的动态库映像的地址区间范围内，所以我们就可以通过检测这个类的实例方法的实现地址是否在可执行程序的映像的地址区间范围内来判断这个方法是否被恶意 HOOK 了。

### 🐕 [百度App iOS工程化实践: EasyBox破冰之旅](https://mp.weixin.qq.com/s/Oa52PvsHw8wS-OvYb3ArZg)

[@xiaofei86](https://weibo.com/xuyafei86)：EasyBox 是手百开发的一套包管理工具集。致力于为超级 App 量身打造一套现代、高效、优雅的研发工具链。EasyBox 主体由工程组装器(Installer)、多仓库管理工具(MGit)、二进制管理工具(LFS)三部分构成，分别负责工作区的构建(组件依赖分析、工程的生成与组合)、源码仓库的管理以及二进制的管理。本文对 EasyBox 的设计进行了讲解，从中可以学到一些软件架构的思想和工程管理的经验。但并没有开放源代码。

### 🐢 [Sharing code between iOS and Android using J2ObjC](https://medium.com/ubique-innovation/sharing-code-between-ios-and-android-using-j2objc-ecd6c4c247)

[@tom](https://xiaozhuanlan.com/u/6682065345)：这是关于跨平台开发的系列文章，之前作者还有讨论[采用 C++ 来进行 iOS 和 Android 的跨平台开发](https://medium.com/ubique-innovation/sharing-code-between-ios-and-android-using-c-d5f6e361aa98?sk=308b1a500b536b94437282955ac56d2b)。关于跨平台的好处就不多说了，这篇文章主要介绍了使用 [J2ObjC](https://developers.google.com/j2objc/) 来进行跨平台开发。J2ObjC 是一个代码转换器，能够直接将 Java 代码翻译成 Objective-C 代码，从而达到跨平台开发的目的。注意的是，正如大部分的跨平台开发框架一样，一般跨平台代码只适合工作在 Model 层，在 UI 层的代码几乎无法做到一份代码共享多个平台（自带虚拟机或者语言翻译机的除外，如 RN、Flutter 等）。最后总结一下 J2ObjC 的优缺点

优点
1. 代码共享
2. 可以只用 Java 进行开发（Java 开发人员容易招，iOS 同学嘛）
3. 可以在 iOS 工程中调试 Java 代码

缺点
1. 代码翻译总是会出错的
2. 如果需要 Swift 混编的话是个灾难
3. 翻译出来代码不是最优形式，会增加包体积大小
4. 翻译的范围有限制，仅限用可支持的 JRE 类
5. 如果依赖了一些第三方库，而又与 J2ObjC 不兼容的话也是一个大问题

### 🐢 [100-Days-Of-iOS-DataStructure-Algorithm](https://github.com/renmoqiqi/100-Days-Of-iOS-DataStructure-Algorithm)

[@kyo](https://github.com/KyoLi)：算法应该是面试中大多数公司都会考察的点，虽然在日常的业务开发中可能并不常使用，但如果做一些深入的比较复杂的项目，算法就是必不可少了。可以说，如果在技术上想更深入的了解，算法和数据结构就是必须要熟悉的。在众多相关的文章中，以 C++，JAVA 等语言进行讲解的很多，很少以 OC 来讲的文章，而这个系列文章就采用 OC 为主语言，这对其他语言不太了解的同学来讲是个福音。

### 🐕 [搞事情之 Vapor 初探](https://juejin.im/post/5ccc7d3fe51d453afc760317)

[@老峰](https://github.com/GesanTung)：从 Swift 开源并支持 Linux 运行之后，Swift Server Side 趋热，先后出现了 Perfect、Vapor、Kitura 和 Zewo 几个框架，其中 Vapor 目前在 Github star 数最多。

本文是作者对 Vapor 的探索实践，分享了在 Vapor 中 MySQL 的基础使用；在 Vapor 中的用户鉴权；以及自己实践中的心得体会。

相关阅读：
[Swift HTTP Server 开发体验](http://posts.enumsblog.com/posts/18014)
[Docker ❤️ Swift & Vapor](https://theswiftdev.com/2018/11/15/docker-loves-swift-and-vapor/)

## 工具

### [SwiftKit](https://github.com/SvenTiigi/SwiftKit)

[@张嘉夫](https://github.com/josephchang10)：用命令行快速生成跨平台 Swift Framework，支持 iOS、tvOS、watchOS 和 macOS，兼容 CocoaPods、Carthage 和 Swift Package Manage，整合了 Fastlane 以便测试和发布，采用 Jazzy 来生成文档。此外还包括 README.md 模板、格式工具 SwiftLint、持续集成服务配置模板（Travis、GitLab）以及自动判断库名在 CocoaPods 上是否已被占用等等。

### [Messier - 简单易用的Objective-C方法跟踪工具](https://everettjf.github.io/2019/05/06/messier/#%E7%AC%AC%E4%B8%80%E6%AD%A5%E5%AE%89%E8%A3%85macos%E5%AE%A2%E6%88%B7%E7%AB%AF)

[@红纸](https://github.com/nianran)：Messier 可以用来跟踪 iOS 应用的 Objective-C 方法调用。在越狱设备上可以跟踪任意应用，在非越狱设备上也可用于跟踪调试中的应用或使用 Monkey Dev 植入框架的项目，仅支持 arm64 的真机。据文中作者介绍，其原理基于 Hook objc_msgSend 来实现函数记录，存储本地，使用自研工具导出文件后，使用 [catapult](https://github.com/catapult-project/catapult) 进行展示。另外调试过程中或多或少影响到了调试性能，适合查问题的时候进行植入。

## 代码

### [MaLiang - iOS 涂鸦库](https://github.com/Harley-xk/MaLiang)

[@anotheren](https://anotheren.com/)：MaLiang 是 iOS 平台基于 Metal 的涂鸦绘图框架，完全使用 Swift 实现。

目前支持的功能：
* 笔迹通过贝塞尔曲线进行平滑处理
* 支持添加自定义贴图
* 纹理和贴图支持旋转
* 内置一个荧光笔特效的实现
* 可以根据压力自动调整笔迹，支持 3D Touch
* 支持撤销和重做
* 支持滚动和缩放画布
* 导出绘制内容为图片
* 将绘制内容保存为矢量文档和从文档恢复数据

## 内推

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


