Qnext大会 | App Slicing在携程APP上的实践

原创专栏|祁一鸣

2016年4月加入携程, 任机票研发部技术专家。毕业于美国常春藤名校Dartmouth College本科,曾先后在硅谷的Oracle, Yahoo!和Salesforce总部效力过。从scratch到delivery完成过的最成功的产品是年销售额超1亿美金的商业社区网站模板。平时喜欢吃冰激凌和甜甜圈,也蛮喜欢上海野兽派的花。

APP Slicing是苹果在2015年推出的基于iOS 9平台的新的打包功能。Slicing本身是一种对不同用户的iPhone设备生成并下发不同版本app安装包的过程。当用户在苹果应用商城下载一款APP的时候,如果这款App实现了Slicing的功能,那么用户下载的app bundle里的静态资源是对用户当前手机版本适配的。譬如,经历过Slicing的安装包里只会有适配于当前手机仅一种分辨率的图片,而不是一倍图,两倍图,甚至是三倍图片同时共存,从而优化并缩小了App安装包的大小。 这就是本次分享的主题思想。

1. iOS App安装包解析

说到一个iOS App的安装包, 首先要了解一下.ipa文件的概念。 ipa文件全名 iOS application archive,是iOS平台下所有应用可执行文件以及资源文件的打包文件。 要了解一个iOS App里的内容, 首先要去解析ipa文件。

ipa文件里的内容包括:

-- app binary可执行文件

-- Nib文件

-- db数据库文件

-- 图片文件

  • Assets.car
  • png, jpeg文件等等

-- plist属性文件

-- 其他

对于运用了Slicing功能的App, 图片资源文件会被压缩并统一储存在于ipa文件里一个名为Assets.car的特殊文件夹里。 反之, 每张图片资源文件会独立存在于ipa文件里。

2. 通过Asset Catalog处理图片实现App Slicing的想法

Xcode 5 推出了Asset Catalog,一款帮助开发者在App里管理图片资源的工具。

如上图,选中Xcode工程中的Images.xcassets文件夹,选择添加 New Image Set,为这个Image Set取个名字(譬如Oval), 再将不同分辨率的图片 (2x, 3x)拖到指定的2x和3x图片区域, 便完成了通过Asset Catalog方法添加图片的操作。以此类推, 如果每张图片都是按这样的方式添加的,那么将Xcode中的工程archive并提交到苹果应用商城之后,Slicing的过程就会自动被触发。苹果应用商城会生成不同variant版本的安装包, 用户下载的app安装包时也会根据自身的设备版本(iphone5, iphone6s plus, etc),仅储存一种适配分辨率的图片资源。譬如,通过iPhone 6s plus下载的App安装包里只有3x的图片资源, 通过iPhone 5s下载的APP安装包里只有2x的图片资源。

3. App Slicing在携程APP上的实践

说了这么多,似乎只要在App里添加图片的时候使用Asset Catalog就可以自动达到Slicing的功能了。 那本次的分享话题也就结束了。 谢谢大家。

确实,如果是新开发一款从零到一的APP,每次在工程中添加图片资源的时候只要按照上面的操作就可以实现Slicing的功能。 但是, 对于一款像携程这样多子工程多业务线团队联合开发并上线多年的APP来说,大部分的图片都不是通过Asset Catalog的方式来管理的。APP里的已有图片大多是直接存储在普通的资源文件夹里。

所以,要想用Asset Catalog来自动实现Slicing的功能,首先能想到的是手动去迁移每个业务线bundle文件夹中的图片到Asset Catalog里去。 这样的做法可以实现目标,但是需要重复手动操作,除了拖拉图片到新建的Image Set里面,还需要手动对照图片名去给Image Set取名,繁冗且容易出错。

那么有没有自动化的的方法来实现App Slicing的功能呢?

答案是有的。如上图,在Xcode里,选中Application的target,然后选中Build Phases,可以看到一个Run Script的环节。 解决方案就是在编译后期, 通过Script来模拟实现Asset Catalog的图片管理功能,打包所有的图片资源文件并生成特殊的Assets.car文件夹。

用Script来实现App Slicing

首先, 让我们来查看一下用Asset Catalog来管理的图片资源的文件结构。

上文中举过一个通过Asset Catalog添加一个Oval图片的例子。 如上图, 在Finder里打开Images.xcassets, 可以看到在Xcode里新添加的每一个Image Set里都有对应的 .imageset 文件夹。 在该文件夹里, 有着在Xcode里通过Asset Catalog添加的一张图片的不同分辨率的资源。 除此以外, 还有一个名为Contents.json的文件。

如上图,Contents.json里储存的是一些key-value pair的资源内容信息。”images”对应的是一个数组的不同分辨率的图片信息。这些信息包括:idiom – 设备家族, scale – 分辨率, filename:图片文件名。 其中,idiom信息的记录为可选。 “info”对应的是版本信息和文件作者。

要想去模拟实现Asset Catalog的图片管理方式,就要在Build Phases里用Script对于每一张图片资源去生成这样的一个文件结构以及Contents.json文件, 等同于每张图片资源是通过Asset Catalog来添加和管理的一样,如下图。

实现在了这样的Images.xcassets文件结构和内容以后,等于完成了一大半的工作量。 前文中还提到,运用了Slicing功能的APP,会在ipa文件把所有的图片资源压缩并统一储存在一个名为Assets.car的特殊文件夹里。 苹果应用商城通过对上传的ipa文件里的Assets.car检验处理,才会自动去生成并下发针对不同设备适配的不同App安装包。 所以,还剩一步就是去把Images.xcassets转化成Assets.car。

