Leer y escribir una cadena desde un archivo de texto

298

Necesito leer y escribir datos en / desde un archivo de texto, pero no he podido averiguar cómo.

Encontré este código de muestra en el iBook de Swift, pero todavía no sé cómo escribir o leer datos.

import Cocoa

class DataImporter
{
    /*
    DataImporter is a class to import data from an external file.
    The class is assumed to take a non-trivial amount of time to initialize.
    */
    var fileName = "data.txt"
    // the DataImporter class would provide data importing functionality here
}

class DataManager
{
    @lazy var importer = DataImporter()
    var data = String[]()
    // the DataManager class would provide data management functionality here
}

let manager = DataManager()
manager.data += "Some data"
manager.data += "Some more data"
// the DataImporter instance for the importer property has not yet been created”

println(manager.importer.fileName)
// the DataImporter instance for the importer property has now been created
// prints "data.txt”



var str = "Hello World in Swift Language."
Jorge Vega Sánchez
fuente

Respuestas:

548

Para leer y escribir, debe usar una ubicación que se pueda escribir, por ejemplo, el directorio de documentos. El siguiente código muestra cómo leer y escribir una cadena simple. Puedes probarlo en un patio de recreo.

Swift 3.x - 5.x

let file = "file.txt" //this is the file. we will write to and read from it

let text = "some text" //just a text

if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {

    let fileURL = dir.appendingPathComponent(file)

    //writing
    do {
        try text.write(to: fileURL, atomically: false, encoding: .utf8)
    }
    catch {/* error handling here */}

    //reading
    do {
        let text2 = try String(contentsOf: fileURL, encoding: .utf8)
    }
    catch {/* error handling here */}
}

Swift 2.2

let file = "file.txt" //this is the file. we will write to and read from it

let text = "some text" //just a text

if let dir = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true).first {
    let path = NSURL(fileURLWithPath: dir).URLByAppendingPathComponent(file)

    //writing
    do {
        try text.writeToURL(path, atomically: false, encoding: NSUTF8StringEncoding)
    }
    catch {/* error handling here */}

    //reading
    do {
        let text2 = try NSString(contentsOfURL: path, encoding: NSUTF8StringEncoding)
    }
    catch {/* error handling here */}
}

Swift 1.x

let file = "file.txt"

if let dirs : [String] = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true) as? [String] {
    let dir = dirs[0] //documents directory
    let path = dir.stringByAppendingPathComponent(file);
    let text = "some text"

    //writing
    text.writeToFile(path, atomically: false, encoding: NSUTF8StringEncoding, error: nil);

    //reading
    let text2 = String(contentsOfFile: path, encoding: NSUTF8StringEncoding, error: nil)
}
Adán
fuente
2
let text2 = String.stringWithContentsOfFile (ruta) // XCode 6.0
Matt Frear
Usar esta solución funciona, pero si abro el archivo no hay texto. ¿Me estoy perdiendo algo?
Nuno Gonçalves
@ Adam ¿Qué es este archivo en let path = dir.stringByAppendingPathComponent (file) ;?
zbz.lvlv
77
Esto debe eliminarse, el código no funciona para las nuevas versiones de Swift.
1
@ billy_b29 El código después de esta línea: //readinghace exactamente eso.
Adam
88

Suponiendo que ha movido su archivo de texto data.txta su proyecto Xcode (use arrastrar y soltar y marque "Copiar archivos si es necesario") puede hacer lo siguiente al igual que en Objective-C:

let bundle = NSBundle.mainBundle()
let path = bundle.pathForResource("data", ofType: "txt")        
let content = NSString.stringWithContentsOfFile(path) as String

println(content) // prints the content of data.txt

Actualización:
para leer un archivo de Bundle (iOS) puede usar:

let path = NSBundle.mainBundle().pathForResource("FileName", ofType: "txt")
var text = String(contentsOfFile: path!, encoding: NSUTF8StringEncoding, error: nil)!
println(text)

Actualización para Swift 3:

let path = Bundle.main.path(forResource: "data", ofType: "txt") // file path for file "data.txt"
var text = String(contentsOfFile: path!, encoding: NSUTF8StringEncoding, error: nil)!

