Introduction to loading resources on demand for iOS and tvOS games

Source: Internet
Author: User
Tags new set spritekit
<span id="Label3"></p><p><p><span class="corner"><span class="corner">Abstract with iOS 9 and watchOS 21, Apple has introduced a new set of content distribution APIs to conserve device space, which is loading resources on Demand. By using On-demand loading of resources, we can host specific application resources on Apple's servers and then load them when Needed. In this tutorial, i'll show you the basic usage of loading resources on demand by developing a picture view app.</span></span></p></p>TvOS on Demand reourse load iOS Development on demand<p><p><span class="corner"><span class="corner"></span></span></p></p><p><p><span id="AnchorContentToggle" class="corner" title="点击收起目录">Catalogue [-]</span></p></p> <ul> <ul> <li class="osc_h4">Introduced</li> <li class="osc_h4">Preparatory work</li> <li class="osc_h4">1. Load Resources on Demand</li> <li class="osc_h5">Benefits</li> <li class="osc_h5">Category</li> <li class="osc_h5">Limit</li> <li class="osc_h5">Apply Sharding</li> <li class="osc_h5">To delete an On-demand load resource</li> <li class="osc_h4">2. Assigning and specifying tags</li> <li class="osc_h4">3. Accessing On-demand Resource Requests</li> <li class="osc_h4">4. Best Practices</li> <li class="osc_h5">Keep each tag to a minimum</li> <li class="osc_h5">Download resources in advance</li> <li class="osc_h5">Stop access to resources correctly</li> <li class="osc_h4">5. On-demand access to resources on tvOS</li> <li class="osc_h4">Summarize</li> </ul> </ul><p><p>Camp David Education Translation: thanks to <strong>Davis Allie</strong> 's an Introduction-on-demand Resources on IOS and TvOS</p></p>Introduced<p><p>With iOS 9 and watchOS 21, Apple introduced a new set of content distribution APIs to conserve device space, which is <strong>loading resources on Demand</strong> . By using On-demand loading of resources, we can host specific application resources on Apple's servers and then load them when Needed. In this tutorial, i'll show you the basic usage of loading resources on demand by developing a picture view app.</p></p>Preparatory work<p><p>This tutorial requires the use of Xcode 7+ and familiarity with iOS Development. You can download the initial project to Github.</p></p>1. Load resource benefits on Demand<p><p>IOS 9 and watchOS 2 introduce the primary purpose of loading resources on demand to reduce the space occupied by a single Application. Another benefit is that our application can be downloaded and started faster by the User.</p></p><p><p>Get On-demand loading of resources by using the only <strong>tags</strong> assigned by the <strong>Asset pack</strong> in Xcode. These resource bundles can contain content from any asset (pictures, Spritekit textures, data, and so on), and even other files such as OpenGL and metal shaders, Spritekit and Scenekit scene files, and particle systems.</p></p><p><p>When we submit apps to the app store, these resources are also uploaded and hosted so that they can be downloaded when Needed. When the program is running, you can easily get to the resource by using the tag set in Xcode.</p></p>Category<p><p>The top two aspects of using On-demand resources are <strong>app bundles</strong>, which contain executable code and important resources such as UI icons and <strong>asset packs</strong>.</p></p><p><p>In xcode, you can divide these resources into three main categories:</p></p> <ul> <ul> <li><strong>Initial installation</strong> : The content that is required for the first run and can be deleted later. You can usually include the beginning of the game, and when the game is far enough, it can be deleted.</li> <li><strong>prefetch</strong> : This category of content needs to be downloaded immediately after the app is Installed. This type of data should be applied to those resources that are not required, but if installed, a better user experience can be Obtained. For example, the Game's novice tutorial.</li> <li><strong>load on Demand</strong> : Downloaded during program run, does not affect the operation of the Program. This is the most load-on-demand type we use.</li> </ul> </ul>Limit<p><p>Applications that support on-demand loading of resources need to adhere to the following restrictions:</p></p> <ul> <ul> <li>iOS apps cannot exceed 2GB</li> <li>The initial installation tag cannot exceed 2GB</li> <li>Pre-fetch tag cannot exceed 2GB</li> <li>The resource you are using cannot exceed 2GB. This only works if the app is running and uses the On-demand load Resource.</li> <li>Each asset pack cannot give you more than 512MB. If this limit is exceeded, Xcode will give a warning and allow us to continue testing and developing the program, but will fail when submitted to the app Store.</li> <li>Apple provides up to 20GB of space for each app to host, which is the number of resources that each program can download at a Time. of course, applications can use up to 2GB of resources at a Time.</li> </ul> </ul>Apply Sharding<p><p>Note that the 20GB limit is the sum of all application shards, but a total of 20GB. So what is application sharding? Application sharding is an attribute introduced by iOS 9 to reduce the size of your app. When the app is installed, it will only look for resources that correspond to the Device. For example, when a resource is used correctly, the IPhone 6 Plus or 6s Plus only loads the 3x icon without downloading 1x and 2x. So the total size of the entire on-demand load of resources is 20GB, which contains the sum of the resources that we need for all the device types that we upload to the App Store Server. Other restrictions are set separately for specific device Types.</p></p>To delete an On-demand load resource<p><p>On-demand load resources that have already been downloaded will only be cleaned up if there is not enough space on the Device. When space is not enough, loading the resource system on demand will look at all apps on the device and decide which to delete based on the last use time of the Resource. If the application is running, the resources it owns will never be cleaned up.</p></p>2. Assigning and specifying tags<p><p>Use Xcode to open the startup project and run the program in the Emulator. It contains a set of pictures, composed of three colors (red, green, blue) and four shapes (circle, square, star, and hexagon). When the program is running, select <strong>Colors > Red</strong>, we can see a red circle.</p></p><p><p></p></p><p><p></p></p><p><p></p></p><p><p>We set up 7 asset packs in the program, each containing one color and one shape. Another feature of Request-on-demand resources is that each resource can have multiple tags set. Red circles, for example, can <strong></strong> be part of the red and <strong>circle</strong> packages.</p></p><p><p>The On-demand Resource API is not downloaded two times for the same resource. In other words, if you <strong></strong> have already downloaded the red package, you will not be able to download the <strong>Circle</strong> package Again.</p></p><p><p>In xcode, open <strong>assets.xcassets</strong>. We can see 12 photos.</p></p><p><p></p></p><p><p>next, Select the <strong>blue block</strong> picture set and open <strong>Attributes Inspector</strong>.</p></p><p><p></p></p><p><p>The <strong>Attributes Inspector</strong> contains a new on <strong>Demand Resource tags</strong> group, which can be used to set the label of the resource (tag). We set the blue and <strong></strong> <strong>Square</strong> labels for the Blues Squares.</p></p><p><p></p></p><p><p></p></p><p><p>After setting the tag for the resource, open <strong>Project Navigator</strong>on the left side of xcode, click the <strong>Resource Tags</strong> tab and select <strong>prefetched</strong> to Filter.</p></p><p><p></p></p><p><p>We can easily see the size of each resource bundle and what is contained within it. The resources in each category are shown in <strong>prefetched</strong> and are allowed to move in different categories:</p></p> <ul> <ul> <li>Initial installation</li> <li>Pre-fetching</li> <li>Download on Demand</li> </ul> </ul><p><p>This is exactly the three categories I mentioned earlier. Prefetched the resources in the <strong>Tag Order</strong> Group start downloading automatically when it is Displayed.</p></p><p><p>Once you've set up all your picture resources, you're ready to start accessing Them.</p></p>3. Accessing On-demand Resource Requests<p><p>We use <code>NSBundleResourceRequest</code> A resource bundle that gets hosted by the App Store Server. Create a Request object using the tag of the resource you want to Get. It tells the system which resource bundle we need to use. Releasing these objects tells the system that we no longer need these resource bundles. Be careful not to exceed the 2GB resource limit.</p></p><p><p>In the project, open <strong>detailviewcontroller.swift</strong> and <code>DetailViewController</code> add the properties in.</p></p><pre><pre><code class="lang-swift hljs"><span class="hljs-keyword">var request: <span class="hljs-type">NSBundleResourceRequest!</span></span></code></pre></pre><p><p>next, Replace the <code>viewDidAppear(_:)</code> method.</p></p><pre><code class="lang-swift hljs"><span class="hljs-keyword">Override<span class="hljs-func"><span class="hljs-keyword"><span class="hljs-func"><span class="hljs-keyword">Func<span class="hljs-func"><span class="hljs-func"> <span class="hljs-title"><span class="hljs-func"><span class="hljs-title">viewDidAppear <span class="hljs-params"><span class="hljs-func"><span class="hljs-params"> (animated:bool) <span class="hljs-func"> {<span class="hljs-keyword">super.viewdidappear (animated) request = <span class="hljs-type">nsbundleresourcerequest (tags: [tagtoload]) Request.beginaccessingresourceswithcompletionhandler {(error: <span class="hljs-type">nserror?), <span class=" Hljs-type ">void <span class=" hljs-keyword ">in <span class=" hljs-comment ">//called on background thread <span class=" Hljs-keyword ">if Error = = <span class=" hljs-built_in ">nil {<span class=" hljs-type ">nsoperationqueue.mainqueue (). Addoperationwithblock ({(), <span class="hljs-type">void <span class="hljs-keyword">in <span class="hljs-keyword">self.displayimages ()}) } }}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span> </span></span></span></span></span></span></span></span></span></span></code></pre><p><p>In the code we have just initialized an object with tag <code>request</code> . <code>tagToLoad</code>properties are set on the previous page, indicating what we want to display.</p></p><p><p>next, we start by calling to <code>beginAccessingResourcesWithCompletionHandler(_:)</code> download the resource bundle indicated by the specific tag. This method automatically accesses all the resources that the tag corresponds to and starts the Download. Once the resource has been acquired, all other code is still the Same.</p></p><p><p>Note that if we only want to access resources that have already been downloaded, we don't want to continue to aggravate the Content. can be called <code>conditionallyBeginAccessingResourcesWithCompletionHandler(_:)</code> .</p></p><p><p>It is necessary to note that after the execution of the above method, handler is executed in the child thread, so it is necessary to switch to the main thread and then update the UI.</p></p><p><p></p></p><p><p>We have successfully used the On-demand loading resources in the program, simple!</p></p><p><p>One of the important debugging features of Xcode 7 is the ability to see which resource bundles are currently Downloaded. Click on <strong>Debug Navigator</strong> and select <strong>Disk</strong> to see it.</p></p><p><p></p></p><p><p>We can change the download priority of the resource so that some content will always be downloaded immediately. You can also change the resource retention priority, such as <strong>Hexagon</strong> and <strong>Star</strong> cleanup before <strong>Circle</strong> and <strong>Square</strong> . Change the code to look like This:</p></p><pre><code class="lang-swift hljs"><span class="hljs-keyword">Override<span class="hljs-func"><span class="hljs-keyword"><span class="hljs-func"><span class="hljs-keyword">Func<span class="hljs-func"> <span class="hljs-title"><span class="hljs-func"><span class="hljs-title">Viewdidappear<span class="hljs-params"><span class="hljs-func"><span class="hljs-params">(animated:bool)<span class="hljs-func">{<span class="hljs-keyword">Super.viewdidappear (animated) request =<span class="hljs-type">Nsbundleresourcerequest (tags: [tagtoload]) request.loadingpriority =<span class="hljs-type">Nsbundleresourcerequestloadingpriorityurgent<span class="hljs-type"><span class="hljs-type">nsbundle.mainbundle () setpreservationpriority (<span class="hljs-number">1.0, forTags: [ Span class= "hljs-string" > "Circle", <span class="hljs-string"> "Square"]) <span class="hljs-type"> Nsbundle.mainbundle (). setpreservationpriority (<span class="hljs-number">0.5, fortags: [<span class="hljs-string"> "Hexagon", <span class="hljs-string"> "Star"]) request.beginaccessingresourceswithcompletionhandler {(error: <span class="hljs-type">nserror?) -<span class="hljs-type">void <span class="hljs-keyword">in <span class="hljs-comment">//Called on background Thread <span class="hljs-keyword">if error = = <span class="hljs-built_in">nil {<span class="hljs-type"> Nsoperationqueue.mainqueue (). addoperationwithblock ({(), <span class="hljs-type">void <span class="hljs-keyword">in <span class="hljs-keyword">self.displayimages ()})} }}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span> </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre><p><p>After initializing the request object, we can set <code>loadingPriority</code> the property to <code>NSBundleResourceRequestLoadingPriorityUrgent</code> . of course, You can also set any value between 0-1 to indicate the load Priority.</p></p><p><p>This constant automatically sets the request to the highest load priority, but it depends on the current CPU Activity. In some cases, if the CPU task is busy, the download of the resource may be postponed.</p></p><p><p>Next we <code>setPreservationPriority(_:forTags:)</code> set the save priority of four shapes by mainbundle. At this point we can confirm that <strong>Hexagon</strong> and <strong>Star</strong>are removed as soon as the system needs to be cleaned with some resources on demand.</p></p>4. Best Practices<p><p>Now we know how to use On-demand loading resources in iOS Apps. I would like to introduce to you some of the areas that need Attention.</p></p>Keep each tag to a minimum<p><p>To reduce the load time of resources, making each resource more accessible, you should keep each resource bundle as small as Possible. This will not lead to being over-cleaned.</p></p><p><p>For example, the system itself needs to free up 50MB of space, but if the most appropriate package to be deleted is 400MB, this can cause 350MB of content to be deleted unnecessarily. This means that the next time you need more than 350MB. It is recommended that the size of each resource pack be close to 64MB.</p></p>Download resources in advance<p><p>If your app has a very predictable user action process, It's a good idea to start downloading resources in Advance. This can improve the user experience without requiring them to wait too long.</p></p><p><p>The game is a very common scenario. If a player has completed the top 5, we'd better start downloading the 7th level when he plays the 6th Pass.</p></p>Stop access to resources correctly<p><p>If you do not need to access a resource bundle, Be sure to dispose of the <code>NSBundleResourceRequest</code> object or invoke the <code>endAccessingResources</code> method.</p></p><p><p>This not only prevents our application from reaching the 2GB limit, but also helps the system know when it needs to access these resources to better decide how to remove resources to get more space.</p></p>5. On-demand access to resources on tvOS<p><p>In my other blog about tvos, the application limitations of tvOS are Mentioned. For example, The maximum program size is 200MB, so you should use On-demand method Resources.</p></p><p><p>The other restrictions on on-demand access to resources for tvOS and iOS are the same, just note that tvOS only uses 1x images, so it does not reduce space because of the presence of application shards.</p></p>Summarize<p><p>On-demand loading of resources on IOS 9 and tvOS is a very important way to reduce program size and provide a better user experience. It is very easy to use and set up, but pay attention to its loading time and some problems caused by data cleanup.</p></p><p><p>Introduction to loading resources on demand for iOS and tvOS games</p></p></span>
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.