[TIMOB-19069] IOS9: App thinning: Support on-demand resources for app thinning
GitHub Issue | n/a |
---|---|
Type | New Feature |
Priority | High |
Status | Open |
Resolution | Unresolved |
Affected Version/s | n/a |
Fix Version/s | n/a |
Components | iOS |
Labels | appthinning |
Reporter | Chee Kiat Ng |
Assignee | Unknown |
Created | 2015-06-25T03:15:44.000+0000 |
Updated | 2018-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>
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?
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.
Could we achieve parity with Android's Google Play Expansion files? [~jasonkneen] has a (closed source) module for that: https://github.com/jasonkneen/TiExpansionFiles
[~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.
[~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.
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.
Ah.... (y)
[~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.
/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:"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 existingimageset
to allow mp3 files and other non-image data as well. TheContents.json
for those sets (e.g.Assets.xcassets/my_music.dataset
looks like the following: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:- Finally, link the tags to the toplevel
Assets.xcassets/Contents.json
as proposed above: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!
Couple of thoughts:
I don't want to continue polluting the
tiapp.xml
with more and more garbage. We need to ditch thetiapp.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.
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.