わたしの日記だよ

ー生きる厳しさと哀しさを鮮烈に謳うー

Xcode6+swift アプリのディレクトリ構成とディレクトリパスの取得

アプリに同梱した画像のzipファイルを、初回起動時に解凍する処理を作っています。

iOSのときは、同梱するファイルや解凍したファイル、どこに置くんだっけ?と思ったので調べてみました。

ついでに、各ディレクトリパスの取得方法も。

 

1.ディレクトリ構成について

いきなり、わかりやすいまとめがありました。

参考:今こそ復習したい、iOSアプリのディレクトリ構成 - Qiita

・zipファイル・・・MyApp.app/(普通の画像と同じ扱い)

・解凍したファイル・・・Library/

に置けば良さそうです。

 

2.各ディレクトリパス取得方法

主なディレクトリパスの取得方法は、MyApp.app/、tmp/、その他のディレクトリ

で分かれています。

 

①MyApp.app/

NSHomeDirectory()

 

②tmp/

NSTemporaryDirectory()

 

③その他は、NSSearchPathForDirectoriesInDomains() メソッドか、NSFileManagerクラスの

URLsForDirectory() または URLForDirectory()メソッドで取得します。

NSFileManagerのほうを検討するように、とあったので、今回はそちらを使用します。

参考:Foundation Functions Reference

URLsForDirectory(directory:NSSearchPathDirectory, 
inDomains domainMask:NSSearchPathDomainMask) -> [AnyObject]

URLForDirectory(directory:NSSearchPathDirectory,
inDomain domain:NSSeatchPathDomainMask,
appropriateForURL url:NSURL?,
create shouldCreate:Bool,
error error:NSErrorPointer) -> NSURL?

 

パラメータ名役割
directory検索したいディレクトリ。NSSearchPathDirectoryを使って指定。
domain検索したい場所。NSSearchPathDomainMaskを使って指定。
urldirectoryにNSItemReplacementDirectory、domainにNSUserDomainMaskが指定されているとき以外は、無視される何か。(わたしの理解力の限界)
shouldCreateディレクトリが存在しなかった場合、作成するかどうか。trueで作成する。
errorエラー情報用のポインタ

 

どちらのメソッドもだいたい一緒ですが

・URLsForDirectoryは戻りが配列になっていること

・URLForDirectoryのほうは、戻りがひとつなので、複数の場所を指定するdomain(NSAllDomainMask)は使えないこと

がポイントかなと思います。

 

使い方は、こんな感じ。

        // MyApp.app/
        let homeDir = NSHomeDirectory()
        println("homeDir: \(homeDir)")
        
        // tmp/
        let tmpDir = NSTemporaryDirectory()
        println("tmpDir: \(tmpDir)")
        
        // NSFileManager取得
        var mgr = NSFileManager.defaultManager()
        
        // Documents/
        let documentDir:AnyObject = mgr.URLsForDirectory(.DocumentDirectory,
            inDomains: .UserDomainMask)[0]
        println("documentDir: \(documentDir)")
        
        // Library/ ディレクトリがなかったら作成する、エラー情報は使用しない
        let libraryDir = mgr.URLForDirectory(.LibraryDirectory,
            inDomain: .UserDomainMask,
            appropriateForURL: nil,
            create: true,
            error: nil)
        println("libraryDir: \(libraryDir)")
        
        // Library/Caches ディレクトリがなかったら作成しない、エラー情報を使用する
        var error:NSError?
        let cachesDir = mgr.URLForDirectory(.CachesDirectory,
            inDomain: .UserDomainMask,
            appropriateForURL: nil,
            create: false,
            error: &error)
        println("cachesDir: \(cachesDir)")
        
        if (error != nil) {
            println("error: \(error)")
        }

 

そして、実行結果はこんな感じでした。

homeDir: /Users/[user name]/Library/Developer/CoreSimulator/Devices/[device ID]/data/Containers/Data/Application/[App ID]
tmpDir: /Users/[user name]/Library/Developer/CoreSimulator/Devices/[device ID]/data/Containers/Data/Application/[App ID]/tmp/
documentDir: [file:///Users/[user name]/Library/Developer/CoreSimulator/Devices/[device ID]/data/Containers/Data/Application/[App ID]/Documents/]
libraryDir: Optional(file:///Users/[user name]/Library/Developer/CoreSimulator/Devices/[device ID]/data/Containers/Data/Application/[App ID]/Library/)
cachesDir: Optional(file:///Users/[user name]/Library/Developer/CoreSimulator/Devices/[device ID]/data/Containers/Data/Application/[App ID]/Library/Caches/)

 

NSSearchPathDirectoryの値は、上記以外にもPicturesDirectory(~/Pictures)とか

使いそうなものがたくさんありました。

やっぱり、Reference読むのが一番ですね。