Skip to content

老司机 iOS 周报 #34 | 2018-09-03

Compare
Choose a tag to compare
@kemchenj kemchenj released this 22 Dec 09:51
· 5574 commits to master since this release

ios-weekly
为了提高大家分享高质量的文章给我们的积极性,我们做出了一点小改变。如果文章是读者推荐给我们的,我们会在文章的点评后面声明推荐人,可以带一条推荐人的链接(博客,微博都可以)。具体了解可以看这里:对提高读者反馈技术文章热情的一点尝试。欢迎大家到 Issues 里多多推荐有价值的信息、文章、工具等可以提给我们。

新闻

iPhone 8 主板更换计划

Apple 已经确定,极少数 iPhone 8 设备的主板存在制造缺陷。受影响的设备可能会出现意外重新启动、屏幕死机或无法开机。Apple 将会免费维修符合条件的设备。受影响的设备是在 2017 年 9 月至 2018 年 3 月期间售出,销售范围覆盖澳大利亚、中国内地、香港特别行政区、印度、日本、澳门特别行政区、新西兰和美国。可以去本篇链接进行序列号查询,从而判断你的 iPhone 8 是否在更换计划范围内。

文章

🐕 [译] 在 Codable 中实践类型推断

类型推断是 Swift 类型安全的一个强大特性。本文介绍了利用类型推断来优化 Codable API。看完文章后对类型推断的运用场景会有更好的理解。

🐢 手把手教你查看和分析 iOS 的 crash 崩溃异常

我们开发的 App 不可避免会出现闪退,可以通过集成一些第三方的闪退收集系统或 iTunesConnect 自身来收集闪退日志。有了闪退日志之后,并不是所有闪退都能快速的定位解决,特别是没有明确上下文或者没有一个函数或者方法能够被直接定位到源代码的场景,本文介绍面对这类闪退的几种可行办法,特别是通过寄存器及汇编代码来定位问题。

🐢 🚧 🌟 Why Monads?

了解过函数式编程的同学多多少少应该都听说过 Monad 这个异常鬼畜概念,似乎从来没有一篇文章能用人话把这个概念说明白,比如学理论的同学会说 Monad 是自函子范畴上的幺半群,Haskell 程序员同学会说如果我们能为一个 type 定义 bind 和 return,那这个 type 就是一个 Monad,而 Swift 程序员一般则认为能被 flatMap 的类就是一个 Monad。那叫一个热闹。其实都不能算错,毕竟每个语言的表现能力不同。

本篇文章尝试从 monoid 开始,使用 Swift 的语言来更严谨的介绍什么是 Monad 以及我们为什么会需要他,写得非常棒。既最大限度的还原了学术层面的定义,但又切实的使用 Swift 来实现并结合了实际的例子,是不可多得的好文,适合对函数式编程有兴趣的同学研究阅读。

文章还有一大亮点就是,一针见血指出了函数式编程普及的最大难点:如果使用 inductive 的方式,从简单的实践出发来学习函数式编程,会发现其实有很多替代方案,很容易质疑 FP 的意义,而另一方面,deductive 的方式,也就是从理论出发落地到实践,却又面临比较陡峭的理论学习曲线。作者深信学好 FP,live with them, 对一个人的编程思路和方法会有极大的增益,所以在尝试中和理论和实践的方式来做 Monad 的介绍,从这篇文章上看他也的确做到了,真心为 Swift 能有这样的开发者高兴。

从本文的专业程度、对理论的还原程度以及对 Swift 语言特性的挖掘这些方面来看,基本可以标志着 Swift 进入主流函数式编程语言的阵营,未来和 Scala,Haskell,OCaml 等竞品同台飙戏的日子指日可待。最后就摘选一句作者原文中的句子作为结尾:I hope I was able to shed some light on why, once upon a time, someone even considered applying mathematical concepts like monads to programming, and on why these structure are useful in solving practical programming problems: now it’s up to the reader to consider taking this leap.

🐢 🌟 Google Swift Style Guide 浓缩版

谷歌版的 Swift Style Guide 是现在公开的 guide 里实用价值最高的一篇。每一个使用 Swift 的开发者看完应该都会有所收获。于此同时我也翻译了官方 Swift API 设计规范,对规范感兴趣的朋友也可以一起阅读。

🐕 Improving Your Build Time in Xcode 10

今年 WWDC 上 Session 408 的主题是 Xcode 中如何提升编译速度,视频链接在此。强烈建议在实际项目中忍受缓慢的编译速度之苦的同学们花费一点时间看一下。

