2019独角兽企业重金招聘Python工程师标准>>>

戴维营教育翻译:感谢Davis Allie的An Introduction to On-Demand Resources on iOS and tvOS

介绍

与iOS 9和watchOS 2一起,苹果引入了一套新的内容分发API,以便节约设备空间,这就是按需加载资源。通过使用按需加载资源,我们可以将特定的应用程序资源托管在苹果的服务器上,然后在需要的时候进行加载。在这个教程中,我将通过开发一个图片查看应用介绍一下按需加载资源的基本用法。

准备工作

这个教程需要使用Xcode 7+并且熟悉iOS开发。可以到Github上下载初始项目。

1. 按需加载资源

益处

iOS 9和watchOS 2引入按需加载资源的主要目的是减少单个应用程序所占的空间。另外一个好处是我们的应用程序能够更快的被用户下载下来并且启动。

通过使用Xcode中的asset pack所唯一分配的tags来获取按需加载资源。这些资源包可用包含任何asset中的内容(图片、SpriteKit纹理、数据等),甚至其它文件如OpenGL和Metal的着色器、SpriteKit和SceneKit的场景文件以及粒子系统。

当我们将应用提交到App Store时,这些资源也会被上传和托管,以便需要的时候下载。程序运行的时候,只要使用在Xcode中设置的tag就可以非常方便的获取到资源。

类别

使用按需加载资源最多的两个方面是app bundle,包含可执行代码和重要的资源,例如UI图标和asset packs

在Xcode中可以将这些资源分为三个主要的类别:

  • 初始安装: 第一次运行需要的内容,过后可以删除。一般可以包含游戏的开始几关,当游戏进度足够远的时候就可以删除了。
  • 预取: 这个类别的内容在安装完应用后就需要立即下载。这个类型的数据应该应用在那些非必需的资源上,但是如果安装了可以获取更好的用户体验。比如游戏的新手教程。
  • 按需加载: 在程序运行过程中下载,不会影响程序的运行。这是我们使用最多的按需加载类型。
限制

支持按需加载资源的应用程序需要遵循以下限制:

  • iOS应用程序不能超过2GB
  • 初始安装的tag不能超过2GB
  • 预取tag不能超过2GB
  • 正在使用的资源不能超过2GB。这一点只有当应用正在运行并且使用了按需加载资源的时候才起作用。
  • 每个asset pack不能给你超过512MB。如果超过了这个限制,Xcode将给出警告并且允许我们继续测试和开发程序,但是提交到App Store时会失败。
  • 苹果为每个应用提供最多20GB的空间进行托管,这也是每个程序一次最多可以下载的资源数量。当然,应用程序一次最多只能使用2GB的资源。
应用分片

注意20GB的限制是所有应用程序分片的总和,而是总共20GB。那什么是应用程序分片呢?应用程序分片是iOS 9引入的,用于降低应用大小的一个特性。当应用被安装后,它只会查找与设备对应的资源。例如,当资源被正确使用的时候,iPhone 6 Plus或6s Plus只会加载3x的图标,而不会下载1x和2x的。所以整个按需加载资源的总的大小是20GB,包含我们上传到App Store服务器的所有设备类型需要的资源总和。除此以外其它限制条件都是针对特定的设备类型单独设置的。

删除按需加载资源

已经下载的按需加载资源只有当设备空间不够时才会被清理。当空间不够时,按需加载资源系统会查看设备上的所有应用,并且根据资源的最后使用时间决定删除哪个。如果应用程序正在运行,它拥有的资源永远都不会被清理。

2. 分配和指定Tag

使用Xcode打开启动项目并且在模拟器中运行程序。它包含一组图片,由三种颜色(红、绿、蓝)和四种形状(圆、正方形、星形和六边形)组合而成。当程序运行的时候,选择Colors > Red,我们可以看到一个红色的圆。

我们在程序中设置7个asset pack,每个包含一种颜色和一个形状。按需请求资源的另外一个特性是每个资源可以设置多个Tag。比如红色的圆可以同时是RedCircle包的一部分。

按需请求资源API对同一个资源不会下载两次。换句话说,就是如果已经下载Red包,那么在下载Circle包的时候,不会再次下载红色圆形这个图片。

在Xcode中,打开Assets.xcassets。我们可以看到12张图片。

下一步,选择蓝色方块图片集,并且打开Attributes Inspector

Attributes Inspector中包含一个新的On Demand Resource Tags组,可以用来设置资源的标签(Tag)。我们给蓝色方块设置BlueSquare标签。

设置好资源的Tag后,打开Xcode左侧的Project Navigator,点击Resource Tags标签并且选择Prefetched进行过滤。

我们可以非常方便的看到每个资源包的大小以及里面所包含的内容。Prefetched中显示每个类别中的资源,并且允许在不同的类别中进行移动:

  • 初始安装
  • 预取
  • 按需下载

