thierryH91200 / SwiftCSV

CSV parser for Swift

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SwiftCSV

Swift 5.0 Platform support Build Status Code coverage status CocoaPods Compatible Carthage compatible License MIT Reviewed by Hound

Simple CSV parsing for macOS, iOS, tvOS, and watchOS.

Usage

CSV content can be loaded using the CSV class:

import SwiftCSV

do {
    // As a string
    let csv = try CSV(string: "id,name,age\n1,Alice,18")

    // With a custom delimiter character
    let tsv = try CSV(string: "id\tname\tage\n1\tAlice\t18", delimiter: "\t")

    // From a file (with errors)
    let csv = try CSV(name: "users.csv")

    // With a custom delimiter, errors, and custom encoding
    let tsv = try CSV(name: "users.tsv", delimiter: tab, encoding: NSUTF8StringEncoding)
} catch parseError as CSVParseError {
    // Catch errors from parsing invalid formed CSV
} catch {
    // Catch errors from trying to load files
}

API

If you don't care about the columns, you can set the loadColumns argument to false and the columns Dictionary will not be populated.

class CSV {
    /// Load a CSV file from a string
    ///
    /// - parameter string: Contents of the CSV file
    /// - parameter delimiter: Character to split row and header fields by (default is ',')
    /// - parameter loadColumns: Whether to populate the columns dictionary (default is true)
    /// - throws: CSVParseError when parsing `string` fails.
    public init(
        string: String, 
        variant: Variant = .named, 
        delimiter: Character = comma, 
        loadColumns: Bool = true) throws
         
    /// Load a CSV file
    ///
    /// - parameter name: name of the file (will be passed to String(contentsOfFile:encoding:) to load)
    /// - parameter delimiter: character to split row and header fields by (default is ',')
    /// - parameter encoding: encoding used to read file (default is UTF-8)
    /// - parameter loadColumns: whether to populate the columns dictionary (default is true) 
    /// - throws: CSVParseError when parsing `string` fails, or file loading errors.
    public convenience init(
        name: String, 
        variant: Variant = .named, 
        delimiter: Character = comma, 
        encoding: String.Encoding = .utf8, 
        loadColumns: Bool = true) throws
    
    /// Load a CSV file from a URL
    ///
    /// - parameter url: url pointing to the file (will be passed to String(contentsOfURL:encoding:) to load)
    /// - parameter delimiter: character to split row and header fields by (default is ',')
    /// - parameter encoding: encoding used to read file (default is UTF-8)
    /// - parameter loadColumns: whether to populate the columns dictionary (default is true)
    /// - throws: CSVParseError when parsing `string` fails, or file loading errors.
    public convenience init(
        url: URL, 
        variant: Variant = .named, 
        delimiter: Character = comma, 
        encoding: String.Encoding = .utf8, 
        loadColumns: Bool = true) throws
}

public enum CSVParseError: Error {
    case generic(message: String)
    case quotation(message: String)
}

Reading Data

Works just like the original:

let csv = CSV(string: "id,name,age\n1,Alice,18\n2,Bob,19")
csv.header    //=> ["id", "name", "age"]
csv.rows      //=> [["id": "1", "name": "Alice", "age": "18"], ["id": "2", "name": "Bob", "age": "19"]]
csv.columns   //=> ["id": ["1", "2"], "name": ["Alice", "Bob"], "age": ["18", "19"]]

The rows can also parsed and passed to a block on the fly, reducing the memory needed to store the whole lot in an array:

// Access each row as an array (array not guaranteed to be equal length to the header)
csv.enumerateAsArray { array in
    print(array.first)
}
// Access them as a dictionary
csv.enumerateAsDict { dict in
    print(dict["name"])
}

Installation

CocoaPods

pod "SwiftCSV"

Carthage

github "swiftcsv/SwiftCSV"

About

CSV parser for Swift

License:MIT License


Languages

Language:Swift 97.2%Language:Ruby 2.8%