而这篇文章总结了 Session 408 ,对于没有时间好好过一遍视频的同学来说,是个不错的学习资料。

🐢 Dynamic Features in Swift

在大家印象中,Swift 一直是以静态语言、类型安全、编译器检查等特点而为人所熟知的,事实上也正是因为这些 OC 无法实现的优点,苹果才会愿意在 OC 之外另起一门新的语言并大力推广。但是这不代表 Swift 只能是静态的,只要有简洁的语法和尽可能安全的调用方式,Swift 也能拥有一些动态特性。作为 iOS 工程师们的老朋友,Raywenderlich 的这篇文章分别介绍了 Swift 中的一些动态特性,包括 Mirror、KeyPath 和 KVO,甚至还有 Swift 4.2 中的新特性 @dynamicMemberLookup,使开发者们在享受 Swift 类型安全的同时,能有更多的选择去完成一些更灵活的需求。

🐢 在 ARKit 中创建一个时空门 App

本文译自 Ray Wenderlich《ARKit by Tutorials》一书免费发布的 7、8、9 三个章节,向你展示了如何利用 ARKit 构建一个沉浸式的时空门 app。时空门 app 是指在现实世界的地面上放置一个通往另一个房间的虚拟门,可以走进走出这个房间,探索其中的内容。

本文由译者史前图腾推荐。

🐎 iOS 的高性能、高实时性 key-value 持久化组件

FastKV 是本文作者参考微信团队的 MMKV 实现的一个 key-value 组件。底层同样使用的是 mmap,上层数据序列化为了不依赖 protobuf 自己实现了一套。mmap 纯读写性能的确要比 NSUserDefaults 高,但是 mmap 也有它的局限性,它需要整数倍的物理页大小(page_size),并且也需要连续的内存区域,同时还需要自己实现映射关系、维护数据结构和异常处理。这相当于提高性能的额外成本,如同作者本人在文末说的 “如果对实时性要求不高的项目,建议还是使用官方的 NSUserDefaults”。有兴趣的同学可以跟作者一起维护这个组件,或者自己动手学习和实现一个类似的 key-vale 组件。

🐢 Life of a Pixel 2018

Steve Kobes 做的 Life of pixels 2018,讲了如何从一个 HTML 文件到屏幕上显示。前端或者对排版有兴趣的同学推荐看一下。从 Dom 到 Display,这中间是一个很复杂的过程。解析、排版、渲染,每一个环节下的结构设计、与 GPU 的协同工作等分享中都有提到。这可以让我们对 Chromium 的页面展示有一个大体的了解,有视屏不用读文字,看起来也会比较轻松一些。分享用到的 PPT 的连接

🐎 When You Refactor, Are You Using Small Steps ?

文中提出重构采取较小步骤原则( Take smaller steps ),作者贴出了他将占位符文本的从 ViewController 转移到 ViewModel 的例子来讲述整个最小步骤重构过程。并提出一个非常好结论:真正的重构是逐步进行的,并且每个步骤都通过单元测试进行验证。相信文本对你在重构的认识上会有所帮助。

🐎 闲聊 Flutter

跨平台一直是大家前赴后继不断追求的目标,原本 web 作为跨平台的解决方案很完美,但历史代码的兼容、CSS 过于复杂、DOM 接口粒度大等问题,造成 Web 技术下的跨平台方案有较明显的性能问题。而 Flutter 基于一个精简版的 web 引擎,抛弃兼容性,只保留主要功能,性能较前者快了不少。虽然 Flutter 还有包大小、缺乏动态性等问题,但一个完整的比 webkit 简单的多的引擎,源码很值得挖掘学习。

🐕 Enum iterations in Swift 4.2

Swift 4.2 为我们带来了全新 CaseIterable 协议,让我们可以快速地取到一个 Enum 中所有的 case。比 Codable 更方便的是,你可以直接扩展已存在的 Enum。文中的 Enum maps 一节为我们展现了很有趣的 CaseIterable 的用法,很快你也会爱上这个新协议的。

🐢 dyld_link & loaddyld_startup 解析

这两篇文章系统、全面地从源码级别探索 dyld 装载、链接、自举等工程。文章针对原本过程进行过滤,抓大放小,简单、明了地把原理阐述出来,并把简化后的伪代码贴出,可读性非常高。

本篇收录由该文作者 @mrriddler 自荐。

