0%

背景

自己很早之前曾经写过一些CocoaPods管理Resource资源的文章:CocoaPods的资源管理和Asset Catalog优化 ,当时列举了对普通图片类型的管理方式和一些用法,也普及了一下UIImage获取Bundle去加载不在mainBundle图像的方式。

但是苹果早在iOS 9,Xcode 7时代,苹果就已经推出了Data Asset的概念,并在随后的Xcode,尤其是Xcode 10中,为Data Asset提供了App Slicing的能力(即App Store提审包会根据选择的不同设备/内存/分辨率/GPU/CPU,最终下载到唯一匹配的一份文件),这个功能渐渐地开始被一些国内开发者使用。

在NSHipster这里,有一篇专门的文章介绍:《NSDataAsset

不过,这篇文章主要的内容是,最近有同事踩到一个关于Data Asset和最低部署版本的坑,这里单独列举一下以防后人重复踩坑。

Data Asset初见

阅读全文 »

iOS端矢量图解决方案汇总(SVG篇)

简介

矢量图,指的是通过一系列数学描述,能够进行无损级别的变化和缩放的一种图像。相比于标量图(如JPEG等标量图压缩格式),能够在绘制时进行任意大小伸缩而不产生模糊,甚至能够实现动态着色,动画等等一系列交互。

intro_raster_to_vecto

在当今移动端设备尺寸越来越复杂,各种操作系统级别的夜间主题(或者Dark Mode)越来越提倡的场景下,如果依旧使用标量图,我们需要针对不同的屏幕大小(如2x,3x),和对应主题场景(Light/Dark),提供NxM数量级的标量图,对于App大小开销是很大的。因此,使用矢量图是一个非常有效的解决方案。这个系列文章,就是主要侧重讲解iOS端上的矢量图解决方案。

第一章是关于SVG及其相应衍生方案的解决方案,后续会有其他矢量图相关的PDF章节,Lottie等。他们各自有不同的细节场景区分和优缺点。

阅读全文 »

WatchKit渲染原理以及SwiftUI桥接

背景

Apple Watch作为苹果智能穿戴设备领域的重头,自从第一代发布已经经历了6次换代产品,操作系统的迭代也已经更新到了watchOS 6。

不同于iPhone的App,watchOS上的大部分App都侧重于健康管理,并且UI交互以直观,快速为基准。在2015年WWDC上,苹果发布的watchOS的同时,面向开发者发布了WatchKit,以用于构建watchOS App。

watchkit-app.jpg

这篇主要讲了关于WatchOS上的App的架构介绍,基本概念,并深入分析了WatchKit的UI渲染逻辑,也谈了一些WatchOS和SwiftUI相关的问题。

阅读全文 »

Hopper简介

Hopper,全称Hopper Disassembler,是一个macOS和Linux平台上的反汇编IDE。提供了诸如伪代码,子程序,脚本,Debugger,Hex编辑等等一些列工具。相比于其他知名的反汇编工具如IDA,最大的好处是对平台特性,也就是Objective-C的反汇编有优化,提供非常贴近原始代码的伪代码(IDA目前则会是保留诸如objc_msgSend的伪代码),并且新版本也对Swift提供了一定的反汇编符号优化,因此作为探究iOS平台上的SDK实现,可以说是一利器。

Hopper安装

