web-dev-qa-db-fra.com

Comment accéder au fichier inclus dans le paquet d'applications dans Swift?

Je sais qu'il y a quelques questions à ce sujet, mais elles sont dans Objective-C.

Comment puis-je accéder à un fichier .txt inclus dans mon application à l'aide de Swift sur un iPhone réel? Je veux pouvoir lire et écrire à partir de cela. Ici sont mes fichiers de projet si vous voulez jeter un oeil. Je suis heureux d'ajouter des détails si nécessaire.

16
atirit

Simplement en recherchant la ressource dans le bundle d'applications

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

Cependant, vous ne pouvez pas y écrire car il se trouve dans le répertoire des ressources de l'application et vous devez le créer dans le répertoire du document pour y écrire.

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)
}

maintenant vous pouvez y accéder depuis fileURL

EDIT - 28 août 2018

Voici comment procéder dans Swift 4.2

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

Pour le créer dans le répertoire du document

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")
   }
}
30
Karim H

Swift 3, basé sur Réponse de Karim .

En train de lire

Vous pouvez lire les fichiers inclus dans l’offre de l’application via sa ressource:

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

L'écriture

Cependant, vous ne pouvez pas y écrire. Vous devrez en créer une copie, de préférence dans le répertoire 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
}

Exemple d'utilisation:

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

Juste une mise à jour rapide pour utiliser ce code avec Swift 4:

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

Et ce qui suit a été mis à jour pour tenir compte de l'écriture du fichier:

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)
    }
}

Cet exemple particulier n’est pas le plus flexible, mais avec un peu de travail, vous pouvez facilement transmettre vos propres noms de fichiers, extensions et valeurs de données.

8
CodeBender

Les paquets sont en lecture seule. Vous pouvez utiliser NSBundle.mainBundle().pathForResource pour accéder au fichier en lecture seule, mais pour un accès en lecture-écriture, vous devez copier votre document dans le dossier Documents ou le dossier tmp.

1
MirekE