🐕 TCP 没那么难吧?

本文详细讲述了TCP 的握手和挥手流程,帮助大家更好地理解并掌握可靠性高的网络协议设计流程

  1. TCP 建立连接本身其实需要4次过程(客户端请求,服务器确认,服务器请求,客户端确认),在合并了第2、3步以后,就变成了我们现在熟知的3步走流程
  2. TCP 状态机将能帮助我们更好地了解,在建立连接过程中的各种异常状态流转过程,通过状态机模型能够很直观地表达复杂流程的各种细节
  3. TCP 终止连接显然也是需要4次流程(客户端终止,服务器确认,服务器终止,服务器确认),然而在这个流程下,第2、3步并不能合并

最后推荐两本书《Wireshark网络分析就这么简单》《Wireshark网络分析的艺术》。书的作者借助 Wireshark 这个“神器”,深入开发中的各种疑难杂症,剥茧抽丝,娓娓道来,是了解计算机网络编程非常好的参考书。

🐎 NSDataAsset

我们经常使用 Asset 来保存 @2x@3x 的图片资源,这样可以利用 app thinning,在不同的设备上之后打包进对应的资源文件。从 iOS 9 开始,Asset 不仅支持图片资源,也支持 data 格式。本文演示了如何使用 NSDataAsset。

🐎 Xcode 10 Storyboard Changes

Xcode 10 快要发布正式版本了,所以有必要了解一下新的改动。这篇文章没有列举所有的改动,主要列举了 Interface Builder 界面的一些改动,具体如下:

  • 浮动的 Library, 控件和资源的窗口不再依附在右下角,而是变成了一个浮动的窗口。
  • 多功能的 Embed in 按钮,主要是替代原来的 stackview 的按钮,同时也新增了 Embed ViewControllers 的功能

当然,Xcode 10 还有很多其他的更新的改动,感兴趣的可以看一下 What’s New in Xcode

🐕 Objective-C: 写一份可测试的代码

本文介绍了如何编写一份可测试的代码。主要阐述了依赖注入,最小知识原则在编写可测试性代码中扮演的角色,如何运用好它们来写出可读性和可测试性并存的代码。

🐕 UI 自动化测试:通过 Appium 加速你的客户端 UI 测试

这篇文章介绍了如何使用 Appium 编写一个完整的 UI 测试用例,Appium 是一个开源的 UI 测试框架,通过给外部暴露出一套完整的 REST API 去完成测试操作,支持 iOS 和 Android,使用 Appium 编写测试时有多种语言可以选择,例如 Ruby,Python 等等。

工具

Mermaid,一个生成结构图的工具

文章介绍了一个名叫 Mermaid 的软件,可以直接通过一定的语法来书写流程图的架构,简直是为程序员量身打造,目前支持流程图、序列图和甘特图(想起了手画流程图的那些蛋疼的日子)。不仅如此,Mermaid 还支持直接和 Gitbook 集成,而且因为本身 Mermaid 是以 SVG 文件输出的,所以和其他的 Web 场景也可以很好地兼容。

软件是好软件,不过这篇介绍文章有点过于简单,建议大家直接去官方地址查看学习。

代码

基于 ARKit 的 iOS 无限屏实现,还原锤子发布会效果

作者通过在越狱环境下修改 SpringBoard.app,并通过 ARKit 的惯导算法来获取手机的相对位移,然后渲染一个远大于手机屏幕的虚拟空间,从而实现了 iOS 桌面的无限屏模式,使得在视口发生位移时,产生在无限屏上游历的效果。即使没有越狱环境也没有关系,本文也适用于修改自己的 app,比如实现一个可以左右、上下翻阅的地图、PDF 阅读器等。

《iOS 面试之道》电子版

纸质书上线一个多月以来颇受欢迎,现在电子版正式开始发售,目前五折。喜爱电子版的朋友现在是入手最佳时机。

内推

关注我们

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

同时也支持了 RSS 订阅:https://github.com/SwiftOldDriver/iOS-Weekly/releases.atom

本期编辑

@没故事的卓同学@四娘@享耳先森@Damonwong@折腾范儿_味精@张嘉夫@AidenRao@Parsifal@aaaron7@方秋枋kyotom510230anotheren水水looping@JasonYuh@老老老老老老老驴

说明

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

预计阅读时间:🐎 很快就能读完(1 - 10 mins);🐕 中等 (10 - 20 mins);🐢 慢(20+ mins)