Atif Farrukh Atif Farrukh - 2 months ago 24
iOS Question

how to open file and append a string in it, swift

I am trying to append a string into text file. I am using the following code.

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

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

//reading
let text2 = String(contentsOfFile: path, encoding: NSUTF8StringEncoding, error: nil)
println(text2) //prints some text
}


this does not append the string to file. Even if I call this function repeatedly.

Rob Rob
Answer

If you want to be able to control whether to append or not, consider using NSOutputStream. For example:

let documents = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
let path = documents.URLByAppendingPathComponent("votes").path!

if let outputStream = NSOutputStream(toFileAtPath: path, append: true) {
    outputStream.open()
    let text = "some text"
    outputStream.write(text)

    outputStream.close()
} else {
    print("Unable to open file")
}

By the way, this is an extension that lets you easily write a String to an NSOutputStream:

extension NSOutputStream {

    /// Write String to outputStream
    ///
    /// - parameter string:                The string to write.
    /// - parameter encoding:              The NSStringEncoding to use when writing the string. This will default to UTF8.
    /// - parameter allowLossyConversion:  Whether to permit lossy conversion when writing the string.
    ///
    /// - returns:                         Return total number of bytes written upon success. Return -1 upon failure.

    func write(string: String, encoding: NSStringEncoding = NSUTF8StringEncoding, allowLossyConversion: Bool = true) -> Int {
        if let data = string.dataUsingEncoding(encoding, allowLossyConversion: allowLossyConversion) {
            var bytes = UnsafePointer<UInt8>(data.bytes)
            var bytesRemaining = data.length
            var totalBytesWritten = 0

            while bytesRemaining > 0 {
                let bytesWritten = self.write(bytes, maxLength: bytesRemaining)
                if bytesWritten < 0 {
                    return -1
                }

                bytesRemaining -= bytesWritten
                bytes += bytesWritten
                totalBytesWritten += bytesWritten
            }

            return totalBytesWritten
        }

        return -1
    }

}
Comments