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.

9
  • String returns an optional string (your tuple) you need to unwrap it Commented Jan 13, 2016 at 4:39
  • As noted I had read that post, but I get errors when running the accepted answer. Besides which it doesn't address the issue of splitting into an array. Commented Jan 13, 2016 at 5:39
  • Can you give an example of unwrapping it correctly? I try print(fileContents!) but that causes an error Commented Jan 13, 2016 at 5:40
  • where is your file located? Commented Jan 14, 2016 at 0:39
  • You should use String instead of NSString Commented Jan 14, 2016 at 0:40

2 Answers 2

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)") 
Sign up to request clarification or add additional context in comments.

Comments

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")

2 Comments

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.
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).

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.