4

I'm building a little utility to load a CSV file into my app and read the next value about 5 times per second (The csv file is from a sensor logger)

For this i'm using this csv library: https://github.com/naoty/SwiftCSV

Now, the performance/update rate suffers dramatically with csv files with more than a few lines. The problem is that i can't for the life of it figure out how to NOT load the csv file with each time i call SensorRecording.getDatapoints()

I'm guessing it should be a global class variable only loaded once, but adding the respective lines for the variables "csvURL" and "csv" at the top of the class declaration yields a strange

"SensorRecording.Type does not have a member named 'csvPath'

How could i store it in a global variable for that class?

Here's the SensorRecording class code:

import UIKit

class SensorRecording: UIViewController {

    var cur: Int = 1

    let csvPath = NSBundle.mainBundle().pathForResource("2014-09-21_23-25-32", ofType: "csv")
    let csvURL = NSURL.fileURLWithPath(csvPath!)
    let csv = CSV(contentsOfURL: csvURL!)

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }



    func getDatapoints() -> NSDictionary {



        let rows = csv.rows

        if (cur == (csv.rows.count-1)) { cur = 1 } else { cur++ }

        return csv.rows[cur]

    }

Many thanks

jodldoe
  • 67
  • 7
  • possible duplicate of [ViewControl.Type does not have a member named](http://stackoverflow.com/questions/25855137/viewcontrol-type-does-not-have-a-member-named) – jtbandes Sep 23 '14 at 20:56
  • How big is the CSV file? – mipadi Sep 23 '14 at 20:59
  • @mipadi 30.837 Bytes – jodldoe Sep 24 '14 at 07:04
  • @jtbandes thanks for the pointer, that still doesn't explain how to declare a global variable or another solution with a similar effect since it recommends putting the variable in a method. – jodldoe Sep 24 '14 at 07:07

1 Answers1

2

There's nothing in your code or in that CSV library that would cause the file to be reloaded each time -- after let csv = CSV(...) you're essentially just working with a few nested Array and Dictionary instances. The memory

(The implementation of that CSV library isn't very memory efficient, though -- duplication of data and super-duplication of headers.)


I had thought that you were having the performance problem you described with your code sample, but now I see the issue you're having. You can't set default property values based on other properties, so you need to load the CSV file in your initializer:

class SensorRecording {
    var cur: Int = 1
    var csv: CSV!      // implicitly unwrapped: skip during initialization,
                       // but need to give value before accessing
    init() {
        // load CSV here
        let csvPath = NSBundle.mainBundle().pathForResource("2014-09-21_23-25-32", ofType: "csv")
        let csvURL = NSURL.fileURLWithPath(csvPath!)
        csv = CSV(contentsOfURL: csvURL!)
    }

    func getDatapoints() -> NSDictionary {
        let rows = csv.rows
        if (cur == (csv.rows.count-1)) { cur = 1 } else { cur++ }
        return csv.rows[cur]
    }
}
Nate Cook
  • 92,417
  • 32
  • 217
  • 178
  • thanks nate - if that code would actually work, that's what had imagined it would do as well. unfortunately the above structure doesn't compile and throws the afforementioned error ""SensorRecording.Type does not have a member named 'csvPath'" the implementation that made the app run slower with larger (30kb) csv files had included the instantiation of the csv object with every call to getDatapoints() – jodldoe Sep 24 '14 at 20:02
  • again, your help is much appreciated. Now it throws a "fatal error: unexpectedly found nil while unwrapping an Optional value" error when getDatapoints() is called, as it seems like this initializer never fires (by calling let mySensorRecording = SensorRecording() from ViewController.swift) - how can i make sure it fires, or are there other ways to initialize a class? – jodldoe Sep 24 '14 at 20:42
  • It seems like you may not be using this as a view controller, instead just as a sort of data controller? If that's the case it can be much more lightweight - see above. – Nate Cook Sep 24 '14 at 20:44