3

I'm trying to write a Swift program that writes a single character to a file. I've researched this but so far haven't figured out how to do this (note, I'm new to Swift). Note that the text file I'm reading and writing to can contain a series of characters, one per line. I want to read the last character and update the file so it only contains that last character.

Here's what I have so far:

let will_file = "/Users/willf/Drobox/foo.txt"

do {
    let statusStr = try String(contentsOfFile: will_file, encoding: .utf8)
    // find the last character in the string
    var strIndex = statusStr.index(statusStr.endIndex, offsetBy: -1)

    if statusStr[strIndex] == "\n" {
        // I need to access the character just before the last \n
        strIndex = statusStr.index(statusStr.endIndex, offsetBy: -2)
    }

    if statusStr[strIndex] == "y" {
        print("yes")
    } else if statusStr[strIndex] == "n" {
        print("no")
    } else {
        // XXX deal with error here
        print("The char isn't y or n")
    }

    // writing

    // I get a "cannot invoke 'write with an arg list of type (to: String)
    try statusStr[strIndex].write(to: will_file) 
}

I would appreciate advice on how to write the character returned by statusStr[strIndex].

I will further point out that I have read this Read and write a String from text file but I am still confused as to how to write to a text file under my Dropbox folder. I was hoping that there was a write method that could take an absolute path as a string argument but I have not found any doc or code sample showing how to do this that will compile in Xcode 9.2. I have also tried the following code which will not compile:

let dir = FileManager.default.urls(for: .userDirectory, in: .userDomainMask).first
let fileURL = dir?.appendingPathComponent("willf/Dropbox/foo.txt")

// The compiler complains about extra argument 'atomically' in call
try statusStr[strIndex].write(to: fileURL, atomically: false, encoding: .utf8)
4
  • Is the application sandboxed? If yes you cannot access the Dropbox folder in your home folder unless you add appropriate entitlements and open the folder with NSOpenPanel Commented Feb 28, 2018 at 9:24
  • Thanks for the info. I don't plan to sandbox this program since I'm doing this for my use only. Commented Mar 1, 2018 at 16:36
  • Consider that in Xcode 9 apps are sandboxed by default. Please check that the setting is disabled. Rather than using the String read/write API I recommend to read and write Data which can easily converted from and to String. Commented Mar 1, 2018 at 16:42
  • Got it. Note that in my answer below the example code is working for me now. Commented Mar 1, 2018 at 16:50

1 Answer 1

1

I have figured out how to write a character as a string to a file thanks to a couple answers on stack overflow. The key is to coerce a character type to a string type because the string object supports the write method I want to use. Note that I used both the answers in Read and write a String from text file and in Swift Converting Character to String to come up with the solution. Here is the Swift code:

import Cocoa

let will_file = "/Users/willf/Dropbox/foo.txt"

do {
    // Read data from will_file into String object
    let statusStr = try String(contentsOfFile: will_file, encoding: .utf8)
    // find the last character in the string
    var strIndex = statusStr.index(statusStr.endIndex, offsetBy: -1)

    if statusStr[strIndex] == "\n" {
        // I need to access the character just before the last \n
        strIndex = statusStr.index(statusStr.endIndex, offsetBy: -2)
    }

    if statusStr[strIndex] != "n" && statusStr[strIndex] != "y" {
        // XXX deal with error here
        print("The char isn't y or n")
    }

    // Update file so it contains only the last status char
    do {
        // String(statusStr[strIndex]) coerces the statusStr[strIndex] character to a string for writing
        try String(statusStr[strIndex]).write(toFile: will_file, atomically: false, encoding: .utf8)
    } catch {
        print("There was a write error")
    }
} catch {
    print("there is an error!")
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.