5

Brand new to Swift, but done a fair amount of coding in other languages (Java, C, Python...) and I'm frustrated at how seemingly difficult it is to simply read in a file.

I've read a number of posts, like this one, but can't get their suggestions to work. Also read this post and this one but the solutions seemed long for such a simple task and also didn't work for me.

Here's a simple version:

    import Foundation
    let path = "./data.txt"        
    let fileContents = String(contentsOfFile: path, encoding: NSUTF8StringEncoding)        
    print(fileContents) // prints out: ("./data.txt", 4)
    let lines : [String] = fileContents.componentsSeparatedByString("\n") // error: value of type 'String' has no member 'componentsSeparatedByString'       

Now, based on the first post I linked above, I expected this to read the specified file into a single string, then split the string on newlines and give me an array with each line as an element. Instead, when I print fileContents, I get some type of tuple rather than the string I expected. And when I try to split the string, apparently that function doesn't exist.

Can someone explain what I'm missing and show me a short, simple way to read the lines from a file into a string array? I'm reading the documentation but can't even find an explanation of the String() call in line 3 or reference to the componentsSeparatedByString() in line 5 so I'm going totally off the suggestions in that first post; any pointers are much appreciated.

Community
  • 1
  • 1
Philip
  • 1,526
  • 1
  • 14
  • 25

2 Answers2

2

For me I believe the problems with other solutions stemmed from me developing on a Linux platform, which at the time didn't seem to work as on a mac. This is basically what ended up with that works for me:

    import Foundation

    func readFile(path: String) -> Array<String> {

        do { 
            let contents:NSString = try NSString(contentsOfFile: path, encoding: NSASCIIStringEncoding)
            let trimmed:String = contents.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
            let lines:Array<String> =  NSString(string: trimmed).componentsSeparatedByCharactersInSet(.newlineCharacterSet())
            return lines
        } catch {
            print("Unable to read file: \(path)");
            return [String]()    
        }    
    }

    let lines = readFile("./somefile.txt")
    print("Read \(lines.count) lines from file: \(lines)") 
Philip
  • 1,526
  • 1
  • 14
  • 25
0

componentsSeparatedByString(separator: String) has been renamed to components(separatedBy: String). So, here's your last line, if you'd rather use String over NSString:

let lines = fileContents.components(separatedBy: "\n")
tobygriffin
  • 5,339
  • 4
  • 36
  • 61
  • I believe if the OP was on Swift 2.2 they would not be receiving the error they describe in the fifth line because as you say the method does exist in that version. – tobygriffin May 29 '16 at 20:41
  • The comment to which I was replying above said that my answer was only relevant to Swift 3. The comment has been removed but the downvote has not. I still think this answer is correct, as the accepted answer describes moving from a Linux platform back to a Mac platform (and Swift 2.2). – tobygriffin Jun 20 '16 at 00:57