Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-19069] IOS9: App thinning: Support on-demand resources for app thinning

GitHub Issuen/a
TypeNew Feature
PriorityHigh
StatusOpen
ResolutionUnresolved
Affected Version/sn/a
Fix Version/sn/a
ComponentsiOS
Labelsappthinning
ReporterChee Kiat Ng
AssigneeUnknown
Created2015-06-25T03:15:44.000+0000
Updated2018-10-03T11:07:58.000+0000

Description

*Overview:* The On-Demand-Resources provide a way to load resources only when requested. The resources are grouped into tags, which is done through Xcode (also need to figure out, how to do this on proxy side). The Idea is, to supply an easy way to access and download resources and release them after there are not needed anymore as part of the app thinning process. The current progress can also be tracked, as well as warnings regarding low memory. *Demo code:*
var win = Ti.UI.createWindow({
  backgroundColor: "#fff",
  layout: "vertical"
});

var manager = Ti.App.iOS.createOnDemandResourcesManager();

var beginButton = Ti.UI.createButton({
  title: "Access Resources",
  top: 50
});

var resultProgress = Ti.UI.createProgressBar({
  top: 50,
  min: 0,
  max: 1,
  width: 300,
  height: 10,
  value: 0.0
});

var resultImage = Ti.UI.createImageView({
  top: 50,
  height: 100,
  image: "titanium.png"
});

beginButton.addEventListener("click", function() {
  manager.conditionallyBeginAccessingResources({
    tags: ["appc"],
    success: function(e) {
      resultImage.setImage("titanium");
      // Resources are now accessible.
      Ti.API.warn(e);
    },
    error: function(e) {
      // Accessing the resources failed.
      Ti.API.error(e);
    }
  });
});

manager.addEventListener("progress", function(e) {
  Ti.API.warn(" -- PROGRESS --");
  Ti.API.warn(e);
  resultProgress.setValue(e.value);
});

win.add(beginButton);
win.add(resultProgress);
win.add(resultImage);
win.open();
*Apple docs:* https://developer.apple.com/library/prerelease/ios/documentation/FileManagement/Conceptual/On_Demand_Resources_Guide/ *Note:* On demand resources are only available for iOS9. that means for developers who wants this, they have to set the minimum iOS version as 9.0 otherwise it won't compile. Just do this in tiapp.xml.
<ios>
    <min-ios-ver>9.0</min-ios-ver>
</ios>

