How to append a string to a text file without overwriting existing data
Asked Answered
D

1

6

I'm new to Swift and trying to append a string to a text file in iOS app.

string.write is simple enough, but will overwrite the existing info.

write(toFile: atomically:encoding:) also overwrites existing info, though the docs note that it may be extended in the future to allow adding information.

Using FileHandle seems logical, but the methods for writing to a file -- such as init(forWritingTo:) -- require write(_:), and that function is deprecated! The docs do not suggest an alternative or replacement.

let fileName: String = "mytextfile.txt"
let directoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let newFileUrl = directoryURL!.appendingPathComponent(fileName)
let textToAdd = "Help me, Obiwan!"
if let fileUpdater = try? FileHandle(forUpdating: newFileUrl) {
   fileUpdater.seekToEndOfFile()
   fileUpdater.write(textToAdd.data(using: .utf8)!)
   fileUpdater.closeFile()
}

So how do I do this now that write(_:) is deprecated?

Dumfries answered 13/1, 2021 at 17:41 Comment(5)
Did you check the updates to https://mcmap.net/q/294884/-append-text-or-data-to-text-file-in-swift/1187415?Disbud
Yes. (And many others!) All of those answers use fileHandle.write, which the apple docs linked in the question show as deprecated. Am I wrong in assuming I shouldn't be using something marked as deprecated?Dumfries
Indeed, the online documentation marks it as deprecated, but my Xcode does not show a warning. With "Jump to Definition” in Xcode one sees that the method is annotated as @available(macOS, introduced: 10.0, deprecated: 100000). According to the discussion at forums.swift.org/t/… that means deprecation in “some future version of the OS or Swift.”Disbud
I likely wouldn't have noticed, but I'm new to Swift so I've been checking documentation as I go. Perhaps they'll take it out when that functionality is added to write(toFile: atomically:encoding:). I'll use .write for now. Thanks for the sanity check.Dumfries
This did not work for me. I have found many examples, but so far I have not found any Swift code that actually appends an existing textfile.Hellhole
W
0

The write(_:) method is deprecated and the documentation now suggests an alternative:

Use write(contentsOf:) to handle errors when writing data to the file handle.

So, replace handle.write(_:) with try handle.write(contentsOf:).

Perhaps:

func append(_ text: String, to filename: String) throws {
    let data = Data(text.utf8)

    let fileUrl = URL.applicationSupportDirectory // or `documentsDirectory` if you really want it to be a user-facing file
        .appending(path: filename)

    do {
        let handle = try FileHandle(forUpdating: fileUrl)
        defer { handle.closeFile() }
        handle.seekToEndOfFile()
        try handle.write(contentsOf: data)
    } catch CocoaError.fileNoSuchFile {
        try data.write(to: fileUrl)
    } catch {
        throw error
    }
}

The idea is that they have deprecated the write(_:) function with one that is capable of throwing errors.

Weepy answered 22/10 at 19:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.