web-dev-qa-db-ja.com

Swiftのアプリバンドルに含まれるファイルにアクセスするにはどうすればよいですか?

これに関連する質問がいくつかありますが、それらはObjective-Cにあります。

Swift 実際のiPhoneで?を使用して、アプリに含まれる.txtファイルにアクセスするにはどうすればよいですか?読み書きできます。 こちら ご覧になりたいプロジェクトファイルです。必要に応じて詳細を追加させていただきます。

24
atirit

リソースのアプリバンドルを検索するだけで

var filePath = NSBundle.mainBundle().URLForResource("file", withExtension: "txt")

ただし、アプリのリソースディレクトリにあり、ドキュメントディレクトリに作成して書き込む必要があるため、書き込みはできません。

var documentsDirectory: NSURL?
var fileURL: NSURL?

documentsDirectory = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).last!
fileURL = documentsDirectory!.URLByAppendingPathComponent("file.txt")

if (fileURL!.checkResourceIsReachableAndReturnError(nil)) {
    print("file exist")
}else{
    print("file doesnt exist")
    NSData().writeToURL(fileURL!,atomically:true)
}

これでfileURLからアクセスできます

編集-2018年8月28日

これはSwift 4.2でそれを行う方法です

var filePath = Bundle.main.url(forResource: "file", withExtension: "txt")

ドキュメントディレクトリに作成するには

if let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last {
   let fileURL = documentsDirectory.appendingPathComponent("file.txt")
   do {
       if try fileURL.checkResourceIsReachable() {
           print("file exist")
       } else {
           print("file doesnt exist")
           do {
            try Data().write(to: fileURL)
           } catch {
               print("an error happened while creating the file")
           }
       }
   } catch {
       print("an error happened while checking for the file")
   }
}
35
Karim H

Swift 3カリムの答え に基づいています。

読書

バンドルのリソースを使用して、アプリのバンドルに含まれるファイルを読むことができます。

let fileURL = Bundle.main.url(forResource:"filename", withExtension: "txt")

書き込み

ただし、そこに書くことはできません。できればDocumentsディレクトリにコピーを作成する必要があります。

func makeWritableCopy(named destFileName: String, ofResourceFile originalFileName: String) throws -> URL {
    // Get Documents directory in app bundle
    guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last else {
        fatalError("No document directory found in application bundle.")
    }

    // Get URL for dest file (in Documents directory)
    let writableFileURL = documentsDirectory.appendingPathComponent(destFileName)

    // If dest file doesn’t exist yet
    if (try? writableFileURL.checkResourceIsReachable()) == nil {
        // Get original (unwritable) file’s URL
        guard let originalFileURL = Bundle.main.url(forResource: originalFileName, withExtension: nil) else {
            fatalError("Cannot find original file “\(originalFileName)” in application bundle’s resources.")
        }

        // Get original file’s contents
        let originalContents = try Data(contentsOf: originalFileURL)

        // Write original file’s contents to dest file
        try originalContents.write(to: writableFileURL, options: .atomic)
        print("Made a writable copy of file “\(originalFileName)” in “\(documentsDirectory)\\\(destFileName)”.")

    } else { // Dest file already exists
        // Print dest file contents
        let contents = try String(contentsOf: writableFileURL, encoding: String.Encoding.utf8)
        print("File “\(destFileName)” already exists in “\(documentsDirectory)”.\nContents:\n\(contents)")
    }

    // Return dest file URL
    return writableFileURL
}

使用例:

let stuffFileURL = try makeWritableCopy(named: "Stuff.txt", ofResourceFile: "Stuff.txt")
try "New contents".write(to: stuffFileURL, atomically: true, encoding: String.Encoding.utf8)
14

Swift 4:でこのコードを使用するための簡単な更新

Bundle.main.url(forResource:"YourFile", withExtension: "FileExtension")

また、ファイルを書き出すために、以下が更新されました。

var myData: Data!

func checkFile() {
    if let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last {
        let fileURL = documentsDirectory.appendingPathComponent("YourFile.extension")
        do {
            let fileExists = try fileURL.checkResourceIsReachable()
            if fileExists {
                print("File exists")
            } else {
                print("File does not exist, create it")
                writeFile(fileURL: fileURL)
            }
        } catch {
            print(error.localizedDescription)
        }
    }
}

func writeFile(fileURL: URL) {
    do {
        try myData.write(to: fileURL)
    } catch {
        print(error.localizedDescription)
    }
}

この特定の例は最も柔軟ではありませんが、少しの作業を行うだけで、独自のファイル名、拡張子、およびデータ値を簡単に渡すことができます。

11
CodeBender

バンドルは読み取り専用です。 NSBundle.mainBundle().pathForResourceを使用して読み取り専用としてファイルにアクセスできますが、読み取り/書き込みアクセスの場合は、ドキュメントをDocumentsフォルダーまたはtmpフォルダーにコピーする必要があります。

2
MirekE

バンドルを書くことができます。 Bundle.main.pathを使用して、ファイルをCopy Bundles Resourceに追加して上書きできます。

Project -> Target -> Build Pharse -> Copy Bundles Resource

0
T.Nhan