Comments

  1. Hans Knöchel 2015-07-09

    The documentation link was updated by Apple yesterday, so i updated here as well. Also added a brief overview, how the implementation will look. [~cng]: The tagging of resources is currently a problem, because resources can only be assigned to tags through Xcode. How could we solve this?
  2. Fokke Zandbergen 2015-08-21

    Once we have generating image asset catalogs in place we could have a Titanium-specific file where developers would list filepaths per tag. Then we can use that when we generate asset catalogs to set the tags for each of them.
  3. Fokke Zandbergen 2015-08-22

    Could we achieve parity with Android's Google Play Expansion files? [~jasonkneen] has a (closed source) module for that: https://github.com/jasonkneen/TiExpansionFiles
  4. Fokke Zandbergen 2015-10-03

    [~hansknoechel] have you looked into android expansion files (see earlier comment) as well? With a 100mb limit (earlier 50) this is even more needed for Android then iOS.
  5. Fokke Zandbergen 2015-10-12

    [~hansknoechel] just an idea.. why not let developers store assets they want on-demand in a separate directory? Then just by looking at the directory tree you can see which assets are on-demand and which are not. And then we don't need any Studio UI as well.
  6. Hans Knöchel 2015-10-13

    Because it's a bit more complicated: We must be able to assign certain certain files to groups (aka "tags"), that can then be accessed. So we cannot access per file but per tag. Example: file1,file2 are part of "mytag_1" and file3,file4 are part of "mytag_2". Therefore we need a Xcode similar interface to tag files to support it the right way.
  7. Fokke Zandbergen 2015-10-13

    Ah.... (y)
  8. Fokke Zandbergen 2015-11-02

    [~hansknoechel] as you start to think of a meta-file and CLI (then later Studio) tooling to tag files, could you right form the start also think about parity with Android APK Expansion Files? TIMOB-17391 [~jasonkneen] used to have a (closed source) module for this on GitHub but I see it's no longer.
  9. Hans Knöchel 2016-11-06

    /cc [~cng], [~cbarber], [~sdavenport] I talked to [~jasonkneen] and he was so kind to provide the Android source for Android APK Expansion Files that we can include in our Ti.Filesystem core to access the downloaded extension files (basically just a zip that needs some file handling from what I saw). In addition to that, we have this (finished) iOS PR to support iOS On-Demand-Resources. The current problem was that we need a data structure to group the resources in "tags" so we can request them from our apps. For that, I thought about an architecture like this (in the <ios/> group:
       <on-demand-resources>
           <tag name="level1">
               <file name="background1.png" />
               <file name="sound1.mp3" />
               <file name="texture1.png" />
           </tag>
           <tag name="level2">
               <file name="background2.png" />
               <file name="sound2.mp3" />
               <file name="texture2.png" />
           </tag>
       </on-demand-resources>
       
    "Tags" can have multiple "files" that are placed in the asset catalog. Currently, I think, we only store JPG and PNG i files in the asset catalog, that regex needs to be updated and allow to create a dataset along with the existing imageset to allow mp3 files and other non-image data as well. The Contents.json for those sets (e.g. Assets.xcassets/my_music.dataset looks like the following:
       {
         "info" : {
           "version" : 1,
           "author" : "xcode"
         },
         "data" : [
           {
             "idiom" : "universal",
             "filename" : "my_music.mp3"
           }
         ]
       }
       
    A summary of all different kind of sets: ||Type||Extension|| |Image Sets|.imageset| |Data Sets|.dataset| |Texture Sets|.textureset| |Cube Texture Sets|.cubetextureset| We would only need support for the first two, as the latter require more CLI logic like X-Y-Z parts. We also need the following CLI adjustments: - Parse the on-demand-resources node to create an internal data structure of tags and files - Map the file names to our used SHA-1 hashes (or even get rid of that if possible by now, solves some more problems as well) - Use the mapped data structure to adjust the .pbxproj so Xcode knows how we group our files, like this:
       29B97313FDCFA39411CA2CEA /* Project object */ = {
           isa = PBXProject;
           attributes = {
               KnownAssetTags = (
       	    level1,
       	);
       	LastUpgradeCheck = 0430;
           };
           ...
       }
       
    - Finally, link the tags to the toplevel Assets.xcassets/Contents.json as proposed above:
       "info" : {
           ...
           "on-demand-resource-tags" : [
               "level1"
           ]
       }
       
    I could think about 6.1.0 or 6.2.0 include this change, it would be a major Enterprise feature for reducing app size and exposing more flexibility across asset management. Thoughts welcome!
  10. Chris Barber 2016-11-07

    Couple of thoughts:

    I don't want to continue polluting the tiapp.xml with more and more garbage. We need to ditch the tiapp.xml as a project file and come up with a proper project file similar to Xcode's. What you're talking about is assigning metadata to individual files and we need this for so many things beyond asset catalog such as encryption. We need a project file that supports proper build configurations (see TIMOB-12025 and https://wiki.appcelerator.org/display/pe/Build+Configurations) because we cannot continue to tightly couple things to the deploy type and app guid.

    I don't love that we have to SHA resource paths, but it works and works well. Perhaps we should just convert the resource path to something readable such as the path where the path separate is underscores?

    What about Android and Windows? I'm not sure what this APK expansion buys us beyond larger apps. Doesn't Android have a similar concept to app thinning? How about Windows? It would be great to design a system that abstracts the asset catalog (cough, Titanium asset catalog, cough) and that works for all platforms.

  11. Hans Knöchel 2016-11-07

    In response:

    Agree. We introduced the [appc.js](https://github.com/appcelerator/hyperloop-examples/blob/master/appc.js) with Hyperloop, maybe that's a good place to store them JS-based (please no more XML :-)

    What have been the problems with base names instead of hashes again? Densities go under one base name (file.png, file@2x.png, file@3x.png), same base names (e.g. file.png and file.mp3) go into different sets (.imageset vs .dataset). And if there is an edge-case like file.png vs file.jpg, we would throw a warn-log and hash the names. But let me check the native behavior first, pretty sure the handle this with "file-1" then. *EDIT*: [Yes](https://abload.de/img/screenshot2016-11-07azask9.png) it [does](https://abload.de/img/screenshot2016-11-07aecsfh.png).

    Looking at [this article](https://arc.applause.com/2015/09/28/android-6-0-apk-file-size/), APK expansion files are the equivalent for iOS on demand resources. For Windows, I could not find anything similar, maybe the Windows team knows more regarding that.

JSON Source