Hopper本身目前是收费的软件,提供了免费的使用(30分钟)。官方下载地址为:[https://www.hopperapp.com](https://www.hopperapp.com/)。Mac版本后解压,拖到Application下即可使用。

对于个人使用,价格不菲,有两种方案,个人比较推荐第一种

  • Per User:收费为¥700,允许同一时间唯一激活,不绑定机器硬件
  • Per Computer,收费¥900,和一台电脑的机器硬件绑定
阅读全文 »

QuickLook简介

QuickLook 是macOS上提供的一项快速展示文档预览的功能,只需要按下空格就可以快速查看各种文件格式的信息,包括文本,代码,图片,音频,视频等等。

由于QuickLook需要支持不断扩展的文件格式,因此macOS专门提供了一个QuickLook Plugin,能让开发者对自己的文件格式提供一个自定义的完整的UI显示,不必依赖macOS系统更新来支持缤纷复杂的格式。

之前一段时间,出于兴趣做了一个AVIF (AV1 Image File Format)的解码器封装,AV1作为现在流行的HEVC(H.265)潜在未来竞争者,有着开源,无专利限制,更高的压缩比等等优势,比起HEVC晚诞生了5年。

目前AVIF虽然发布了第一版规范,但是缺少相应的周边工具链的支持,在macOS上想要找一个简单的Image Viewer都没找到,调试起来异常困难,因此抽空顺便做了一个简单的Quick Look Plugin,来让自己能直接空格预览AVIF图像。

在做QuickLook Plugin的过程中,感觉有一些小坑需要记下来,因此这篇文章,目标就是一个简单的入门教程,讲解如何做一个QuickLook Plugin,来对自己喜爱但又不被系统支持的文件格式,提供更好的用户体验支持。

阅读全文 »

主流图片加载库所使用的预解码究竟干了什么

很多图片库,都会有一个类似叫做Force-Decode,Decode For Display之类的感念,很多人可能对这个过程到底是为了解决什么问题不清楚,这里写一个文章来说明它。

这里列举了各个图片库各自的说法,其实讲的都是完全相同的一个概念。

  • SDWebImage:使用了forceDecode, decompressImages的概念
  • YYWebImage:使用了decodeForDisplay的概念
  • Kingfisher:使用了backgroundDecode的概念

为什么需要这个过程,解决了什么问题

为了解释这个过程具体的解决问题,需要至少了解苹果的系统解码器的工作流程。

阅读全文 »

这篇文章介绍了关于CocoaPods的资源管理行为,对于Pod库作者是必须了解的知识。同时介绍了CocoaPods使用Asset Catalog的注意事项。如果已经了解某方面知识,可以大致略过直接看结论。

Asset Catalog和App Thinning

Asset Catalog,是Xcode提供的一项图片资源管理方式。每个Asset表示一个图片资源,但是可以对应一个或者多个实际PNG图,比如可以提供@1x, @2x, @3x多张尺寸的图以适配;在macOS上,还可以通过指定日间和夜间不同Appearances的两套图片。

这种资源,在编译时会被压缩,然后在App运行时,可以通过API动态根据设备scale factor(Mac上日夜间设置)来选择对应的真实的图片渲染。

App Thinning,是苹果平台(iOS/tvOS/watchOS)上的一个用于优化App包下载资源大小的方案。在App包提交上传到App Store后,苹果后台服务器,会对不同的设备,根据设备的scale factor,重新把App包进行精简,这样不同设备从App Store下载需要的容量不同,3x设备不需要同时下载1x和2x的图。

但是,这套机制直接基于Asset Catalog,换言之,只有在Asset Catalog中引入的图片,才可以利用这套App Thinning。直接拷贝到App Bundle中的散落图片,所有设备还是都会全部下载。因此如何尽量提升Asset Catalog利用率,是一个很大的包大小优化点。

阅读全文 »

这篇教程,是系列教程的第三篇,前篇名为iOS平台图片编解码入门教程(第三方编解码篇)。由于vImage已经属于较为底层框架,这一篇将不会特别着重图片封装格式的编解码,会介绍一些Bitmap级别的操作,包括了图像的色彩转换,Alpha合成、基本几何变换等实际用法。由于教程侧重是图像格式,所以不会介绍vImage强大的Convolution等知识,这方面涉及到数字图像处理的复杂知识,不是教程的目标

基本介绍

vImage是Apple的Accelerate库的一部分,侧重于高性能的图像Bitmap级别的处理。库本身全部是C的接口,而且不同于Core系列的(Core Graphics/Core Foundation)C接口,是比较贴近传统C语言的接口,不会有XXXRef这种贴心的定义,而且很多接口需要自己手动分配内存。

vImage按照功能,可以分为Alpha Compositing(Alpha合成)、Geometry(几何变换)、Conversion(色彩转换)、Convolution(卷积,用于图像滤镜)Morphology(形态学处理)等。这里主要介绍的,就是色彩转换,Alpha合成,以及几何变换的内容。

首先需要对vImage的基本接口有所了解,有这么几个概念:

  • vImage_Buffer: 对应Bitmap的数据,只有最基本的width、height、rowBytes(stride)以及data
  • vImage_CGImageFormat: 每个vImage的功能,会提供不同色彩格式的类似接口,比如会有ARGB8888,Planar8的同样功能。这里ARGB8888指的是ARGB排列,每通道占8个Bit,也就是一个Piexel占32Bit。而vImage还有一个常见的色彩格式Plane8,指的是只有一个通道(平面),按照顺序排列,比如{R, R, R, R}这样,更方便进行计算
  • vImage_Flags: 每个vImage接口,都会有一个flags 参数来控制一些选项,比如说可以自己定义内存分配,背景色填充策略,重采样策略等,默认的是kvImageNoFlags
  • vImage_Error: 每个vImage的接口,都会返回这个result,来让用户确认是否成功,以及失败的原因,在Debug下比较有帮助
阅读全文 »