Para Swift 5

let path = Bundle.main.path(forResource: "ListAlertJson", ofType: "txt") // file path for file "data.txt"
let string = try String(contentsOfFile: path!, encoding: String.Encoding.utf8)
wottpal
fuente
3
Para proyectos de iOS, "stringWithContentsOfFile" no está disponible (en desuso desde iOS 7)
alttag
1
Nada que ver con los proyectos de iOS, está en desuso y ya no funciona con Xcode 6.1 (incluido Mac OS X)
Leo Dabus
1
puede utilizar cuerdas (contentsOfFile: ...)
cuña
1
paquete de solución similar con iOS 10 Swift 3 aquí
Timeless
69

Xcode 8.x • Swift 3.xo posterior

do {
    // get the documents folder url
    if let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
        // create the destination url for the text file to be saved
        let fileURL = documentDirectory.appendingPathComponent("file.txt")
        // define the string/text to be saved
        let text = "Hello World !!!"
        // writing to disk 
        // Note: if you set atomically to true it will overwrite the file if it exists without a warning
        try text.write(to: fileURL, atomically: false, encoding: .utf8)
        print("saving was successful")
        // any posterior code goes here
        // reading from disk
        let savedText = try String(contentsOf: fileURL)
        print("savedText:", savedText)   // "Hello World !!!\n"
    }
} catch {
    print("error:", error)
}
Leo Dabus
fuente
¿Cuáles son los errores más comunes de "No existe tal archivo"? Como agregué mis archivos .txt al navegador de proyectos y luego trato de abrirlos, recibo este mensaje. (Créelos en el escritorio y arrástrelos al navegador de proyectos)
Darvydas
56

Nuevo método más simple y recomendado: Apple recomienda usar URL para el manejo de archivos y las otras soluciones aquí parecen obsoletas (ver comentarios a continuación). La siguiente es la nueva forma simple de leer y escribir con URL (no olvide manejar los posibles errores de URL):

Swift 5+, 4 y 3.1

import Foundation  // Needed for those pasting into Playground

let fileName = "Test"
let dir = try? FileManager.default.url(for: .documentDirectory, 
      in: .userDomainMask, appropriateFor: nil, create: true)

// If the directory was found, we write a file to it and read it back
if let fileURL = dir?.appendingPathComponent(fileName).appendingPathExtension("txt") {

    // Write to the file named Test
    let outString = "Write this text to the file"
    do {
        try outString.write(to: fileURL, atomically: true, encoding: .utf8)
    } catch {
        print("Failed writing to URL: \(fileURL), Error: " + error.localizedDescription)
    }

    // Then reading it back from the file
    var inString = ""
    do {
        inString = try String(contentsOf: fileURL)
    } catch {
        print("Failed reading from URL: \(fileURL), Error: " + error.localizedDescription)
    }
    print("Read from the file: \(inString)")
}
Sverrisson
fuente
1
¿Puede proporcionar una referencia donde Apple lo recomiende? ¿O puede explicar un poco más por qué es esta la forma recomendada?
Andrej
66
@Andrej "Los objetos URL son la forma preferida de referirse a archivos locales. La mayoría de los objetos que leen o escriben datos en un archivo tienen métodos que aceptan un objeto NSURL en lugar de una ruta como referencia de archivo". developer.apple.com/library/ios/documentation/Cocoa/Reference/…
Sverrisson
1
No tiene que emitir los errores como NSError, o incluso usar "catch let error". Simplemente puede hacer catch y obtener la variable de error de forma gratuita.
cuomo456
@ cuomo456 a la derecha lo elimino, es un resto de la versión anterior de Swift beta.
Sverrisson
1
@Alshcompiler Create: true informa a FileManager para crear el directorio si aún no está allí, en lugar de fallar
Sverrisson
28

Xcode 8, Swift 3 forma de leer el archivo del paquete de la aplicación:

if let path = Bundle.main.path(forResource: filename, ofType: nil) {
    do {
        let text = try String(contentsOfFile: path, encoding: String.Encoding.utf8)
        print(text)
    } catch {
        printError("Failed to read text from \(filename)")
    }
} else {
    printError("Failed to load file from app bundle \(filename)")
} 

Aquí hay una conveniente extensión para copiar y pegar

public extension String {
    func contentsOrBlank()->String {
        if let path = Bundle.main.path(forResource:self , ofType: nil) {
            do {
                let text = try String(contentsOfFile:path, encoding: String.Encoding.utf8)
                return text
                } catch { print("Failed to read text from bundle file \(self)") }
        } else { print("Failed to load file from bundle \(self)") }
        return ""
    }
    }

Por ejemplo

let t = "yourFile.txt".contentsOrBlank()

Casi siempre quieres una serie de líneas:

let r:[String] = "yourFile.txt"
     .contentsOrBlank()
     .characters
     .split(separator: "\n", omittingEmptySubsequences:ignore)
     .map(String.init)
Crashalot
fuente
2
Pegué en una práctica extensión @crashalot - siéntete libre de borrar, saludos
Fattie
1
@Alshcompiler ¡NO! No puede ESCRIBIR un archivo en el paquete.
Sverrisson
Estaba hablando de leer del archivo, es la única respuesta que funcionó conmigo si el archivo está en los archivos del proyecto
compilador Alsh
10

Quiero mostrarte solo la primera parte, que se lee . Así de simple puedes leer:

Swift 3:

let s = try String(contentsOfFile: Bundle.main.path(forResource: "myFile", ofType: "txt")!)

Swift 2:

let s = try! String(contentsOfFile: NSBundle.mainBundle().pathForResource("myFile", ofType: "txt")!)
AKM Tariqul Islam
fuente
5

La forma más sencilla de leer un archivo en Swift> 4.0

 let path = Bundle.main.path(forResource: "data", ofType: "txt") // file path for file "data.txt"
        do {
            var text = try String(contentsOfFile: path!)
        }
        catch(_){print("error")}
    }
ios mentalista
fuente
3

La respuesta actual aceptada anteriormente de Adam tenía algunos errores para mí, pero así es como modifiqué su respuesta e hice que esto funcionara para mí.

let file = "file.txt"

let dirs: [String]? = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true) as? [String]

if (dirs != nil) {
    let directories:[String] = dirs!
    let dirs = directories[0]; //documents directory
    let path = dirs.stringByAppendingPathComponent(file);
    let text = "some text"

    //writing
    text.writeToFile(path, atomically: false, encoding: NSUTF8StringEncoding, error: nil);

    //reading
     var error:NSError?

    //reading
    let text2 = String(contentsOfFile: path, encoding:NSUTF8StringEncoding, error: &error)

    if let theError = error {
        print("\(theError.localizedDescription)")
    }
}
DCorrigan
fuente
3

Puede encontrar esta herramienta útil no solo para leer del archivo en Swift sino también para analizar su entrada: https://github.com/shoumikhin/StreamScanner

Simplemente especifique la ruta del archivo y los delimitadores de datos de esta manera:

import StreamScanner

if let input = NSFileHandle(forReadingAtPath: "/file/path")
{
    let scanner = StreamScanner(source: input, delimiters: NSCharacterSet(charactersInString: ":\n"))  //separate data by colons and newlines

    while let field: String = scanner.read()
    {
        //use field
    }
}

Espero que esto ayude.

shoumikhin
fuente
2

Tuve que recodificar así:

let path = NSBundle.mainBundle().pathForResource("Output_5", ofType: "xml")
let text = try? NSString(contentsOfFile: path! as String, encoding: NSUTF8StringEncoding)
print(text)
Nagarjun
fuente
2

En el ejemplo de función, (leer | escribir) DocumentsFromFile (...) tener algunos envoltorios de funciones ciertamente parece tener sentido ya que todo en OSx e iOS parece necesitar tres o cuatro clases principales instanciadas y un montón de propiedades, configuradas, vinculadas, instanciado y configurado, solo para escribir "Hola" a un archivo, en 182 países.

