18

I was wondering what the simplest and cleanest to read a text file into an array of strings is in swift.

Text file:

line 1
line 2
line 3 
line 4

Into an array like this:

var array = ["line 1","line 2","line 3","line 4"]

I would also like to know how to do a similar thing into struct like this:

Struct struct{
   var name: String!
   var email: String!
}

so take a text file and put it into struct's in an array.

Thanks for the help!

Henry oscannlain-miller
  • 1,991
  • 3
  • 14
  • 13
  • http://stackoverflow.com/questions/24097826/read-and-write-data-from-text-file – brimstone Mar 23 '15 at 18:22
  • 1
    See this post for an excellent discussion on the options for converting a text file to a line array. http://codereview.stackexchange.com/a/100813/79551 – Suragch Aug 15 '15 at 02:28

7 Answers7

17

First you must read the file:

let text = String(contentsOfFile: someFile, encoding: NSUTF8StringEncoding, error: nil)

Then you separate it by line using the componentsSeparatedByString method:

let lines : [String] = text.componentsSeparatedByString("\n")
Ian
  • 12,538
  • 5
  • 43
  • 62
  • 2
    Note that some files do not just `\n` as the new line marker. You can consider using `NSCharacterSet.newlineCharacterSet()` and `componentsSeparatedByCharactersInSet`. – Suragch Aug 15 '15 at 02:26
  • 1
    new Swift syntax would be: `try! let text = String(contentsOfFile: someFile!, encoding: NSUTF8StringEncoding)` http://stackoverflow.com/questions/32663872/swift2-cannot-invoke-initializer-for-type-nsstring – thumbtackthief Oct 17 '15 at 19:49
17

Updated for Swift 3

    var arrayOfStrings: [String]?

    do {
        // This solution assumes  you've got the file in your bundle
        if let path = Bundle.main.path(forResource: "YourTextFilename", ofType: "txt"){
            let data = try String(contentsOfFile:path, encoding: String.Encoding.utf8)                
            arrayOfStrings = data.components(separatedBy: "\n")
            print(arrayOfStrings)
        }
    } catch let err as NSError {
        // do something with Error
        print(err)
    }
He Yifei 何一非
  • 2,592
  • 4
  • 38
  • 69
Adrian
  • 16,233
  • 18
  • 112
  • 180
6

Updated for Swift 5:

The const path contains the file path.

do {
    let path: String = "file.txt"
    let file = try String(contentsOfFile: path)
    let text: [String] = file.components(separatedBy: "\n")
} catch let error {
    Swift.print("Fatal Error: \(error.localizedDescription)")
}

If you want to print what's inside of file.txt line by line:

for line in text {
    Swift.print(line)
}
Cristian
  • 654
  • 1
  • 13
  • 30
2

Here is a way to convert a string to an array(Once you read in the text):

var myString = "Here is my string"

var myArray : [String] = myString.componentsSeparatedByString(" ")

This returns a string array with the following values: ["Here", "is", "my", "string"]

ebo
  • 2,717
  • 1
  • 27
  • 22
tukbuk23
  • 71
  • 5
2

Swift 4:

do {
    let contents = try String(contentsOfFile: file, encoding: String.Encoding.utf8)
    let lines : [String] = contents.components(separatedBy: "\n")    
} catch let error as NSError {
    print(error.localizedDescription)
}
pkamb
  • 33,281
  • 23
  • 160
  • 191
Jinesh Mathew
  • 366
  • 3
  • 5
1

In Swift 3 for me worked like below:

Import Foundation

let lines : [String] = contents.components(separatedBy: "\n")
Alessandro Mattiuzzi
  • 2,309
  • 2
  • 18
  • 24
0

Updated so you don't need to hardcode the file path:

Because Xcode requires you to use unique filenames inside a project, we can simply search for the filename inside the main bundle. This approach eliminates the need to hardcode the file path, thereby preventing potential issues, especially when collaborating with others / working on different machines:

import Foundation

extension Bundle {
    /// Creates an array of strings from a text file in the bundle.
    /// - Parameters:
    ///   - fileName: The name of the text file.
    ///   - separatedBy: The string used to separate the contents of the file.
    /// - Returns: An array of strings representing the contents of the file, separated by the specified separator.
    /// - Note: Will raise a fatal error if the file cannot be located in the bundle or if the file cannot be decoded as a String.
    func createArrayOfStringsFromTextFile(fileName file: String, separatedBy separator: String) -> [String] {
        guard let url = self.url(forResource: file, withExtension: nil) else {
            fatalError("Failed to locate '\(file)' in bundle.")
        }
        
        guard let fileContent = try? String(contentsOf: url)  else {
            fatalError("Failed to read content of '\(file)' as a string.")
        }
        let result: [String] = fileContent.components(separatedBy: separator)
        return result
    }
}

Usage:

let result: [String] = Bundle.main.createArrayOfStringsFromTextFile(fileName: "someFile.txt", separatedBy: "\n")
Julius
  • 1
  • 3