# 老司机 iOS 周报 #198 | 2022-04-11

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

## 新闻

### [Call to Code](https://developer.apple.com/wwdc22/)

苹果将在今年 6 月 6 日举办一年一度的 WWDC 全球开发者大会，今年的大会主题是「Call to Code（召唤编码侠）」，依旧采用在线形式举行，会给大家带来各种最新技术的展示。今年，老司机依旧会牵头组织 「WWDC 内参」活动，想参与的可以添加 iTDriverr 了解细节。

### [“阅读器”app 分发的更新](https://developer.apple.com/cn/news/?id=grjqafts)

去年，Apple 宣布了 2022 年初在 App Store 上将进行的更新，该更新将允许“阅读器”app 的开发者在 app 中提供一个指向其网站的链接，以便用户创建或管理帐户。从今天开始，《App Store 审核指南》中的准则 3.1.3(a) 将会更新，阐明阅读器 app 的开发者现在可以申请外部链接的帐户授权。此授权将允许阅读器 app 链接到开发者拥有或维护的网站，以便用户在 app 外创建或管理其帐户。阅读器 app 指的是提供以下一种或多种数字内容类型 — 杂志、报纸、图书、音频、音乐或视频 — 作为其主要功能的 app。

##  Developer - 设计开发加速器

### [降低 App 的卡顿率](https://developer.apple.com/cn/accelerator/)

2022 年 4 月 12 日（报名截止 4 月 11 日）

App 性能留给用户的第一印象往往难以改变。本讲座详细讲解导致 app 卡顿的一些反面典型，和避免这些卡顿的最佳实践。讲座重点讨论 Grand Central Dispatch 多线程技术，以便减少卡顿。并指导开发者适时采用异步编程，以便提高性能。

