How to use DispatchQueue or delay to enumerateLines(_:)

Hi!
guard let file = try? String(contentsOf: URL(string: url)!) else { return }

(10.000 rows)

file.enumerateLines { line, shouldStop in 
.... 
}

This function enumerates 10000 rows in just one second, I will like to make a delay between enumeration, to complete the whole task in 45 seconds.

What should I actually use?

You can get delayed execution using a Dispatch timer source.

let timer = DispatchSource.makeTimerSource(queue: .main)
timer.setEventHandler {
… runs every second …
}
timer.schedule(deadline: .now(), repeating: 1.0)
timer.activate()

Reading lines from a file could be easier in Swift. I generally do this using the C standard library. That requires a bit of glue to return lines as Swift strings:

func readLine(_ file: UnsafeMutablePointer<FILE>) -> String? {
var buffer = [CChar](repeating: 0, count: 1024)
guard fgets(&buffer, Int32(buffer.count), file) != nil else {
return nil
}
return String(cString: buffer)
}

With that in place reading line-by-line is pretty straightforward:

let url: URL = …
guard let f = fopen(url.path, "r") else { fatalError() }
while let l = readLine(f) {
print(l)
}
fclose(f)

Another alternative is to read the entire file into memory and then use an iterator to work through the lines:

let url: URL = …
let fileContents = try! String(contentsOf: url)
let fileLines = fileContents.split(separator: "\n")
var lines = fileLines.makeIterator()
while let l = lines.next() {
print(l)
}

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

1 Like
Terms of Service

Privacy Policy

Cookie Policy