【追記】2014.9.13 3:00
この方法はあくまで「アプリ内保存した画像のパス」の話で、Xcode上で最初から登録している画像には当てはまりません。パスに「Documents」ディレクトリが含まれないためです。
【Xcode5.1.1 + iOS 7.1 + MacOX10.9.4】
前回の解決編です。
JBOYSOFT JunjiSuzukiさんに「NSSearchPathForDirectoriesInDomains を使うのもいいかも」との助言を受けて、描いてみたコードがこれ。NSSearchPathForDirectoriesInDomainsでディレクトリのパスを取ってきて、保存しているファイル名と組み合わせて、自前でパスを作っている。
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory,
NSUserDomainMask, YES);
NSArray *ph = [select_name componentsSeparatedByString:@"/"];
NSString *fn = [ph objectAtIndex:ph.count-1];
NSLog(@"paths >> %@",paths);
NSLog(@"fn >> %@",fn);
path = [NSString stringWithFormat:@"%@/%@",[paths objectAtIndex:0],fn];
NSLog(@"path >> %@",path);
iconImage = [[UIImage alloc] initWithContentsOfFile:path];
これだと既存のものも、起動後に保存したものも、どちらも問題なく参照出来る!NSLogによるトレースはこちら。
paths >> (
"/var/mobile/Applications/BB4E2366-816D-427F-8F8B-FF836EB58AB8/Documents"
)
fn >> icon20140913003532.png
path >> /var/mobile/Applications/BB4E2366-816D-427F-8F8B-FF836EB58AB8/Documents/icon20140913003532.png
気になったので、前回描いたコードで取得されるパスを確認してみる。前回のコードはコレ。
NSArray *phrases = [imageName componentsSeparatedByString:@".png"];
NSString *filename = [phrases objectAtIndex:0];
NSString *path= [[NSBundle mainBundle] pathForResource:filename ofType:@"png"];
//アプリ内保存した直後の画像は、path が nullになる
NSLog(@"path >> %@",path);
//保存直後の画像はNSBundleでパスが取れないための対処(アプリが再起動しないとダメみたい)
UIImage *iconImage;
if (path == NULL) {
iconImage = [UIImage imageNamed:imageName];
} else {
iconImage = [[UIImage alloc] initWithContentsOfFile:path];
}
※ imageNameには、”../Documents/icon20140912171442.png”のようなパスが入っている。
アプリ起動前に保存されている画像について、NSLogで表示されるパスを見ると・・・
path >> /var/mobile/Applications/BB4E2366-816D-427F-8F8B-FF836EB58AB8/xxxxxx.app/../Documents/icon20140913003017.png
と、アプリ名(xxxxxx.app/../)がはさまってる。この違いは何?NSBundleだとこうなるの?
更に、冒頭の修正コードをアプリ名(xxxxxx.app/../)がはさまってるパスに変更して参照してみる。
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory,
NSUserDomainMask, YES);
NSArray *ph = [select_name componentsSeparatedByString:@"/"];
NSString *fn = [ph objectAtIndex:ph.count-1];
NSLog(@"paths >> %@",paths);
NSLog(@"fn >> %@",fn);
NSArray *paths2 = [[paths objectAtIndex:0] componentsSeparatedByString:@"Documents"];
path = [NSString stringWithFormat:@"%@iconFaceCam.app/%@",[paths2 objectAtIndex:0],select_name];
NSLog(@"path >> %@",path);
iconImage = [[UIImage alloc] initWithContentsOfFile:path];
NSLogの出力結果がこれ。
paths >> (
"/var/mobile/Applications/BB4E2366-816D-427F-8F8B-FF836EB58AB8/Documents"
)
fn >> icon20140913012801.png
path >> /var/mobile/Applications/BB4E2366-816D-427F-8F8B-FF836EB58AB8/xxxxxx.app/../Documents/icon20140913012801.png
動作としては、こちらでも問題なく動きました。
で、結論としては、アプリ内保存のファイル参照では・・・
・NSSearchPathForDirectoriesInDomainsでドキュメントディレクトリを取得する。
・ドキュメントディレクトリ+ファイル名でパスを生成する。
・生成したパスを使って、initWithContentsOfFileで参照する。
ということになるんだけれど、そもそも何で・・・
[[NSBundle mainBundle] pathForResource:filename ofType:@”png”]
でパスが取得できないのか、がわからずモヤモヤします…。
とりあえずは余計なifとか要らなくなったので、よしとして先に進みます。
JBOYSOFT JunjiSuzukiさんに感謝。