Read/Write csv files with Swift 3 and iOS 10

Hi, I'm trying to figure out how to upgrade an app of mine for iOS 10 / Swift 3.0.


With iOS 9.0 and Swift 2 I was using an open solution from GitHub to read and write

csv files (reading the data they were mapped into dictionaries).

Now many parts are deprecated, and I cannot use anymore that solution.


Do you have any suggestion to solve that problem, and maybe any sample code as an

example?


Many thank, Salva

I found a simple CSV parser for Objective-C that I converted to Swift:


github.com/ahltorp/csvparser


You use it like this:


do {
     let csvData = try String(contentsOfFile: "file")
     let csv = csvData.csvRows()
     for row in csv {
          print(row)
     }
} catch {
    print(error)
}


I don't know how well it parses files, so verify that before you use it.

A CVS reader/write is rather straight forward to write assuming that your dealing with a sane CVS format.


There are really only four rules:

  • Each table cell consists of characters that can be converted to strings, numbers or other data types.
  • A new table row starts with a single CR or NL character or possibly both (look into mac/Win/Unix line breaks). These may or may not be needed.
  • Specify one character as the the separator - ",", SPACE or TAB are common. You could allow for the use of multiple separators at once.
  • Specify a way to escape a separator e.g. by using \, to escape a ","-separator and treat it as cell content. The escape character also needs to be able to be escaped, this an be done by treating double occurences of it as a escape e.g. \\ is treated as the cell content "\".


For reading CVS data you simply accumulate cell content until you find a separator or a escape character in which case you need to also look at the following character. When writting CVS data you will simply have to add escapes (if needed) for the text of a cell and separators after each cell except the last one. You may also need to insert/detect new lines.


ps: this is also pretty much the minimum feature set for a general purpouse CVS reader/writer, more complex ones may want to deal with the multiple levels of escapes that apps like Excel has been know to generate. Other desireable features may be autodetection of separator and escape charcters.

This works, but I had to change your suggestion to:


let csvPath = Bundle.main.path(forResource: "fileName", ofType: "csv")

        if csvPath == nil {
            return
        }
       
        var csvData: String? = nil
       
        do {
            csvData = try String(contentsOfFile: csvPath!, encoding: String.Encoding.utf8)
            let csv = csvData?.csvRows()
            for row in csv!{
           
                print(row)
            }
       
        } catch{
            print(error)
        }


Hope this helps to somebody!

A.

It is probably better to use guard instead of the first five lines. Also, you never use the csvData outside the "do", so why did you change it to be declared outside? My suggestion:


guard let csvPath = Bundle.main.path(forResource: "fileName", ofType: "csv") else { return }

do {
    let csvData = try String(contentsOfFile: csvPath, encoding: String.Encoding.utf8)
    let csv = csvData.csvRows()
   
    for row in csv {
        print(row)
    }
} catch{
    print(error)
}
Read/Write csv files with Swift 3 and iOS 10
 
 
Q