Progress indicators are seen everywhere in any systems such as loading webpages of browsers, installation of applications and reminding time and tasks for user completion. NSProgress is class to accurate report the progress of work.
class NSProgress {
var totalUnitCount: Int64 //total work units
var completedUnitCount: Int64 //total work units completed
var fractionCompleted: Double { get } //computed property
var indeterminate: Bool { get } // return true if totalUnitCount < 0 or completedUnitCount < 0, useful when the total work unit is unknown
var localizedDescription: String!
var localizedAdditionalDescription: String!
var kind: NSProgressKind
}
currently only setting kind as NSProgressKindFile to change the localizedDescriptions and localizedAdditionalDescription
Composition of progress is needed when not tracking single progress but many progress
Use a parent progress that allows childs' progress to report back via pendingUnitCount

In older system, implicit composition is used
let parentProgress = NSProgress()
parentProgress.totalUnitCount = 2
//assigning 1 unit count to child's progress to finish
parentProgress.becomeCurrentWithPendingUnitcount(1)
startDownload() //NSProgress(totalUnitCount:...)
parentProgress.resignCurrent() //completed child's progress
let childProgress = child.progress
let parentProgress = ...
parentProgress.addChild(childProgress, withPendingUnitCount:1)
var cancellable: Bool
var cancellationHandler: (() -> Void)?
var cancelled: Bool { get }
calling progress.cancel() will
cancelled to truecancellationHandlervar pausable: Bool
var pausingHandler: (() -> Void)?
var resumingHandler: (() -> Void)?
var paused: Bool { get }
calling progress.pause() or progress.resume() will
NSProgress properties are key value observable
//somewhere in code
progress.addObserver(self, forKeyPath: "fractionCompleted", options: [], context: &observationContext)
override func observeValueForKeyPath(keyPath: ..., object: ..., ..., context: ...) {
if context == &observationContext && keyPath == "fractionCompleted" {
NSOperationQueue.mainQueue().addOperationWithBlock {
let progress = (object as! NSProgress)
progressView.progress = Float(progress.fractionCompleted)
}
}
else {
super.observeValueForKeyPath(...)
}
}