Hacker News new | ask | show | jobs
by robomartin 5180 days ago
Thinking some more about the problem I concluded that I don't personally have a problem with the creation of multiple versions of the artwork. Most of it can be done through batch processing and some hand tweaking. No big deal. The issue is with app bundle bloat and the download of a huge number of files into a device that will not use them.

Here's an off-the-top-of-my-head potential solution:

Update Xcode to sensibly handle file structures within a project. You know, the blue folders. We currently use blue folders for all app assets because, well, can you imagine maintaining 1600 files all in on directory?

The problem with blue folders today is that they needle you with pain. You have to remember to do clean builds (scripts during the build don't seem to work reliably) and, in general, be very aware of them. Once they are part of your process its not a big deal, but I think it's high time that Xcode come to this century and do something that most other development systems have been doing for, I don't know, decades?

Anyhow, once that is in place, you could have a directory structure such as this one at the app root:

  App Resources
  App Resources @2X
  App Resources ~ipad
  App Resources ~ipad @2X
I then want to include a JSON file at the app root level that points out the root directories for each device category. Maybe something like this:

  {
    "ipod 1":    "App Resources",
    "ipod 2":    "App Resources",
    "ipod 3":    "App Resources",
    "ipod 4":    "App Resources @2X",
    "iphone 1":  "App Resources",
    "iphone 2":  "App Resources",
    "iphone 3":  "App Resources",
    "iphone 4":  "App Resources @2X",
    "iphone 4S": "App Resources @2X",
    "ipad 1":    "App Resources ~ipad",
    "ipad 2":    "App Resources ~ipad",
    "ipad 3":    "App Resources ~ipad @2X"
  }
Now provide for a way to load this JSON data into the app and have relevant methods, such as "imageNamed" use a device specific path. My guess is that you'd want this to be by extension rather than modification so:

  + (UIImage *) imageNamedAndKeyForPath:(NSString *)name  key_for_path:(NSString *)key
Obviously the key would be used to retrieve the value from the JSON file or, preferably, a value already stored in memory when the JSON file was parsed at app start time.

Apple then, would have a mechanism to only deliver the appropriate resource files during an in-device installation. iTunes could download the whole set and also be intelligent during to-device installation. They'd use the JSON file to have the developer tell them which files to deliver.

Any files left outside the designated directories would be treated as they are today: Everything goes to every device.

Also, other methods that take a path, such as "imageWithContentsOfFile" ought to have a version that uses the aforementioned mechanism while --and this is important-- letting me specify relative paths from the device-specific folder. If I have something like this:

  <device specific folder>
    + character
      + arms
      + legs
      + head
    + background
      + trees
      + rocks
      + clouds
I ought to be able to access the path structure relative to the chosen device-specific directory of assets.

On first inspection this sounds like a good solution. I haven't thought it through entirely. I'd be interested to hear of what holes the idea might have.

Something like this could have a striking effect on app bundle size, particularly on older devices. I don't think that it places an undue burden on developers either, if anything it makes things easier. Heck I'm sure Apple could even find a way to make it a marketing point: "Four times as many apps in the same space".

3 comments

I feel like this is an overengineered solution by somebody who is not quite familiar with what the platform has to offer.

1) UIImage already handles choice based on asset name. Apple could use the same asset choice logic server-side for each device, without the developer having to corral his assets into directories. It just needs to be expanded to handle ~ipad and ~iphone (which UIImage does not natively, but if they make this a standard, they could.) The fallbacks would, of course, be most-specific to least-specific: scale and device before common. One downside here is that direct path access to an image will not be fixed, but they already do static analysis for message names, you can find calls to bundle methods and keep those assets lying around.

2) JSON?! We have property lists, they're way more Appley and have framework support through-and-through.

3) While this might provide the ability for a developer to choose which resources are used where, Apple is not in the business of giving developers (or users) choices.

In other words, I don't think the onus should be on developers. They should be free to do what they do best: innovate about the real problems, not the platform's solvable deficiencies.

The above listed can also be applied to all existing app bundles, were Apple feeling adventurous. Parent's method can not.

> an overengineered solution by somebody who is not quite familiar with what the platform has to offer.

Geez, thanks.

UIImage's handling of assets based on file name is a horrible band-aid.

Also, one has to think workflow. And, to make things more interesting, exaggerate. Let's make it 5,000 files in one directory. That's a mess. With device-specific directories an artist could create a workflow leading to easy maintenance and creation of files. No need to engage in funky naming conventions. The per-device files are simply located where they need to be and a mechanism is provided to identify which path serves a particular device type.

Another problem with UIImage is that there is no way to communicate to Apple which files are to be delivered to, say, an iPod touch. So, an external mechanism is required in order to encode that information. Hence the proposal for an external JSON (or whatever) file.

Why JSON. I like it. Supported by iOS 5.0 as well. Easy to maintain and exist externally to Xcode. This also means that I can write scripts or automation tools on a PC or Mac to automate the creation of assets and their placement within the proper structure. The file used within the app to communicate the per-device directory structure would also could also serve external purposes that cannot be covered with plists. In our case, as an example, all of our assets are being produced on PC's, not Macs.

> Apple is not in the business of giving developers (or users) choices.

That's another matter. Although my proposal wasn't about providing choices as much as it is about a mechanism to only deliver the necessary files to a device. Only the developer can make decisions about which files are appropriate, not Apple.

Ultimately, I don't care what technology might be used in order to enable something like this so long as it works and is reasonably open. Right now I'd love to be able to deliver only 1X files to iPods and ~ipad@2X files to the new iPad rather than forcing a huge download of 1,600 files to every device or the current project on our table. That's just silly.

I have a question about localization: Does Apple deliver all language files to a device or only those based on the localization settings? That could be another area of app bloat.

Also, keep in mind that localization can also exist in graphical assets. You could have images with built-in text that need to be switched in based on localization. So, an English version of the app uses this set and an Italian version another set of assets. This might include sound files.

Depending on how this is handled it can start to explode the app bundle in impressive ways. Start with 100 images. Now you need 400 to cover all device display configurations. Then you need to replicate this on a per-language basis. If you cover, say, five languages, you are up to 2,000 files potentially delivered to every single device regardless of applicability. I realize that this is a corner case where all images need to be localized. No need to point that out.

I have not done any internationalization yet, so I don't know how this part works. For some cases it might not be practical to release a separate app in different languages. For example, a kids app that is able to operate in English and Spanish and sold through the US app store.

Another interesting point about using a JSON file to map to device-specific resources is that the concept could be extended for future devices.

Let's say that a future iDevice comes with a better audio engine. Maybe it can do 5.1 surround? You could extend the JSON structure to include a section to define where the 5.1 surround files would be for the new device. Older devices wouldn't have to waste storage and download audio files that they can never use.