Sin embargo, estos ejemplos no son lo suficientemente completos como para usarlos en un programa real. La función de escritura no informa ningún error al crear o escribir en el archivo. En la lectura, no creo que sea una buena idea devolver un error de que el archivo no existe como la cadena que se supone que contiene los datos que se leyeron. Desearía saber que falló y por qué, a través de algún mecanismo de notificación, como una excepción. Luego, puede escribir un código que muestre cuál es el problema y permite que el usuario lo corrija, o "correctamente" interrumpe el programa en ese punto.

No querrá devolver una cadena con el mensaje "El archivo de error no existe". Entonces, tendría que buscar el error en la cadena de la función de llamada cada vez y manejarlo allí. Posiblemente, tampoco podría saber realmente si la cadena de error se leyó realmente de un archivo real, o si se produjo a partir de su código.

Ni siquiera puede llamar a la lectura de esta manera en swift 2.2 y Xcode 7.3 porque NSString (contentsOfFile ...) arroja una excepción. Es un error de tiempo de compilación si no tiene ningún código para atraparlo y hacer algo con él, como imprimirlo en stdout, o mejor, una ventana emergente de error o stderr. He oído que Apple se está alejando del intento de captura y excepciones, pero va a ser un movimiento largo y no es posible escribir código sin esto. No sé de dónde viene el argumento & error, quizás una versión anterior, pero NSString.writeTo [File | URL] actualmente no tiene un argumento NSError. Se definen así en NSString.h:

public func writeToURL(url: NSURL, atomically useAuxiliaryFile: Bool, encoding enc: UInt) throws
public func writeToFile(path: String, atomically useAuxiliaryFile: Bool, encoding enc: UInt) throws
public convenience init(contentsOfURL url: NSURL, encoding enc: UInt) throws
public convenience init(contentsOfFile path: String, encoding enc: UInt) throws

Además, el archivo que no existe es solo uno de una serie de problemas potenciales que su programa podría tener al leer un archivo, como un problema de permisos, el tamaño del archivo u otros muchos problemas para los que ni siquiera querría intentar codificar un controlador cada uno de ellos. Es mejor asumir que todo está correcto y atrapar e imprimir, o manejar, una excepción si algo sale mal, además, en este punto, en realidad no tiene otra opción.

Aquí están mis reescrituras:

func writeToDocumentsFile(fileName:String,value:String) {

    let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString!
    let path = documentsPath.stringByAppendingPathComponent(fileName)

    do {
        try value.writeToFile(path, atomically: true, encoding: NSUTF8StringEncoding)
    } catch let error as NSError {
        print("ERROR : writing to file \(path) : \(error.localizedDescription)")
    }

}

func readFromDocumentsFile(fileName:String) -> String {

    let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
    let path = documentsPath.stringByAppendingPathComponent(fileName)

    var readText : String = ""

    do {
        try readText = NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding) as String
    }
    catch let error as NSError {
        print("ERROR : reading from file \(fileName) : \(error.localizedDescription)")
    }
    return readText
}
Sam Allen
fuente
En muchas de sus respuestas, creo que no está entendiendo mi punto. (o puede que no te importe y eso está bien). Sin embargo, para ser claros, lanzar una excepción y manejarlo de alguna manera cuando está buscando un archivo que no está allí (o tiene otro problema, como un permiso) es mucho mejor que devolver una cadena como "ERROR: Archivo [nombre de archivo] no existe "como la cadena que se suponía que debía leer realmente del archivo. Entonces solo imprime eso. Si debe imprimir los detalles de la excepción, no la cadena que no se pudo leer que ahora tiene un error, es probable que el programa no solo continúe.
Sam Allen
2

Para mi archivo txt funciona de esta manera:

let myFileURL = NSBundle.mainBundle().URLForResource("listacomuni", withExtension: "txt")!
let myText = try! String(contentsOfURL: myFileURL, encoding: NSISOLatin1StringEncoding)
print(String(myText))
Alessandro Mattiuzzi
fuente
2

Para evitar confusiones y agregar facilidad, he creado dos funciones para leer y escribir cadenas en archivos en el directorio de documentos. Aquí están las funciones:

func writeToDocumentsFile(fileName:String,value:String) {
    let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! NSString
    let path = documentsPath.stringByAppendingPathComponent(fileName)
    var error:NSError?
    value.writeToFile(path, atomically: true, encoding: NSUTF8StringEncoding, error: &error)
}

func readFromDocumentsFile(fileName:String) -> String {
    let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! NSString
    let path = documentsPath.stringByAppendingPathComponent(fileName)
    var checkValidation = NSFileManager.defaultManager()
    var error:NSError?
    var file:String

    if checkValidation.fileExistsAtPath(path) {
        file = NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding, error: nil) as! String
    } else {
        file = "*ERROR* \(fileName) does not exist."
    }

    return file
}

Aquí hay un ejemplo de su uso:

writeToDocumentsFile("MyText.txt","Hello world!")

let value = readFromDocumentsFile("MyText.txt")
println(value)  //Would output 'Hello world!'

let otherValue = readFromDocumentsFile("SomeText.txt")
println(otherValue)  //Would output '*ERROR* SomeText.txt does not exist.'

¡Espero que esto ayude!

Versión de Xcode: 6.3.2

gooroo7
fuente
2

Último código swift3
Puede leer datos del archivo de texto solo use el siguiente código Este es mi archivo de texto

     {
"NumberOfSlices": "8",
"NrScenes": "5",
"Scenes": [{
           "dataType": "label1",
           "image":"http://is3.mzstatic.com/image/thumb/Purple19/v4/6e/81/31/6e8131cf-2092-3cd3-534c-28e129897ca9/mzl.syvaewyp.png/53x53bb-85.png",

           "value": "Hello",
           "color": "(UIColor.red)"
           }, {
           "dataType": "label2",
           "image":"http://is1.mzstatic.com/image/thumb/Purple71/v4/6c/4c/c1/6c4cc1bc-8f94-7b13-f3aa-84c41443caf3/mzl.hcqvmrix.png/53x53bb-85.png",
           "value": "Hi There",
           "color": "(UIColor.blue)"
           }, {
           "dataType": "label3",
           "image":"http://is1.mzstatic.com/image/thumb/Purple71/v4/6c/4c/c1/6c4cc1bc-8f94-7b13-f3aa-84c41443caf3/mzl.hcqvmrix.png/53x53bb-85.png",

           "value": "hi how r u ",
           "color": "(UIColor.green)"
           }, {
           "dataType": "label4",
           "image":"http://is1.mzstatic.com/image/thumb/Purple71/v4/6c/4c/c1/6c4cc1bc-8f94-7b13-f3aa-84c41443caf3/mzl.hcqvmrix.png/53x53bb-85.png",
           "value": "what are u doing  ",
           "color": "(UIColor.purple)"
           }, {
           "dataType": "label5",
          "image":"http://is1.mzstatic.com/image/thumb/Purple71/v4/6c/4c/c1/6c4cc1bc-8f94-7b13-f3aa-84c41443caf3/mzl.hcqvmrix.png/53x53bb-85.png",
           "value": "how many times ",
           "color": "(UIColor.white)"
           }, {
           "dataType": "label6",
           "image":"http://is1.mzstatic.com/image/thumb/Purple71/v4/5a/f3/06/5af306b0-7cac-1808-f440-bab7a0d18ec0/mzl.towjvmpm.png/53x53bb-85.png",
           "value": "hi how r u ",
           "color": "(UIColor.blue)"
           }, {
           "dataType": "label7",
           "image":"http://is5.mzstatic.com/image/thumb/Purple71/v4/a8/dc/eb/a8dceb29-6daf-ca0f-d037-df9f34cdc476/mzl.ukhhsxik.png/53x53bb-85.png",
           "value": "hi how r u ",
           "color": "(UIColor.gry)"
           }, {
           "dataType": "label8",
           "image":"http://is2.mzstatic.com/image/thumb/Purple71/v4/15/23/e0/1523e03c-fff2-291e-80a7-73f35d45c7e5/mzl.zejcvahm.png/53x53bb-85.png",
           "value": "hi how r u ",
           "color": "(UIColor.brown)"
           }]

}

