Objective-C
Xcode
iOS

Xcode5から追加されたAsset Catalogの挙動をいろいろ試してみた

More than 5 years have passed since last update.

先日yimajoさんがQiitaへ投稿された記事「Xcode5から追加されたAsset Catalog最大のメリット」の中で


Asset Catalog使える環境なのに使わないのは老害


とおっしゃっていたのを見て、大変ショックを受けた私(笑)はムチを打ってAsset Catalogの挙動を調べてみる事にしたのでした(もしかして釣られた!?)。

また、すでに「Asset Catalogはアプリのアイコンや起動画面で使うと管理が楽になる」というのは国内のブログなどを見ていても明白だと思いますので、今回は通常の画像パーツを取り扱う上で何をするとどうなるかを適当に試してみる事にしました。


  • Xcode 5.0.1 使用 (2013/11/15現在)


非RetinaとRetinaで同名ファイルを突っ込むとどうなるの?

New Image Setaaaという名前のイメージセットを作り、1xに000.png、2xにRetina/000.pngをドロップで突っ込んでみた結果がこちら。

kobito.1384492399.517850.png

Images.xcassetsフォルダの中に以下のようなフォルダ・ファイルが出来るようです。

kobito.1384492621.998737.png


Contents.json

{

"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "000.png"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "000-1.png"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}


  • ドラッグ&ドロップで登録する限り、ファイルはコピーが前提のもよう(旧方式はネットワークから持ってきた時、間違ってリンク扱いにしてしまう事もあった)。

  • 同名だったら勝手にリネームされて登録される(000-1.png)。

  • 元の画像ファイル名は何でもよく、JSONファイルに書かれた内容によって処理される。

  • Image Set名を変えた場合はフォルダ名が変わるだけでPNGファイル名は変わらない(Image Set名と中のPNGファイル名は関連していない)。

ビルドして、バイナリがどのように配置されるのかをシミュレータで試してみたところ、てっきりaaa.pngaaa@2x.pngに展開されるのかと思いきや、Assets.carというファイルにパッキングされているようです。

kobito.1384493923.341885.png


画像はどうやってロードするの?

UIImage#imageNamedを使う。

[UIImage imageNamed:@"aaa"];

imageNamedは画像がキャッシュされるという話を良く聞いていますので他に方法が無いか探してみましたが、昔のように

NSString *path = [[NSBundle mainBundle] pathForResource:@"aaa" ofType:@"png"];

UIImage *img = [[UIImage alloc] initWithContentsOfFile:path];

というような書き方では動きませんでした。

パスがうまく取得できません。

(前述のようにAssets.carになっているからでしょうね。)

参考:http://stackoverflow.com/questions/18968352/access-asset-catalog-pathforresource


ローカライズは可能なの?

現時点では簡単にはできないようです。

頑張れば出来るっぽいですが。

参考:http://stackoverflow.com/questions/18814801/localize-asset-catalogs


階層化して同名の画像名があっても大丈夫なの?

kobito.1384500431.859906.png

警告が出ました。

kobito.1384500462.307341.png

名前の重複を回避するためにフォルダ機能を使えるかと思ったのですが、駄目みたいです。


外部からカタログフォルダ内を構築しても勝手に反映されるの?

Images.xcassetsフォルダ内をfinderなどから適当にいじっても、即座にXcode側が変更を検知してくれます。

ツールを作って画像を一括処理してAsset Catalogフォルダを構築するといった手段は使えそうですね。


おまけ

Asset Catalogを使う事で、リサイザブルな設定がIDE上でできるようです(iOS7以降のようですが)。

参考:https://developer.apple.com/library/ios/recipes/xcode_help-image_catalog-1.0/SlicinganImage/SlicinganImage.html#//apple_ref/doc/uid/TP40013303-CH4-SW1


感想

大量の画像リソースをImage Setとしてマウスで登録していく作業は正直苦行だと思います。


  • ちなみに私が先日まで作っていたアプリで使ったPNGファイルは1000近くありました(Retina+非Retina)。

やるなら(上にも少し書きましたが)デザイナーから上がってきた画像類を、Images.xcassetsフォルダ内へ配置(JSONファイルも作成)するように自動化するツールでも作らないとやっていられなさそうです。自動化してしまえば更新も楽ですし(まあAsset Catalogを使わない場合でもこういった自動化をしている方はいらっしゃると思いますが)。

ローカライズの対応も怪しいようですし、コンフリクトのメリットは有るのかもしれませんが、通常画像においては、メリットはそれぐらいしか無いのではないかという印象です。

もしAsset Catalog使うと今まで不便だったアレコレがこんなに良くなるぜ!ですとか、むしろこんなデメリットがあるぜ!という話がありましたら、お聞かせいただけると幸いです。