2016-06-01 53 views
9

So che ci sono alcune domande relative a questo, ma sono in Objective-C.Come accedere al file incluso nel pacchetto di app in Swift?

Come accedere a un file .txt incluso nella mia app utilizzando Swift su un iPhone effettivo? Voglio essere in grado di leggere e scrivere da esso. Here sono i miei file di progetto se si vuole dare un'occhiata. Sono felice di aggiungere dettagli se necessario.

+1

"Voglio poter leggere e scrivere da esso." Non puoi. Se installato su un dispositivo, il pacchetto dell'app è ** di sola lettura **. Puoi leggere un file nel pacchetto di app ma non puoi scriverci sopra. –

risposta

12

Semplicemente effettuando una ricerca nel pacchetto app per la risorsa

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

Tuttavia non è possibile scrivere ad esso, perché è nella directory di risorse app ed è necessario creare nella directory del documento di scrivere a si

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

ora è possibile accedervi da fileURL

+0

Con "it" si intende il file scrivibile copiato nella directory del documento? – atirit

+0

"ora puoi accedervi da fileURL" significa che il file creato non è incluso ed è scrivibile – Karim

+0

il file non viene copiato è un nuovo file vuoto – Karim

1

pacchi sono di sola lettura. È possibile utilizzare NSBundle.mainBundle().pathForResource per accedere al file in sola lettura, ma per l'accesso in lettura-scrittura è necessario copiare il documento nella cartella Documenti o nella cartella tmp.

8

Swift 3, basato su Karim’s answer.

lettura

È possibile leggere i file inclusi nel pacchetto di un'applicazione attraverso risorse del bundle:

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

scrittura

Tuttavia, non si può scrivere lì. Sarà necessario creare una copia, preferibilmente nella directory Documenti: utilizzo

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 
} 

Esempio:

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

Solo un rapido aggiornamento per utilizzare questo codice con Swift 4:

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

E quanto segue è stato aggiornato per tener conto della scrittura del file:

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

Questo particolare esempio non è il più flessibile, ma con un po 'di lavoro è possibile passare facilmente nei propri nomi di file, estensioni e valori dei dati.

Problemi correlati