Puede usar este código para obtener datos del archivo json de texto en swift3

     let filePath = Bundle.main.path(forResource: "nameoftheyourjsonTextfile", ofType: "json")


    let contentData = FileManager.default.contents(atPath: filePath!)
    let content = NSString(data: contentData!, encoding: String.Encoding.utf8.rawValue) as? String

    print(content)
    let json = try! JSONSerialization.jsonObject(with: contentData!) as! NSDictionary
    print(json)
    let app = json.object(forKey: "Scenes") as! NSArray!
    let _ : NSDictionary
    for dict in app! {
        let colorNam = (dict as AnyObject).object(forKey: "color") as! String
        print("colors are \(colorNam)")

       // let colour = UIColor(hexString: colorNam) {
       // colorsArray.append(colour.cgColor)
       // colorsArray.append(colorNam  as! UIColor)

        let value = (dict as AnyObject).object(forKey: "value") as! String
        print("the values are \(value)")
        valuesArray.append(value)

        let images = (dict as AnyObject).object(forKey: "image") as! String
        let url = URL(string: images as String)
        let data = try? Data(contentsOf: url!)
        print(data)
        let image1 = UIImage(data: data!)! as UIImage
        imagesArray.append(image1)
         print(image1)
            }
Gangireddy Rami Reddy
fuente
2

Esto funciona con Swift 3.1.1 en Linux:

import Foundation

let s = try! String(contentsOfFile: "yo", encoding: .utf8)
Adam Dingle
fuente
1

escribir en ViewDidLoad

var error: NSError?
var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
var documentsDirectory = paths.first as String
var dataPath = documentsDirectory.stringByAppendingPathComponent("MyFolder")

if !NSFileManager.defaultManager().fileExistsAtPath(dataPath) {
    NSFileManager.defaultManager().createDirectoryAtPath(dataPath, withIntermediateDirectories: false, attributes: nil, error: &error)
} else {
    println("not creted or exist")
}

func listDocumentDirectoryfiles() -> [String] {
    if let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as? String {
        let myFilePath = documentDirectory.stringByAppendingPathComponent("MyFolder")
        return NSFileManager.defaultManager().contentsOfDirectoryAtPath(myFilePath, error: nil) as [String]
    }
    return []
}
NRV
fuente
1

Las soluciones anteriores responden preguntas, pero en mi caso, eliminar el contenido antiguo del archivo mientras escribía era un problema.

Entonces, creé una pieza de código para escribir en un archivo en el directorio de documentos sin eliminar el contenido anterior. Probablemente necesite un mejor manejo de errores, pero creo que es un buen punto de partida. Swift 4. Uso:

    let filename = "test.txt"
    createOrOverwriteEmptyFileInDocuments(filename: filename)
    if let handle = getHandleForFileInDocuments(filename: filename) {
        writeString(string: "aaa", fileHandle: handle)
        writeString(string: "bbb", fileHandle: handle)
        writeString(string: "\n", fileHandle: handle)
        writeString(string: "ccc", fileHandle: handle)
    }

Métodos de ayuda:

func createOrOverwriteEmptyFileInDocuments(filename: String){
    guard let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
        debugPrint("ERROR IN createOrOverwriteEmptyFileInDocuments")
        return
    }
    let fileURL = dir.appendingPathComponent(filename)
    do {
        try "".write(to: fileURL, atomically: true, encoding: .utf8)
    }
    catch {
        debugPrint("ERROR WRITING STRING: " + error.localizedDescription)
    }
    debugPrint("FILE CREATED: " + fileURL.absoluteString)
}

private func writeString(string: String, fileHandle: FileHandle){
    let data = string.data(using: String.Encoding.utf8)
    guard let dataU = data else {
        debugPrint("ERROR WRITING STRING: " + string)
        return
    }
    fileHandle.seekToEndOfFile()
    fileHandle.write(dataU)
}

