Search code examples
propertiesswift3writetofile

Why can't I use write(toFile: ) property on a string?


I'm following a tutorial that was written in some earlier version of Swift, that teaches me how to read/write a .txt file in Swift3. Xcode has been doing a good job so far of letting me know when I'm using old syntax, and changing it for me to the latest syntax. However, I'm coming across something that works in an older version of Swift, but not the current one.

class ViewController: UIViewController {

    // MARK: Properties

    @IBOutlet weak var monthToEditTextField: UITextField!
    @IBOutlet weak var bedTimeTextField: UITextField!
    @IBOutlet weak var wakeTimeTextField: UITextField!
    @IBOutlet weak var theLabel: UILabel!

    @IBAction func saveButton(_ sender: UIButton)
    {
        var theMonth = monthToEditTextField.text
        var bedTime = bedTimeTextField.text
        var wakeTime = wakeTimeTextField.text

        var stringForTXTFile = "The user's info is: \(theMonth), \(bedTime), \(wakeTime)"

        let fileManager = FileManager.default

        if (!fileManager.fileExists(atPath: filePath))
        {
            var writeError: NSError?
            let fileToBeWritten = stringForTXTFile.write(toFile: // This is where the problem is
        }   
    }

When I type

stringForTXTFile.write

I get this error box

Error Box

What do I need to do in order to use the "write" property?


Solution

  • Write to file doesn't return Bool anymore in Swift3. It throws, so just delete let fileToBeWritten = and use do try catch error handling. Any code that needs to be run if the operation was successful needs to be placed below that inside the do try curly brackets. You can also use guard to unwrap your textfield optional strings. Try like this:

    import UIKit
    
    class ViewController: UIViewController {
        @IBOutlet weak var monthToEditTextField: UITextField!
        @IBOutlet weak var bedTimeTextField: UITextField!
        @IBOutlet weak var wakeTimeTextField: UITextField!
        @IBOutlet weak var theLabel: UILabel!
        let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("textFile.txt")
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
        @IBAction func save(_ sender: UIButton) {
            guard
                let theMonth = monthToEditTextField.text,
                let bedTime = bedTimeTextField.text,
                let wakeTime = wakeTimeTextField.text
                else { return }
    
            let stringForTXTFile = "The user's info is: \(theMonth), \(bedTime), \(wakeTime)"
                do {
                    try stringForTXTFile.write(toFile: fileURL.path, atomically: true, encoding: .utf8)
                    // place code to be executed here if write was successful
                } catch {
                    print(error.localizedDescription)
                }
        }
    
        @IBAction func load(_ sender: UIButton) {
            do {
                theLabel.text = try String(contentsOf: fileURL)
            } catch {
                print(error.localizedDescription)
            }
        }
    }