img

Overview

This is primarily an educational class which is also fully functional and can be used to base your own implementation upon. It shows how to read a file decoupled from the GUI. I.e. the data processing happens at the end of the run loop when all GUI related events have been processed.

Though the data processing happens at the end of the runloop, if the process itself takes a long time it could still have an impact on the GUI experience by delaying the reaction to GUI events. If that is an issue the processing itself should be put into another thread. (This is not covered by this example)

Use the class by creating a child class that override the “processStreamBuffer” method.

The StreamingFileReader needs SwifterLog (which is available for free from Github)

The public interface to the StreamingFileReader is as follows:

class StreamingFileReader: NSObject, NSStreamDelegate {
    
    
    // The path of the file to be read
    
    let fileUrl: NSURL

    
    // Size of the stream buffer, also the initial size of the first block of data that is attempted to be read from the file.
    
    let streamBufferSize: Int
    
    
    /// The buffer to be processed by processStreamBuffer when it is called.
    
    var streamBuffer: Array<UInt8> = []

    
    /// The listener will not receive callbacks until the startReadingFromFile returns 'true'.
    
    init(fileUrl: NSURL, streamBufferSize: Int) {}

    
    /// This method starts file reading, it returns true if reading started, false if not.
    
    func startReading() -> Bool {}

    
    /// Override this method to read from the streambuffer. Return true to keep reading, return false to abort.
    ///
    /// :param: nofBytes The number of bytes that were read or error information: -2 if the startAtOffset value is too big, -1 if a stream error occured, 0 when no more bytes are available. If an error is indicated, this will be the last callback. Even if true is returned.
    ///
    /// :param: startAtOffset The location from which the bytes are stored in the streambuffer, resp the location from which to start filling the streambuffer. In case the numOfBytes indicate an error, this parameter will always be zero. If this parameter is >= streamBufferSize (set during initialization) there will be an immedate callback with nofBytes = -2. Note that this parameter is never changed by the methods in StreamingFileReader (except in error cases). It is provided as a service to the child class so it can choose to implement partial processing of the stream buffer. If the child class always completely consumes all of the data in the stream buffer then either never change this variable or always set it to zero.
    ///
    /// :returns: Return true if reading should continue, false if not.
    
    func processStreamBuffer(nofBytes: Int, inout startAtOffset: Int) -> Bool { return false }
    
}

Typical use would be as follows:

class MyClass: StreamingFileReader {

	let STREAM_BUFFER_SIZE = 4*1024

	init(fileUrl: NSURL) {
   		super.init(fileUrl: fileUrl, streamBufferSize: STREAM_BUFFER_SIZE)
	}

	override func processStreamBuffer(nofBytes: Int, inout startAtOffset: Int) -> Bool {

   		switch nofBytes {

		case -2: return errorEnd("Oeps, programming error, offset is too big")
		case -1: return errorEnd("Error reading from file, see application log for details")
		case  0: return false

	    case  1 ... STREAM_BUFFER_SIZE: return processData(nofBytes, offset: &startAtOffset)

	    default: return errorEnd("Oeps, programming error, illegal number of bytes read \(nofBytes)")
		}
	}

	private func processData(nofBytes: Int, inout offset: Int) -> Bool {
	   	...
	}

	private errorEnd(message: String) -> Bool {
		...
		return false
	}
}

Buy

By clicking the button below you can buy the Swift class StreamingFileReader.

When buying you agree to the license conditions:

  1. You ACCEPT this source code AS IS without any guarantees that it will work as intended. Any liability from its use is YOURS.
  2. You WILL NOT seek damages from the author or balancingrock.nl.
  3. You WILL NOT in any way, shape or form redistribute this source code.

Upon completion of the process you will receive an email with a download link. That link will be valid for 3 download attempts within the next three days of purchase. Upon downloading you will receive a zip file with the StreamingFileReader.swift file in it.

Payment will be processed by paypal. Note that you do not need a paypal account to use paypal, all major credit cards are accepted. Receiver will be sales@balancingrock.nl

Note: We are currently revamping our infrastructure that deals with the ordering process. Until that is completed clicking the “BUY NOW” button will immediately start the download for free.