private func getHandleForFileInDocuments(filename: String)->FileHandle?{
    guard let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
        debugPrint("ERROR OPENING FILE")
        return nil
    }
    let fileURL = dir.appendingPathComponent(filename)
    do {
        let fileHandle: FileHandle? = try FileHandle(forWritingTo: fileURL)
        return fileHandle
    }
    catch {
        debugPrint("ERROR OPENING FILE: " + error.localizedDescription)
        return nil
    }
}
Szuwar_Jr
fuente
1

Swift 3.x - 5.x

El mejor ejemplo es crear un local Logfilecon una extensión .txt que pueda verse y mostrarse en el"Files App" fecha y hora actuales como un nombre de archivo

solo agregue este código en info.plist habilite estas dos características

  UIFileSharingEnabled
  LSSupportsOpeningDocumentsInPlace

y esta función a continuación

var logfileName : String = ""
func getTodayString() -> String{

    let date = Date()
    let calender = Calendar.current
    let components = calender.dateComponents([.year,.month,.day,.hour,.minute,.second], from: date)

    let year = components.year
    let month = components.month
    let day = components.day
    let hour = components.hour
    let minute = components.minute
    let second = components.second

    let today_string = String(year!) + "-" + String(month!) + "-" + String(day!) + "-" + String(hour!)  + "" + String(minute!) + "" +  String(second!)+".txt"

    return today_string

}

func LogCreator(){
    logfileName = getTodayString()

    print("LogCreator: Logfile Generated Named: \(logfileName)")

    let file = logfileName //this is the file. we will write to and read from it

    let text = "some text" //just a text

    if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {

        let fileURL = dir.appendingPathComponent(file)
        let documentPath = NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask, true)[0]
        print("LogCreator: The Logs are Stored at location \(documentPath)")


        //writing
        do {
            try text.write(to: fileURL, atomically: false, encoding: .utf8)
        }
        catch {/* error handling here */}

        //reading
        do {
            let text2 = try String(contentsOf: fileURL, encoding: .utf8)
            print("LogCreator: The Detail log are :-\(text2)")
        }
        catch {/* error handling here */}
    }
}


  [1]: https://i.stack.imgur.com/4eg12.png
Vishal Shelake
fuente
Intenté esto, pero debe haber perdido algo. Guarda mi documento y lo coloca en el archivo: /// var / mobile / Containers / Data / Application / E4BF1065-3B48-4E53-AC1D-0DC893CCB498 / Documents / pero no puedo encontrarlo en los archivos.
user3069232
1
Me perdí ESTA clave ... <key> CFBundleDisplayName </key> <string> $ {PRODUCT_NAME} </string> funcionó en iOS 13, Swift 5
user3069232
0
 func writeToDocumentsFile(fileName:String,value:String) {
    let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
    let path = documentsPath.appendingPathComponent(fileName)
    do{
    try value.write(toFile: path, atomically: true, encoding: String.Encoding.utf8)
}catch{
    }
    }

func readFromDocumentsFile(fileName:String) -> String {
    let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
    let path = documentsPath.appendingPathComponent(fileName)
    let checkValidation = FileManager.default
    var file:String

    if checkValidation.fileExists(atPath: path) {
        do{
       try file = NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue) as String
        }catch{
            file = ""
        }
        } else {
        file = ""
    }

    return file
}
maroc
fuente
0

Xcode 8.3.2 Swift 3.x . Usando NSKeyedArchiver y NSKeyedUnarchiver

Leer archivos de documentos

let documentsDirectoryPathString = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let documentsDirectoryPath = NSURL(string: documentsDirectoryPathString)!
let jsonFilePath = documentsDirectoryPath.appendingPathComponent("Filename.json")

let fileManager = FileManager.default
var isDirectory: ObjCBool = false

if fileManager.fileExists(atPath: (jsonFilePath?.absoluteString)!, isDirectory: &isDirectory) {

let finalDataDict = NSKeyedUnarchiver.unarchiveObject(withFile: (jsonFilePath?.absoluteString)!) as! [String: Any]
}
else{
     print("File does not exists")
}

Escribir archivo en documentos

NSKeyedArchiver.archiveRootObject(finalDataDict, toFile:(jsonFilePath?.absoluteString)!)
Prashant Gaikwad
fuente