或许你有过这样的使用体验:当你看完某 App 的年度报告之后,会有一个交互按钮支持你生成视频并保存到相册。当你点击并经过一定的等待时间之后,你会发现相册里多了一段内容为自动翻页的年度报告视频。
谓之何解?照 WKWebView 且使动之为之一途。
或许你有过这样的使用体验:当你看完某 App 的年度报告之后,会有一个交互按钮支持你生成视频并保存到相册。当你点击并经过一定的等待时间之后,你会发现相册里多了一段内容为自动翻页的年度报告视频。
谓之何解?照 WKWebView 且使动之为之一途。
对于商品落地页而言,价格无疑是最重要的信息。而 IAP 商品却是在 App Store Connect 后台进行管理的,Server 是无法拿到相关信息的。一种最简单的方式是:在商品创建的同时,将商品的价格信息注册到 Server,然后 Frontend 与 Server 通信获取落地页信息。但这显然存在问题,因为它无法处理实时价格、价格国际化和折扣优惠。目前唯一的解决方式是 Native 通过 StoreKit 获取商品信息,并将其告知 Frontend。
iOS 中的列表视图:UICollectionView 和 UITableView 可以在兼顾性能的同时让开发者比较容易地搭建复杂的 App UI 界面,并且用户的交互行为也变得顺畅。如果要百尺竿头更进一步的话,我们需要按需刷新列表而不是一股脑儿地调用 reloadData。在 iOS 13 之前,我们可以通过 IndexPath 或者 IndexSection 来进行局部刷新,但却几乎总是会遇到这个崩溃:
Terminating app due to uncaught exception’NSInternalInconsistencyException’,reason: ‘Invalid update: invalid number of sections. The number of sections contained in the tableView view after the update (1) must be equal to the number of sections contained in the tableView view before the update (1), plus or minus the number of sections inserted or deleted (0 inserted, 1 deleted).
而造成崩溃本质上的原因是模型层和渲染层的数据不一致。考虑到了开发者的“民间疾苦“,在 iOS 13 之后,Apple 提供了一套新的 API 用于 Diff 数据源,还附送优雅的刷新动画,You deserve it!
在组件的编码工作完成之后,就需要将代码进行公开托管以供其他开发者使用。作为全球最大的“码农交流”平台,Github 无疑是最好的选择。借助于它的 action,可以自动化地帮助我们完成很多重复性工作,在保证代码质量的同时减轻维护工作的压力。
对于音视频资源来说,缓存行为分为两种:先下后播和边下边播。前者对于资源本身没有特殊要求,能够通过一个下载任务将数据转换为可播放的媒体文件即可。后者则需要其支持指定范围获取数据,这反应在 URL 响应表现为响应头中键为 accept-ranges 的值是 bytes。为了能描述这两种缓存行为,我们在 Part 1 中定义了 ZPCacheable
:它要求遵循者需要实现将 URL 异步转换为 AVURLAsset 的方法。如果过程中发生了错误,则通过 ZonPlayer.Error
这个类型去描述。这得益于 AVURLAsset 天然支持本地文件路径,并且对于流媒体来说如果有缓存需要,只需设置它的 AVAssetResourceLoaderDelegate 就可以接管数据的请求与响应。
在上文中,我们完成了 ZonPlayer
的需求分析和接口设计,后者的核心思想是面向协议编程。使用者不用关心播放器具体是什么类型,而是通过 ZPSettable
完成播放器的初始化设置,并且通过遵循 ZonPlayable
的返回值进行播放器行为的控制和状态的读取。如果从权责分明的设计原则来看,ZPSettable
中包含的音频会话和远程控制设置(可选)似乎有违规范。事实上,为了简化播放器上下文的环境的构建,特别是解决官方 SDK 挖下的坑,如此设计是目前能想到的无奈之举。欲知细节如何,且看下文分解!
说起播放器,在 iOS 平台上就离不开 AVPlayer。什么?你说还有 AVAudioPlayer!用不了,根本用不了一点!在流媒体横行的时代,一个“只”能播放本地音频文件的播放器已经被后浪拍死在沙滩上了。撇开跨平台和一些不常见的视频格式不谈,使用 AVPlayer 作为音视频播放器应该是优先考虑的选择。开箱 AVPlayer,你会发现基于 KVO 那一套接口使用起来真的是难受和折磨,要是还想要先下后播或者边下边播这样的缓存功能,唯有带上痛苦面具一边撸代码一边累牛满面了。好在“万能”的 github 上有不少的开源项目可供研究,但未找到一个兼具易用、支持缓存(先下后播/边下边播)、音频会话管理和后台播放控制的轮子。即然无法做伸手党了,遂决定自个儿动手从头撸一个,期望能够对开源界做一点微不足道的贡献。搞砸了还望大伙轻喷,手动狗头保命~
屈服于 Apple 的“淫威”,开发者不得不将 App 的网页容器从 UIWebView 迁移到 WKWebView。我们在享受后者带来的性能和功能提升的同时,也被诸如 Cookie 同步、截图、白屏等问题弄得抓耳挠腮、狼狈不堪。无疑,上述问题会随着系统更新被逐渐修复,而开发者在产品系统适配的硬性要求下只得各凭本身缝缝补补,以期望减少在用户侧出现的问题。如题,下文我们对 Cookie 同步的情况进行一些说明,并总结出一种可行的方案。
自 iOS 问世以来,官方从来没有提供工具让第三方开发者监控线上 App 的运行情况。特别地,如果开发者想要统计分析崩溃和卡顿,那就只能“自食其力”。而这一切从 iOS 14 开始有了转机,因为 Apple 推出的性能诊断框架 MetricKit 终于囊括异常情况的分析数据:卡顿、崩溃等的堆栈信息。“得益”于 Apple 对用户隐私的保护,它只能作为常规手段的一个补充,而非主力选手。此外,MetricKit 能捕捉到诸如 Watchdog timeout 之类的漏网之鱼,让它不至于全然如鸡肋一般,食之无味,弃之可惜。
对于 iPhone 来说,我们都常有一个使用习惯,即将屏幕自动旋转锁定,毕竟 iOS 的这个陀螺仪的方向检测有时候会出现蜜汁现象。不过这样做的话,就错过了验证各大厂 App LaunchScreen 对屏幕方向的支持情况。举个 🌰:众所周知,天猫和淘宝在 iPhone 上的实际使用中只支持横屏。但如果你把屏幕自动旋转锁定关闭,然后将你的 iPhone 横屏,会发现淘宝的 LaunchScreen 也“躺”下了,而天猫没有…… emmmmmmmm
这篇文章会梳理官方提供的几种屏幕旋转控制的方式以及它们的优先级,当然上面提到的这个问题自然就迎刃而解了。