iPhone/iPad の実機やシミュレータのアプリケーションフォルダの中身を見る

Xcode でプロジェクトに追加したファイルの置かれている場所を調べようとして、副産物的にできたものをメモ的に置いてみる。アプリ自体は NSFileManager を使えば簡単にできる。ホームディレクトリの取得は NSHomeDirectory() でできるが、アプリケーションのフォルダ (.app) 自体は NSHomeDirectory とかを使って自力で指定しないとダメぽい? NSSearchPathForDirectoriesInDomainsで NSApplicationDirectory を指定すると ~/Applications が取れるようだし。

IB は使わず、Empty アプリに UITableViewController のサブクラスとして DataView クラスを追加して作っている。ARC は on にしてある。off にするなら table.path に NSString を代入するときに retain しないとアプリがエラーで止まる(多分).

  • AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    DataView *table = [[DataView alloc] initWithStyle: UITableViewStylePlain];
 
    // ホームディレクトリを取得して root になる DataView にセットしている                 
    table.path = [NSString stringWithFormat: @"%@", NSHomeDirectory()];
    
    UINavigationController *n = [[UINavigationController alloc] initWithRootViewController:table];
    
    [self.window setRootViewController: n];
    
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}
  • DataView.h
@interface DataView : UITableViewController
{
    // ディレクトリのファイル一覧を入れる配列
    NSArray *array;

    // 参照するディレクトリのパス
    NSString* path;
}

@property (strong) NSString* path;
@end
  • DataView.m

変更したメソッドのみ。

- (void)viewDidLoad
{
    [super viewDidLoad];

    // カレントのファイル一覧を取りだす。    
    array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
    [self.navigationItem setTitle:[NSString stringWithFormat:@"%d items", array.count]];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return array.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    cell.textLabel.text = [array objectAtIndex:indexPath.row];

    // ディレクトリかどうかを調べ、ディレクトリだったら→アイコンをつける。    
    NSString* newpath = [NSString stringWithFormat:@"%@/%@",
                         path, [array objectAtIndex: indexPath.row]];
    BOOL result = NO;
    [[NSFileManager defaultManager] fileExistsAtPath:newpath isDirectory: &result];
    if ( result == YES )
    {
        cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
    }else{
        // ディレクトリではないときは none を指定する。これを明示的にやらないと
        // cell が再利用されたときに表示がおかしくなる。
        cell.accessoryType = UITableViewCellAccessoryNone;
    }
    
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // ディレクトリだったら新しい DataView を作って遷移させる
    NSString* newpath = [NSString stringWithFormat:@"%@/%@",
                         path, [array objectAtIndex: indexPath.row]];
    BOOL result = NO;
    [[NSFileManager defaultManager] fileExistsAtPath:newpath isDirectory: &result];

    if ( result == YES )
    {
    
        DataView *table = [[DataView alloc] initWithStyle: UITableViewStylePlain];
        table.path = newpath;
        //NSLog(@"%@", table.path);

        [self.navigationController pushViewController:table animated: YES ];
    }
}