这正是我之前所提到的三个类别。Prefetched Tag Order组中的资源在显示的时候自动开始下载。

设置好了所有的图片资源后,就可以开始访问这些内容了。

3. 访问按需请求资源

我们使用NSBundleResourceRequest获取App Store服务器托管的资源包。使用需要获取的资源的Tag创建request对象。它会告诉系统我们所需要使用的资源包是哪个。而释放这些对象则告诉系统我们不再需要这些资源包了。一定要注意不能超过2GB的资源限制。

在项目中,打开DetailViewController.swift并且在DetailViewController中添加一下属性。

var request: NSBundleResourceRequest!

下一步,替换viewDidAppear(_:)方法。

override func viewDidAppear(animated: Bool) {super.viewDidAppear(animated)request = NSBundleResourceRequest(tags: [tagToLoad])request.beginAccessingResourcesWithCompletionHandler { (error: NSError?) -> Void in//  Called on background threadif error == nil {NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void inself.displayImages()})}}
}

刚才的代码中我们用Tag初始化了一个request对象。tagToLoad属性是在前一个页面设置的,表示我们要显示的内容是什么。

下一步,我们通过调用beginAccessingResourcesWithCompletionHandler(_:)开始下载特定Tag标明的资源包。这个方法自动访问Tag对应的所有资源,并且开始下载。一旦获取到资源后,其它代码一切照旧。

注意,如果我们只希望访问已经下载的资源,而不想继续加重内容。可以调用conditionallyBeginAccessingResourcesWithCompletionHandler(_:)

需要提醒的是,上面方法的执行完后,handler是在子线程中执行的,因此需要切换到主线程再更新UI。

我们已经成功的在程序里使用了按需加载资源,简单吧!

Xcode 7的有一个重要的调试特性就是能够查看当前下载了那些资源包。点开Debug Navigator并且选择Disk就可以看到了。

我们可以改变一下资源的下载优先级,这样有些内容就会总是立马下载。同时还可以改变资源的保存优先级,比如HexagonStar会在CircleSquare之前清理。将代码改成一下样子:

override func viewDidAppear(animated: Bool) {super.viewDidAppear(animated)request = NSBundleResourceRequest(tags: [tagToLoad])request.loadingPriority = NSBundleResourceRequestLoadingPriorityUrgentNSBundle.mainBundle().setPreservationPriority(1.0, forTags: ["Circle", "Square"])NSBundle.mainBundle().setPreservationPriority(0.5, forTags: ["Hexagon", "Star"])request.beginAccessingResourcesWithCompletionHandler { (error: NSError?) -> Void in//  Called on background threadif error == nil {NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void inself.displayImages()})}}
}

初始化request对象后,我们可以设置loadingPriority属性为NSBundleResourceRequestLoadingPriorityUrgent。当然,也可以设置0-1之间的任意值来表明加载优先级。

这个常量自动设置请求为最高加载优先级,但是这取决于当前的CPU活动情况。在某些情况下,如果CPU任务繁忙,资源的下载可能会被推迟。

下一步我们通过mainBundle的setPreservationPriority(_:forTags:)设置四个形状的保存优先级。这时我们就可以确认,一旦按需加载系统需要清理一些资源的时候,就会先删除HexagonStar

4. 最佳实践

现在我们知道了如何在iOS应用里使用按需加载资源。下面我想给大家介绍一些需要注意的地方。

让每个Tag保持最小

为了减少资源的加载时间,使得每个资源更容易访问,应该让每个资源包保持尽可能的小。这样就不会导致被过度清理。

例如,系统本身需要释放50MB的空间,但是如果最合适被删除的包是400MB,这样就会导致350MB的内容被不必要的删除。这就意味着下次需要的时候又要多下350MB。建议每个资源包的大小应该接近64MB。

提前下载资源

如果你的应用有一个非常容易预见的用户操作过程,最好是提前就开始下载资源。这样可以提高用户体验,而不需要他们等待太久。

游戏是一个非常常见的场景。如果一个玩家已经完成了前5关,我们最好在他玩第6关的时候,开始下载第7关。

正确的停止对资源的访问

如果不在需要访问某个资源包,确保释放NSBundleResourceRequest对象或者调用endAccessingResources方法。

这样不仅可以防止我们的应用达到2GB的限制,而且可以帮助系统知道什么时候需要访问这些资源,从而更好的决定如何删除资源来获取更多空间。

5. tvOS上的按需访问资源

在我的另外一篇关于tvOS的博客提到tvOS的应用限制。比如最大程序大小为200MB,因此更应该使用按需方法资源。

tvOS和iOS的按需访问资源的其它限制是一样的,只是要注意tvOS仅使用1x的图片,因此并不会因为应用程序分片的存在而减少空间。

总结

iOS 9和tvOS上的按需加载资源是用来减少程序大小和提供更好用户体验的一个非常重要的方法。它非常容易使用和设置,但是要注意它的加载时间和数据清理所带来的一些问题。

转载于:https://my.oschina.net/kgdugyiy/blog/537728

iOS和tvOS游戏按需加载资源简介相关推荐

  1. On-Demand Resources Guide中文版(按需加载资源--上)

    本文翻译由唧唧歪歪翻译自Apple文档 On-Demand Resources Guide On-Demand Resources Guide中文版(按需加载资源--下)包含管理按需加载资源.调试以及 ...

  2. On-Demand Resources Guide中文版(按需加载资源--下)

    本文由唧唧歪歪翻译自Apple文档 On-Demand Resources Guide  该文档的上部分包含:按需加载资源基础以及创建和编辑tag两部分 (三)管理按需加载资源 下载和管理按需加载资源 ...

  3. Webpack实战(九):实现资源按需加载-资源异步加载

    第八篇[<教你搞懂webpack如果实现代码分片(code splitting)>] (https://blog.csdn.net/lfcss/article/details/104099 ...

  4. ensure函数_webpack中利用require.ensure()实现按需加载

    webpack中的require.ensure()可以实现按需加载资源包括js,css等,它会给里面require的文件单独打包,不和主文件打包在一起,webpack会自动配置名字,如0.js,1.j ...

  5. 按需加载图片、html代码、js代码,前端页面性能优化

    加载一个比较长的页面,或者图片比较多的页面,如果把资源一次性全部加载,在网络不是很好的情况下可能造成页面留白现象,用户体验极差! 因此呢,我们可以把用户暂时不会看到或用到的资源先不加载,在某个条件下, ...

  6. ensure函数_webpack中require.ensure()实现按需加载

    webpack中的require.ensure()可以实现按需加载资源包括js,css等,它会给里面require的文件单独打包,不和主文件打包在一起,webpack会自动配置名字,如0.js,1.j ...

  7. yepnope.js 异步加载资源文件

    yepnope.js是一个能够根据输入条件来选择性异步加载资源文件的js脚本,可以在页面上仅加载用户需要的js/css. yepnope的优点: 可以同时处理javascript以及css 能够按条件 ...

  8. React Native按需加载 手Q狼人杀探索之路

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/mUzq4NaBHeF3T-NStLzuRw 作者:pe ...

  9. React Native 按需加载 手Q狼人杀探索之路

    导语:最近特别火的狼人杀和最近特别火的React Native会擦出什么样的火花呢?本文和您一同探讨RN性能优化的现实场景. 项目简介: 狼人杀游戏是多人实时性游戏,对流畅度等性能都有要求.作为大型游 ...

最新文章

  1. Windows搜索工具 — Everything
  2. html背景mov,科技常识:html5自动播放mov格式视频的实例代码
  3. 菜鸟成长日记(一)之WMIC简单命令应用
  4. springboot配置内部配置类
  5. Bootstrap3 滚动监听插件的调用方式
  6. 《恋上数据结构第1季》二叉树代码实现
  7. 毕设过程小记—同步带传动选型计算+张紧机构
  8. CSS盒模型之内边距、边框、外边距 十九问(持续更新)
  9. 企业微信异常java.security.InvalidKeyException:illegal Key Size的解决方案,提供jce_policy-8下载
  10. Mac必备软件之程序员、设计师、产品经理
  11. 佳博80系列小票打印机 gp 80180安装驱动,显示打印错误
  12. windows快捷键失效 - 重启无效 - 插拔键盘解决
  13. 层次高的人,都拥有成长型思维
  14. 为什么微信显示这个android设备,微信显示安卓手机型号在哪设置
  15. Spring Boot系列 - 3. SpringBoot项目学习汇总
  16. ABAP 资产类BAPI过账 BAPI_ACC_DOCUMENT_POST
  17. 如何用计算机控制家带你开关,计算机控制系统复习点及答案
  18. 项目风险的主要来源有哪些?应如何防范
  19. C#与雷塞运动控制卡Dmc1380源码三轴点动运动 手动与自动位置设定
  20. 服务器自检后显示scsi,SCSI RAID卡常见故障分析及BIOS升级指导

热门文章

  1. Android ubuntu 设置手机驱动
  2. 计算机屏幕900,win10系统电脑屏幕没有1440 900分辨率的修复技巧
  3. 呵,偶居然也能“说教”了
  4. vue中is属性搭配vuedraggable插件实现可拖动可视化大屏展示组件的自定义配置功能
  5. 橄榄油可以用来炒菜吗
  6. 基于Seq2Seq的GRU时间序列预测Python程序
  7. Sputtr--万能搜索引擎
  8. 低功耗蓝牙5.0芯片nrf52832-QFAA简单介绍
  9. 基于微信小程序的服装童装商城+后台管理系统(SSM+mysql)-JAVA.VUE【毕业设计、论文、源码、开题报告】
  10. css 居中问题的总结