![156925166-f0e9ae02-0d06-4806-aa19-e84d84e2fd1f](https://user-images.githubusercontent.com/11873526/162620205-0cddfae9-05e0-4e10-9359-4d914e3ae08b.jpeg)

## 新手推荐

### 🐎 [Introduction to Xcode Frame Debug - A Sherlock Holmes Adventure](https://holyswift.app/introduction-to-xcode-frame-debug-a-sherlock-holmes-adventure)

[@Smallfly](https://github.com/iostalks)：在 iOS 开发过程中经常要和 View 打交道，难免会遇到 View 显示异常的问题。本文从 Xcode Debug View 工具入手，介绍了几种调试 View 不显示的线索，主要包括：

* 检查 View 是否在父视图上
* 检查 alpha 属性
* 检查 hidden 属性
* 检查 frame 是否超出父视图

这几种方式都比较常规。最后还介绍了一个小技巧，设置 `clipsToBounds = true` 的父视图，通过 *Show Clipped Content* 能显示被裁切的子视图。

## 文章

### 🌟 🐢 [干货 | Flutter在携程复杂业务的高性能之旅](https://mp.weixin.qq.com/s/QgPXNpdU2mlAb6tlcsm_eQ)

[@CrazyCoderShi](https://github.com/CrazyCoderShi): Flutter 在渲染性能上一直都是其宣传的亮点，然而即使这样在业务开发中仍然有较多需要注意的地方，本文由携程团队给大家带来的 Flutter 下复杂场景的性能优化，涉及方方面面，干货满满，所有优化项所见所得:

- UI 线程优化
  - 拆分VieModel降低刷新几率
  - Provider监听数据推荐使用Selector
  - 减少在build中做耗时操作，放到Isolate去执行
  - 缓存高层级组件
  - 控制刷新范围、频次
  - setState 刷新颗粒度在最低层
  - const 修饰避免频繁构造

- GPU 线程优化
  - 使用RepaintBinary隔离 提别是轮播广告、动画
  - 减少ClipPath的使用,简单圆角采用BoxDecoration实现
  - 避免Opacity,可以通过切图实现。有动画效果的建议用AnimatedOpacity
  - 避免使用带换行符的长文本

- 图片渲染性能和内存开销治理
  - 图片预加载
  - 资源优化
  - 图片内存优化

- 长列表滑动性能优化
  - ListView Item 复用
  - 首页预加载
  - 分页预加载
  - 取消在途网络请求

小编强烈推荐 👍 ，同时再次推荐携程团队的[另一个干货: Flutter控件CustomScrollView原理解析及应用实践](https://mp.weixin.qq.com/s/dF5Id3w_To4aXeXDbUnUjQ)给同学们搭配学习

### 🐕 [Airbnb’s Page Performance Score on iOS | by Nicholas Miller | The Airbnb Tech Blog | Medium](https://medium.com/airbnb-engineering/airbnbs-page-performance-score-on-ios-36d5f200bc73)

[@Barney](https://github.com/BarneyZhaoooo)：本文是 Airbnb PPS 的第二部分，介绍了 PPS 在 iOS 端的具体实践应用，并配有重点代码思路分析，时间锚点的选取和状态机的丝滑运用让人眼前一亮。

- Page System
- PPSStateMachine
- Time
- View Association
- Metric Implementation

### 🐕 [FormatStyle AttributedString Output](https://ampersandsoftworks.com/posts/formatstyle/style-deep-dives/attributed-strings/)

[@anotheren](https://github.com/anotheren): AttributedString 是 iOS 15 引入的全新富文本对象，同时也引入了 FormatStyle 协议来抽象格式化的方式。本文提供了大量实例（Playground）来展示如何使用这些内置的 API 来格式化日期、单位、数据等对象。

### 🐕 [iOS 15.4 12小时制 时间格式转换崩溃 - 掘金](https://juejin.cn/post/7077493937383948295)

[@Barney](https://github.com/BarneyZhaoooo) ：本文介绍了一个在iOS15.4系统由于时间转换造成的崩溃。时间转换是大家平时开发经常用到的，值得引起注意防患于未然。

- 系统解析对比
- 理论原因定位

### 🐕 [Flutter 代码生成 source_gen 使用与原理分析](https://mp.weixin.qq.com/s/lrEzYdbafrqfDVFQl2ebRQ)

[@邦Ben](https://weibo.com/linwenbang)：众所周知，你应该多少会用过 json_serializable 吧，那么就一定知道基本的原理是通过解析声明文件，从而生成相关 json 序列化和反序列化代码。那么当你从事过较多的开发之后，一定会遇到很多重复的代码复制粘贴，例如：路由的编写，或者 channel 的生成，架构代码生成，ImageAsset 代码生成等等。那么你应该会自然地想到，我也可以像 json_serializable 和 pigeon 去做一些提高效率的工具，那这时候可以看下 source_gen，这个库进行了一些封装，让你更方便的定制代码生成的逻辑。

参考链接：
[Flutter使用source_gen快速提升开发效率](https://mp.weixin.qq.com/s/kwgI1FsEo5BGE7bRqKM7Mw)

### 🐢 [Flutter 滑动体验对齐原生 - 滑动曲线篇](https://mp.weixin.qq.com/s/aqXdYYEArhEj6ikqg2oX9g)

[@ChengzhiHuang](https://github.com/ChengzhiHuang)：本文介绍了在 Flutter 的滑动手感拉齐 Native 方向上做出的努力。主要思路分为两步：解决 fling 动画在一次滑动中反复重启；选择更合适的衰减公式。同时介绍了调整滑动曲线的一些常用思路：降低初速度给曲线减速；通过对初始速度叠加衰减值，运用二次函数，在快速滑动时衰减慢，慢速滑动时衰减快。

### 🐕 Optimization in Swift

作者以 filter 为例，带着我们进行一次算法性能优化，包括算法性能的测算，结果的分析以及后续针对性的优化：

1. [如何测量算法性能](https://trycombine.com/posts/swift-performance-concurrency-1/)
2. [使用 Concurrency 算法](https://trycombine.com/posts/swift-performance-concurrency-2/)
3. [内存预分配](https://trycombine.com/posts/swift-performance-concurrency-3/)
4. [总结](https://trycombine.com/posts/swift-performance-concurrency-4/)

### 🐕 [Swift 生成原生二维码](https://digitalbunker.dev/native-barcode-qr-code-generation-in-swift/)

[@AidenRao](https://weibo.com/AidenRao)：如果你需要生成一个二维码或者条码，无需去寻找第三方库，直接用 swift 原生代码就可以实现。iOS 自带的 CIFilter 支持二维码、[Aztec 码](https://zh.wikipedia.org/wiki/Aztec%E7%A0%81)、[Code 128](https://en.wikipedia.org/wiki/Code_128) 以及 [PDF417 条码](https://zh.wikipedia.org/wiki/PDF417%E6%9D%A1%E7%A0%81)，文章还提供了每一个条码的示例代码作为实现参考。

### 🐎 [Weak self, a story about memory management and closure in Swift](https://benoitpasquier.com/weak-self-story-memory-management-closure-swift/)

[@kemchenj](https://kemchenj.github.io/)：在 Swift 里我们经常需要使用 weak 和 unowned 来解决循环引用的问题。

只使用一个闭包的时候，引用的逻辑关系很简单明了，但闭包嵌套的时候，即使使用了 weak 也有可能会不小心产生循环引用，这篇文章就针对这种情况进行了仔细的说明，并且提供对应的解决方案。

### [Swift.org Website is Now Open Source](https://www.swift.org/blog/website-open-source/)

Swift.org 网站一直以来为广大开发者提供 Swift 相关的开源库、工具、文章等，现如今，其官方宣布 Swift.org 网站本身也成为了一个开源项目！这为广大 Swift 粉丝提供了一个很好的学习平台，快去看看吧！

### 🐎 [Consistent Swift style in Xcode with SwiftLint](https://swdevnotes.com/swift/2022/consistent-swift-style-in-xcode-with-swiftlint/)

[@老峰](https://github.com/gesantung)：SwiftLint 是 Realm 推出的一款 Swift 代码规范检查工具，本文较详细的的介绍了 SwiftLint 的使用，包括：
- 将 SwiftLint 与 Xcode 集成
- SwiftLint 规则
- 自动修复&手动修复 SwiftLint 违规代码
- 自定义 SwiftLint 规则

### 🐕 [理解 Swift 中的指针](https://mp.weixin.qq.com/s/4O5RZCiR9-kUOHJ5SdE9jg)

[@AidenRao](https://weibo.com/AidenRao)：Swift中的指针分为两类

1. typed pointer： 指定数据类型指针，即 UnsafePointer\<T>。
2. raw pointer： 未指定数据类型的指针（原生指针） ，即 UnsafeRawPointer。

每一类又分可变不可变，pointer（单个值） 与 bufferPointer（相同类型集合）。

文章通过示例代码，详细介绍了这些指针的使用方式。

### 🌟 🐕 [短视频编辑中的AVFoundation框架](https://juejin.cn/post/7077870149239308324)

[@JonyFang](https://github.com/JonyFang): 本系列文章围绕 iOS 平台上短视频编辑功能中 AVFoundation 扮演的角色展开讨论，本篇主要介绍学习 AVFoundation 框架需要了解的基础模块和相关的数据类型及注意事项。本系列文章分三篇，依次为：

- [01.框架概述与基础](https://juejin.cn/post/7077870149239308324)
- [02.素材添加与处理](https://juejin.cn/post/7077875029161017380)
- [03.视频编辑与导出](https://juejin.cn/post/7079397452192841735)

### 🌟 🐕 [音视频工程示例专栏](https://mp.weixin.qq.com/mp/appmsgalbum?)

- 第六篇 iOS 音频渲染: [从 MP4 中解封装解码出音频并渲染播放](https://mp.weixin.qq.com/s/xrt277Ia1OFP_XtwK1qlQg)
- [iOS 音频处理框架及重点 API 合集](https://mp.weixin.qq.com/s/w_5pZoeV0GdcFppIpuvVcw)

[@JonyFang](https://github.com/JonyFang): 第六篇 Demo，主要是实现对 MP4 文件中音频部分的解封装和解码逻辑，并将解封装、解码后的数据送给渲染模块播放；最后在前面音频处理 Demo 的基础上，对 iOS 音频处理框架及重点 API 的梳理。


## 工具

###  [Hot Reloading in Swift](https://merowing.info/2022/04/hot-reloading-in-swift/)

[@zvving](https://github.com/zvving)：Xcode 通过 Previews 提供快速预览 SwiftUI 代码修改的方案，虽几经迭代，稳定性一直被人诟病；而通过 [InjectionIII](https://github.com/johnno1962/InjectionIII) 同样可以达到实时预览（Live Reload）代码修改的效果，但注入代码非常冗余。通过作者提供的 [Inject](https://github.com/krzysztofzablocki/Inject) 可以大幅简化注入代码（依旧需要配合 InjectionIII 工作）。

需要经常调试预览 SwiftUI、UIKit 的朋友不要错过，建议先通过 [Example 项目](https://github.com/MarcoEidinger/InjectSwiftUIExample) 上手配置过程。


## 代码

### 🌟 🐕 [fatbobman/SwiftUIOverlayContainer](https://github.com/fatbobman/SwiftUIOverlayContainer)

[@JonyFang](https://github.com/JonyFang): SwiftUI Overlay Container 是一个用于 SwiftUI 的视图容器组件，可定制、高效、便捷的视图管理器。通过文档的配置，即可完成从视图组织、队列处理、转场、动画、交互到显示样式配置等基础工作。

## WWDC21 内参

### [初见 TextKit 2](https://mp.weixin.qq.com/s/vZ74jNgItabOB-TsaQn6Uw)

[@Damien](https://github.com/ZengyiMa): 通过本文你将会了解到 TextKit 1 到 TextKit 2 的变化内容，并且可以深入了解 TextKit 2 的内部的工作原理和机制。

### [IAP 用户退款与客诉处理优化](https://mp.weixin.qq.com/s/MtytymgkcP3_oAH7JyI1og)

[@SeaHub](https://github.com/SeaHub): 众所周知，IAP 客诉处理一直是一个"老大难"问题。用户在反馈 IAP 问题时，往往只提供其支付后获得的苹果订单。而由于苹果设计原因，开发者无法根据苹果订单反查出业务订单信息，继而无法较好的处理用户反馈的客诉问题，导致支付用户可能因体验不佳而流失。除此之外，恶意退款也是另外一个 IAP 工程师必经的"老大难"问题，无法有效索回商品，导致造成业务出现坏账的情况比比皆是

WWDC 2021，苹果为了优化客诉处理，同时为了打击恶意退款，提供了不少新能力。通过阅读本文，读者可以快速掌握部分 IAP 场景的痛点，以及如何基于新特性优化这部分的痛点

### [IAP 后台通信优化与实践](https://mp.weixin.qq.com/s/dWsRKRJsYMRl0GX_36T-kg)

[@SeaHub](https://github.com/SeaHub): 长期以来，苹果仅为 IAP 提供了 /verifyReceipt 这一个用于校验票据的后台接口。这也导致了该接口被全球众多开发者所依赖，基本上这个接口一旦出现问题，依赖后台票据校验的 App 都会出现因无法校验票据有效性而出现发货延迟问题。令人糟心的是，/verifyReceipt 接口目前表现确实不太稳定，一年总会出现两三次的服务不可用的情况；而日常其请求时耗也极高，业务的 IAP 后台处理时耗严重受该接口影响

终于在今年，苹果新增了  Subscription Status API & In-App Purchase History API，同时，也诞生了可自校验的 JWS 形式票据。并且苹果还对备受开发者吐槽的后台通知进行了升级，新增 App Store Server Notification V2。

在我看来，类似的举措一方面是为了给 /verifyReceipt 降负，另一方面也是为了丰富 IAP 的场景，给开发者提供更好的服务。通过阅读本文，读者可以快速掌握本次 WWDC21 的新特性，以及能够基于新特性对历史遗留的痛点做相应的优化处理

## 摸鱼周报

[@摸鱼周报 #49](https://mp.weixin.qq.com/s/6GvVh8_CJmsm1dp-CfIRvw)：第四十九期摸鱼周报来了，一起来看下本期概要：

* 话题：Chrome 100 发布，关于阅读器类的 App 审核指南有所更新
* 面试模块：Runtime 中的 **StripeMap<T>** 模板类
* 优秀博客：Swift 5.6 和 Xcode 13.3 的新特性和新功能
* 学习资料：即时设计是一款可以在线实时协作的专业 UI 设计工具
* 开发工具：Decode，将 `Xcode Interface Builder` 文件（`Xib` 和 `Storyboard` 文件）转换为 `Swift` 源代码。

## 内推

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

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

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

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

## 关注我们

我们是「老司机技术周报」，一个持续追求精品 iOS 内容的技术公众号，欢迎关注。

**关注有礼，关注【老司机技术周报】，回复「2021」，领取 2017/2018/2019/2020 内参**

![](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）
