7

Basically, I am trying to do this with Swift 3:

write a titleString to file
For i=1 to n
    newString = createNewString()  //these may look like "1: a, b, c"
    append each new string to end of file
next i

Here is what I have done:

let fileURL = URL(fileURLWithPath: completePath)
let titleString = "Line, Item 1, Item 2, Item 3"
var dataString: String
let list1 = [1, 2, 3, 4, 5]
let list2 = ["a", "b", "c", "d", "e"]
let list3 = ["p", "q", "r", "s", "t"]


for i in 0...4 {
    dataString =  String(list1[i]) + ": " + list2[i] + list3[i] + "\n"

    //Check if file exists
    if let fileHandle = FileHandle(forReadingAtPath: fileURL.absoluteString) {
        fileHandle.seekToEndOfFile()
        fileHandle.write(dataString.data(using: .utf8)!)
    } else { //create new file

        do {
            try titleString.write(to: fileURL, atomically: true, encoding: String.Encoding.utf8)
        } catch let error as NSError {
            print("Error creating file \(error)")
        }

    }
    print(dataString)
    print("Saving data in: \(fileURL.path)")
}

All I get in the file is the titleString. The other strings don't show up.

Greg
  • 667
  • 8
  • 19
  • 1
    Please use `if let fileHandle = try? FileHandle(forUpdating: fileURL)` in place of `if let fileHandle = FileHandle(forReadingAtPath: fileURL.absoluteString)` – Vini App Sep 19 '17 at 21:23

1 Answers1

8

You can use a FileHandle for appending the existing file after checking if the file already exists.

let titleString = "Line, Item 1, Item 2, Item 3"
var dataString: String
let list1 = [1, 2, 3, 4, 5]
let list2 = ["a", "b", "c", "d", "e"]
let list3 = ["p", "q", "r", "s", "t"]

do {
    try "\(titleString)\n".write(to: fileURL, atomically: true, encoding: String.Encoding.utf8)
} catch {
    print(error)
}

for i in 0...4 {
    dataString =  String(list1[i]) + ": " + list2[i] + list3[i] + "\n"
    //Check if file exists
    do {
        let fileHandle = try FileHandle(forWritingTo: fileURL)
            fileHandle.seekToEndOfFile()
            fileHandle.write(dataString.data(using: .utf8)!)
            fileHandle.closeFile()
    } catch {
        print("Error writing to file \(error)")
    }
    print(dataString)
    print("Saving data in: \(fileURL.path)")
}

Output:

Line, Item 1, Item 2, Item 3
1: ap
2: bq
3: cr
4: ds
5: et
pkamb
  • 33,281
  • 23
  • 160
  • 191
Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
  • 1
    Don't forget to close the file handle after writing. – rmaddy Sep 19 '17 at 19:33
  • There is no "Post Your Answer" box at the bottom to show what I did and not enough characters here... But this didn't work either. – Greg Sep 19 '17 at 19:55
  • You should edit your original question if you have more to add on the issue. And please specify what you mean by "this didn't work either". What was the issue? – Dávid Pásztor Sep 19 '17 at 19:57
  • Oh, does being marked a duplicate prevent me from further discussing and posting what I did? – Greg Sep 19 '17 at 19:59
  • Thanks! I edited above. – Greg Sep 19 '17 at 20:04
  • @Greg it seems like you're using the version of my answer before editing it. You should also include the `fileHandle.closeFile()` line. – Dávid Pásztor Sep 19 '17 at 20:07
  • No, there are a few modifications. For example, I used dataString if the file exists and titleString when creating a new file. And put it in the loop - is that the right place? – Greg Sep 19 '17 at 20:09
  • Yeah, all the other changes should be fine, but closing the file is necessary. – Dávid Pásztor Sep 19 '17 at 20:41
  • I've tried closing it at the very end as well as in the loop after the fileHandle.write(dataString.data(using: .utf8)!) line. In both cases, the file contains only the titleString. It's driving me nuts! I miss good old C..... – Greg Sep 19 '17 at 23:50
  • Check my updated answer, I tested it and it's working fine now. – Dávid Pásztor Sep 20 '17 at 07:12
  • That does the trick! Thank you Dávid! – Greg Sep 20 '17 at 17:09
  • I upvoted but my rep is too low to display :-( – Greg Sep 20 '17 at 17:09
  • No worries, glad I could help. Even with a low reputation, you can accept an answer if you found it useful using the checkmark symbol under the downvoting arrow. – Dávid Pásztor Sep 20 '17 at 17:16
  • Great! I'm still new to this stackoverflow... Thanks again! – Greg Sep 21 '17 at 19:34