前文中提到过Assets.car不是一个普通的文件夹。 实际上, 它是Asset Catalog管理的图片资源在编译后得到的版本。要想在Run Script Phase生成Assets.car, 需要用到Command Line Tools命令行中的actool工具。

actool应该存在于/Applications/Xcode.app/Contents/Developer/usr/bin/目录下。如果发现该目录下没有actool。可以执行下图中的命令,之后会弹出一个对话框,点击安装即可。

在有了actool之后,编译Images.xcassets从而生成Assets.car就只需要执行一条命令。

如上图,有两点要说明。 需要把${wdir}替换成编译过程中Images.xcassets的父文件夹地址,而--minimum-deployment-target需要填7.1或者以上。将这条命令执行好以后, ${wdir}目录下便会有全新的Assets.car生成。

综上所述,在Build Phases的Run Script环节用Script去实现模实现Asset Catalog图片管理方式并生成Assets.car文件以后,APP Slicing的功能就基本实现了。

如上图, 在iOS application archive打包完成之后,开发者可以通过核实针对各个iOS设备生成的ipa包的大小,来验证App Slicing带来的效果。 记住一点,拥有Slicing功能的App在发布到苹果商城供用户下载时, 不同iOS设备下载的安装包都是经过优化的。Assets.car里面的不同分辨率的同一张图会适配到不同的iOS设备的安装包中,以此实现缩小app size的功能。

4. App Slicing过程中碰到的问题和注意点

App Slicing是基于Asset Catalog管理图片功能之上的。Asset Catalog管理的图片的读取方式是 [UIImage imageNamed:@"imageName"]。 然而,iOS工程中普遍存在的另一种图片的读取方式是[UIImage imageWithContentsOfFile:@"imagePath"], Asset Catalog管理的图片是无法通过imagePath图片路径来读取的。 所以对于这种场景, 需要去有意识地选择是否使用Asset Catalog, 毕竟两种图片的读取方式对于在内存的占用影响都不同。

除此以外,对于Script的维护也会成为日常的工作。新增图片和已有图片的迁移改动,都可能会需要去对Script做修改。

最后,上文也提到过App Slicing是iOS 9新推出的功能, 它仅对iOS系统是9.0.2及以上版本设备有效。

5. 参考资源

  • Reducing the size of my App

https://developer.apple.com/library/content/qa/qa1795/_index.html

  • iOS App Thinning

https://developer.apple.com/library/content/documentation/IDEs/Conceptual/AppDistributionGuide/AppThinning/AppThinning.html

  • actool man page

https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/actool.1.html

本文分享自微信公众号 - 携程技术中心(ctriptech)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-11-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏JadePeng的技术博客

weex官方demo weex-hackernews代码解读(上)

一、介绍 weex 是阿里出品的一个类似RN的框架,可以使用前端技术来开发移动应用,实现一份代码支持H5,IOS和Android。最新版本的weex已默认将v...

37650
来自专栏AI科技评论

学界 | 全景照片不怕歪!Facebook 用神经网络矫正扭曲的地平线

AI科技评论按:最近微博上的全景照片很火呀,相比各位都已经在自己的iPhone或者iPad上品鉴了多家IT公司的办公室、游玩了多个旅游胜地、享受了被小猫小狗环绕...

41270
来自专栏腾讯研究院的专栏

可穿戴技术攻坚战:将心跳变成现金

等到苹果明年春季发布Apple Watch之时,全球将无人不想知道这款让众人期待已久的可穿戴设备到底具备何种功能,佩戴的感觉如何,以及其所代表的含义。不过,关...

36090
来自专栏美团技术团队

Shield:支撑美团点评品类最丰富业务的移动端模块化框架开源了

引言 一直以来,如何能更高效地开发与维护页面是Android与iOS开发同学最主要的工作和最关心的问题。随着业务的不断发展,根据特定业务场景产生的定制化需求变得...

52190
来自专栏程序员互动联盟

如何入门移动端app开发

随着互联网时代的到来,安卓和苹果的火热,移动端app的需求越来越多。这就催生了越来越多的开发人员加入移动端app开发的队伍中。目前移动端主要被三大操作系统占据着...

50050
来自专栏人工智能LeadAI

OpenCV人脸识别之三:识别自己的脸

本系列人脸识别文章用的是opencv2,最新版的opencv3.2的代码请参考文章: OpenCV之识别自己的脸——C++源码放送(请在上一篇文章末尾查看) ...

58640
来自专栏美团技术团队

关于刘海打理这种事儿,美团点评的iOS工程师早就有经验了,不信你看!

背景 iPhone X 刘海机于9月13日发布,给科技小春晚带来一波高潮。作为开发人员却多出来一份忧虑,iPhone X 怎么适配?我们 App 的脑袋会不会也...

40370
来自专栏美团技术团队

Hyperloop,让发布简洁高效

Hyperloop 是什么? Hyperloop 是服务于美团点评客户端的组件发版、持续集成、App 打包构建、资源调度等各个环节的发布调度系统。名称起源于美国...

43370

方舟的移动钱包即将推出

在过去的几周里,Ark一直在缓慢而稳定的上涨。Ark似乎因市场整体上涨而推高。

48270
来自专栏新智元

揭秘《星球大战》机器人BB-8技术原理,跑这么萌是有原因的

这应该是影视史上最受关注的非人类角色之一了。 没错,就是那个正在美国热映的《星球大战:原力觉醒》中的机器人BB-8。从去年10月官方放出的首支预告片开始,结构奇...

31340

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励