iOS Developer Library — Prerelease

Developer

Foundation Framework Reference NSProgress Class Reference

Options
Deployment Target:

On This Page
Language:

NSProgress

The NSProgress class provides a self-contained mechanism for progress reporting. It makes it easy for code that does work to report the progress of that work, and for user interface code to observe that progress for presentation to the user. Specifically, it can be used to show the user a progress bar and explanatory text, both updated properly as progress is made. It also allows work to be cancelled or paused by the user.

Reporting Progress

Using the methods of this class, your code can report the progress it’s currently making toward completing some task, including progress in related subtasks. You can create instances of this class using the initWithParent:userInfo: instance method or the progressWithTotalUnitCount: class method.

Progress objects have a number of properties that you can use to observe and report current progress. For instance, the totalUnitCount property represents the total number of units of work that need to be performed, and the completedUnitCount and fractionCompleted properties represents how much of that work has already been completed. The fractionCompleted property is useful for updating progress indicators or textual descriptors; to check whether progress is complete, you should test that completedUnitCount >= totalUnitCount (assuming, of course, that totalUnitCount > 0).

The following listing shows a sample method that reports the progress of performing some operation on a piece of data. When the progress object is first created, the value of its totalUnitCount property is set to some suitable batch size for this operation, and the completedUnitCount count is 0. Each time the loop executes and the batch of data is processed, the progress object’s totalUnitCount property is incremented appropriately.

  1. - (void)startTaskWithData:(NSData *)data {
  2. NSUInteger batchSize = ... use a suitable batch size
  3. NSProgress *progress = [NSProgress progressWithTotalUnitCount:batchSize];
  4. for (NSUInteger index = 0; index < batchSize; index++) {
  5. // Check for cancellation
  6. if ([progress isCancelled]) {
  7. // Tidy up as necessary...
  8. break;
  9. }
  10. // Do something with this batch of data...
  11. // Report progress (add 1 because we've completed the work for the current index).
  12. [progress setCompletedUnitCount:(index + 1)];
  13. }
  14. }

Each of the properties of a progress object, including totalUnitCount, completedUnitCount, and fractionCompleted, support Key-Value Observing. This makes it extremely easy for a view or window controller object to observe the properties, and update UI elements such as progress indicators when the values change. It also means that there is a non-zero cost to updating the values of these properties, so you should avoid using a unit count that is too granular—if you’re iterating over a large data set, for example, and each operation takes only a trivial amount of time, you should divide the work into batches so you can update the unit count once per batch rather than once per iteration.

Creating a Tree of Progress Objects

Often, your code may need to report the overall progress of an operation that is composed of several sub-operations. To accomplish this, your code can report the progress of each sub-operation by building up a tree of progress objects.

The NSProgress reporting mechanism supports a loosely coupled relationship between progress objects. Sub-operations don’t need to know anything about the parent progress item—you can simply create new progress objects and, if another NSProgress instance already exists and is marked as being current for the current thread, the new objects will be set as children of that instance. When the children complete, the parent’s completedUnitCount property is automatically increased by a predefined amount.

As an example, consider that you are tracking the progress of code downloading and copying files on disk. You could use a single progress object to track the entire task, but it’s easier to manage each subtask using a separate progress object. You start by creating an overall parent progress object with a suitable total unit count, then call becomeCurrentWithPendingUnitCount:, then create your sub-task progress objects, before finally calling resignCurrent.

The pending unit count that you specify in the first method is divided equally among the child progress objects you create between these two method calls. Each child progress object maintains its own internal unit count, but when it completes its units (that is, the child object’s completedUnitCount == totalUnitCount), the parent progress object’s completedUnitCount is increased by the assigned portion of the original pending unit count.

In the following example, the overall parent progress has 100 units; the two child objects therefore get 50 pending units each, and keep track internally of 10 units of work each. When each child completes its 10 units, the parent’s completed unit count is increased by 50.

  1. - (void)startLongOperation {
  2. self.overallProgress = [NSProgress progressWithTotalUnitCount:100];
  3. [self.overallProgress becomeCurrentWithPendingUnitCount:50];
  4. [self work1];
  5. [self.overallProgress resignCurrent];
  6. [self.overallProgress becomeCurrentWithPendingUnitCount:50];
  7. [self work2];
  8. [self.overallProgress resignCurrent];
  9. }
  10. - (void)work1 {
  11. NSProgress *firstTaskProgress = [NSProgress progressWithTotalUnitCount:10];
  12. // Perform first task...
  13. }
  14. - (void)work2 {
  15. NSProgress *secondTaskProgress = [NSProgress progressWithTotalUnitCount:10];
  16. // Perform second task...
  17. }

If you don’t create any child progress objects between the calls to becomeCurrentWithPendingUnitCount: and resignCurrent, the “parent” progress automatically updates its completedUnitCount by adding the pending units.

  • Initializes a newly allocated NSProgress instance.

    Declaration

    Swift

    init(parent parentProgressOrNil: NSProgress?, userInfo userInfoOrNil: [NSObject : AnyObject]?)

    Objective-C

    - (instancetype nonnull)initWithParent:(NSProgress * nullable)parentProgressOrNil userInfo:(NSDictionary * nullable)userInfoOrNil

    Parameters

    parentProgressOrNil

    The parent NSProgress object, if any, to notify when reporting progress or to consult when checking for cancellation.

    The only valid values are [NSProgress currentProgress] or nil.

    userInfoOrNil

    The user information dictionary for the progress object. May be nil.

    Discussion

    This is the designated initializer for the NSProgress class.

    Availability

    Available in iOS 7.0 and later.

  • Creates and returns an NSProgress instance, initialized using initWithParent:userInfo:.

    Declaration

    Swift

    init(totalUnitCount unitCount: Int64)

    Objective-C

    + (NSProgress * nonnull)progressWithTotalUnitCount:(int64_t)unitCount

    Parameters

    unitCount

    The total number of units of work to be carried out.

    Discussion

    The initializer is passed the current progress object, if there is one, and the value of the totalUnitCount property is set.

    In many cases you can simply precede code that does a substantial amount of work with an invocation of this method, then repeatedly set the completedUnitCount or cancelled property in the loop that does the work.

    You can invoke this method on one thread and then message the returned NSProgress on another thread. For example, you can capture the created progress instance in a block that you pass to dispatch_async(3) Mac OS X Developer Tools Manual Page. In that block you can invoke methods like becomeCurrentWithPendingUnitCount: or resignCurrent, and set the completedUnitCount or cancelled properties as work is carried out.

    Availability

    Available in iOS 7.0 and later.

  • Returns the NSProgress instance, if any, associated with the current thread by a previous invocation of becomeCurrentWithPendingUnitCount:.

    Declaration

    Swift

    class func currentProgress() -> NSProgress?

    Objective-C

    + (NSProgress * nullable)currentProgress

    Return Value

    The NSProgress instance associated with the current thread, if any.

    Discussion

    Use this per-thread currentProgress value to allow code that performs work to report useful progress even when it is widely separated from the code that actually presents progress information to the user, without requiring layers of intervening code to pass around an NSProgress instance.

    When reporting progress, you typically work with a child progress object, created by calling progressWithTotalUnitCount:, to ensure that you report progress in known units of work.

    Availability

    Available in iOS 7.0 and later.

  • Sets the receiver as the current progress object of the current thread and specifies the portion of work to be performed by the next child progress object of the receiver.

    Declaration

    Swift

    func becomeCurrentWithPendingUnitCount(_ unitCount: Int64)

    Objective-C

    - (void)becomeCurrentWithPendingUnitCount:(int64_t)unitCount

    Parameters

    unitCount

    The number of units of work to be carried out by the next progress object that is initialized by invoking the initWithParent:userInfo: method in the current thread with the receiver set as the parent. This number represents the portion of work to be performed in relation to the total number of units of work to be performed by the receiver (represented by the value of the receiver’s totalUnitCount property). The units of work represented by this parameter must be the same units of work that are used in the receiver’s totalUnitCount property.

    Discussion

    Use this method to build a tree of progress objects, as described in Creating a Tree of Progress Objects.

    Availability

    Available in iOS 7.0 and later.

  • Balance the most recent previous invocation of becomeCurrentWithPendingUnitCount: on the same thread by restoring the current progress object to what it was before becomeCurrentWithPendingUnitCount: was invoked.

    Declaration

    Swift

    func resignCurrent()

    Objective-C

    - (void)resignCurrent

    Discussion

    Use this method after building your tree of progress objects, as described in Creating a Tree of Progress Objects.

    Availability

    Available in iOS 7.0 and later.

  • The total number of units of work tracked for the current progress.

    Declaration

    Swift

    var totalUnitCount: Int64

    Objective-C

    @property int64_t totalUnitCount

    Discussion

    For an NSProgress with a kind of NSProgressKindFile, the unit of this property is bytes while the NSProgressFileTotalCountKey and NSProgressFileCompletedCountKey keys in the userInfo dictionary are used for the overall count of files.

    For any other kind of NSProgress, the unit of measurement does not matter as long as it is consistent. The values may be reported to the user in the localizedDescription and localizedAdditionalDescription.

    Availability

    Available in iOS 7.0 and later.

  • The number of units of work for the current job that have already been completed.

    Declaration

    Swift

    var completedUnitCount: Int64

    Objective-C

    @property int64_t completedUnitCount

    Discussion

    For an NSProgress with a kind of NSProgressKindFile, the unit of this property is bytes while the NSProgressFileTotalCountKey and NSProgressFileCompletedCountKey keys in the userInfo dictionary are used for the overall count of files.

    For any other kind of NSProgress, the unit of measurement does not matter as long as it is consistent. The values may be reported to the user in the localizedDescription and localizedAdditionalDescription.

    Availability

    Available in iOS 7.0 and later.

  • A localized description of progress tracked by the receiver.

    Declaration

    Swift

    var localizedDescription: String!

    Objective-C

    @property(copy) NSString * __null_unspecified localizedDescription

    Discussion

    If you don’t specify your own custom value for this property, NSProgress uses the value of the kind property to determine how to use the values of other properties, as well as values in the user info dictionary, to return an automatically-computed string. If it fails to do that, it returns an empty string.

    The localizedDescription represents a general description of the work tracked by the receiver. Depending on the kind of progress, the completed and total unit counts, and other parameters, example localized descriptions include:

    • Copying 10 files…

    • 30% completed

    • Copying “TextEdit”…

    By default, NSProgress is KVO-compliant for this property, sending notifications on the same thread that updates the property.

    Availability

    Available in iOS 7.0 and later.

  • A more specific localized description of progress tracked by the receiver.

    Declaration

    Swift

    var localizedAdditionalDescription: String!

    Objective-C

    @property(copy) NSString * __null_unspecified localizedAdditionalDescription

    Discussion

    If you don’t specify your own custom value for this property, NSProgress uses the value of the kind property to determine how to use the values of other properties, as well as values in the user info dictionary, to return an automatically-computed string. If it fails to do that, it returns an empty string.

    The localizedAdditionalDescription is more specific than localizedDescription about the work the receiver is tracking at any particular moment. Depending on the kind of progress, the completed and total unit counts, and other parameters, example localized additional descriptions include:

    • 3 of 10 files

    • 123 KB of 789.1 MB

    • 3.3 MB of 103.92 GB – 2 minutes remaining

    • 1.61 GB of 3.22 GB (2 KB/sec) – 2 minutes remaining

    • 1 minute remaining (1 KB/sec)

    By default, NSProgress is KVO-compliant for this property, sending notifications on the same thread that updates the property.

    Availability

    Available in iOS 7.0 and later.

  • The fraction of the overall work completed by this progress object, including work done by any children it may have. (read-only)

    Declaration

    Swift

    var fractionCompleted: Double { get }

    Objective-C

    @property(readonly) double fractionCompleted

    Discussion

    If the receiver object does not have any children, fractionCompleted is generally the result of dividing completedUnitCount by totalUnitCount.

    If the receiver does have children, fractionCompleted will reflect progress made in child objects in addition to its own completedUnitCount. When children finish, the completedUnitCount of the parent is updated.

    Availability

    Available in iOS 7.0 and later.

  • Indicates whether the receiver is tracking work that can be cancelled.

    Declaration

    Swift

    var cancellable: Bool

    Objective-C

    @property(getter=isCancellable) BOOL cancellable

    Discussion

    By default, NSProgress objects are cancellable.

    You typically use this property to communicate whether controls for canceling should appear in a progress reporting user interface. NSProgress itself does not do anything with this property other than help pass the value from progress reporters to progress observers.

    If an NSProgress is cancellable, you should implement the ablity to cancel progress either by setting a block for the cancellationHandler property, or by polling the cancelled property periodically while performing the relevant work.

    It is valid for the value of this property to change during the lifetime of an NSProgress object. By default, NSProgress is KVO-compliant for this property, sending notifications on the same thread that updates the property.

    Availability

    Available in iOS 7.0 and later.

  • Indicates whether the receiver is tracking work that has been cancelled. (read-only)

    Declaration

    Swift

    var cancelled: Bool { get }

    Objective-C

    @property(readonly, getter=isCancelled) BOOL cancelled

    Discussion

    By default, NSProgress is KVO-compliant for this property, sending notifications on the same thread that updates the property.

    If the receiver has a parent that has already been cancelled, the receiver will also report being cancelled.

    Availability

    Available in iOS 7.0 and later.

  • Cancel progress tracking.

    Declaration

    Swift

    func cancel()

    Objective-C

    - (void)cancel

    Discussion

    This method invokes the block set for cancellationHandler, if there is one, and ensures that any subsequent reads of the cancelled property return YEStrue.

    If the receiver has any children, those children will also be cancelled.

    Availability

    Available in iOS 7.0 and later.

  • The block to invoke when progress is cancelled.

    Declaration

    Swift

    var cancellationHandler: (() -> Void)?

    Objective-C

    @property(copy) void (^ )(void) cancellationHandler

    Discussion

    If the receiver is a child of another progress object, the cancellationHandler block will be invoked when the parent is cancelled.

    Special Considerations

    The cancellation handler may be invoked on any queue. If you must do work on a specific queue, you should dispatch to that queue from within the cancellation handler block.

    Availability

    Available in iOS 7.0 and later.

  • Indicates whether the receiver is tracking work that can be paused.

    Declaration

    Swift

    var pausable: Bool

    Objective-C

    @property(getter=isPausable) BOOL pausable

    Discussion

    By default, NSProgress objects are not pausable.

    You typically use this property to communicate whether controls for pausing should appear in a progress reporting user interface. NSProgress itself does not do anything with this property other than help pass the value from progress reporters to progress observers.

    If an NSProgress is pausable, you should implement the ability to pause either by setting a block for the pausingHandler property, or by polling the paused property periodically while performing the relevant work.

    It is valid for the value of this property to change during the lifetime of an NSProgress object. By default, NSProgress is KVO-compliant for this property, sending notifications on the same thread that updates the property.

    Availability

    Available in iOS 7.0 and later.

  • Indicates whether the receiver is tracking work that has been paused. (read-only)

    Declaration

    Swift

    var paused: Bool { get }

    Objective-C

    @property(readonly, getter=isPaused) BOOL paused

    Discussion

    By default, NSProgress is KVO-compliant for this property, sending notifications on the same thread that updates the property.

    If the receiver has a parent that has already been paused, the receiver will also report being paused.

    Availability

    Available in iOS 7.0 and later.

  • Pause progress tracking.

    Declaration

    Swift

    func pause()

    Objective-C

    - (void)pause

    Discussion

    This method invokes the block set for pausingHandler, if there is one, and ensures that any subsequent reads of the paused property return YEStrue.

    If the receiver has any children, those children will also be paused.

    Availability

    Available in iOS 7.0 and later.

  • The block to invoke when progress is paused.

    Declaration

    Swift

    var pausingHandler: (() -> Void)?

    Objective-C

    @property(copy) void (^ )(void) pausingHandler

    Discussion

    If the receiver is a child of another progress object, the pausingHandler block will be invoked when the parent is paused.

    Special Considerations

    The pausing handler may be invoked on any queue. If you must do work on a specific queue, you should dispatch to that queue from within the pausing handler block.

    Availability

    Available in iOS 7.0 and later.

  • Indicates whether the tracked progress is indeterminate. (read-only)

    Declaration

    Swift

    var indeterminate: Bool { get }

    Objective-C

    @property(readonly, getter=isIndeterminate) BOOL indeterminate

    Discussion

    Progress is indeterminate when the value of either totalUnitCount or completedUnitCount is less than zero.

    Setting both totalUnitCount and completedUnitCount properties to zero indicates that there is no progress to track; in this case, isIndeterminate returns NOfalse and fractionCompleted returns 1.0.

    By default, NSProgress is KVO-compliant for this property, sending notifications on the same thread that updates the property.

    Availability

    Available in iOS 7.0 and later.

  • kind kind Property

    A string identifying the kind of progress being made.

    Declaration

    Swift

    var kind: String?

    Objective-C

    @property(copy) NSString *kind

    Discussion

    This property identifies the kind of progress being made, such as NSProgressKindFile. It can be nil.

    If the value of the localizedDescription property has not previously been set to a non-nil value, the default localizedDescription getter uses the progress kind to determine how to use the values of other properties, as well as values in the user info dictionary, to create a string that is presentable to the user.

    Availability

    Available in iOS 7.0 and later.

  • Set a value in the userInfo dictionary.

    Declaration

    Swift

    func setUserInfoObject(_ objectOrNil: AnyObject?, forKey key: String)

    Objective-C

    - (void)setUserInfoObject:(id nullable)objectOrNil forKey:(NSString * nonnull)key

    Parameters

    objectOrNil

    The object to set for the given key, or nil to remove an existing entry in the dictionary.

    key

    The key to use to store the given object.

    Discussion

    Use this method to set a value in the userInfo dictionary, with appropriate KVO notification for properties whose values can depend on values in the user info dictionary, like localizedDescription.

    Supply a value of nil to remove an existing dictionary entry for a given key.

    Availability

    Available in iOS 7.0 and later.

  • A dictionary of arbitrary values associated with the receiver. (read-only)

    Declaration

    Swift

    var userInfo: [NSObject : AnyObject]? { get }

    Objective-C

    @property(readonly, copy) NSDictionary *userInfo

    Discussion

    A KVO-compliant dictionary that changes in response to setUserInfoObject:forKey:. The dictionary sends all of its KVO notifications on the thread that updates the property.

    Some entries have meanings that are recognized by the NSProgress class itself—see General progress user info dictionary keys, Progress kinds, File operation user info dictionary keys, and File operation kinds.

    Availability

    Available in iOS 7.0 and later.

  • Set values for these keys in the user info dictionary to affect the auto-generated localizedAdditionalDescription string.

    Declaration

    Swift

    let NSProgressEstimatedTimeRemainingKey: String let NSProgressThroughputKey: String

    Objective-C

    NSString *const NSProgressEstimatedTimeRemainingKey; NSString *const NSProgressThroughputKey;

    Constants

    • NSProgressEstimatedTimeRemainingKey

      NSProgressEstimatedTimeRemainingKey

      The corresponding value is an NSNumber instance representing the time remaining, in seconds.

      Available in iOS 7.0 and later.

    • NSProgressThroughputKey

      NSProgressThroughputKey

      The corresponding value is an NSNumber instance indicating the speed of data processing, in bytes per second.

      Available in iOS 7.0 and later.

  • When working with files, set this string for the kind of progress.

    Declaration

    Swift

    let NSProgressKindFile: String

    Objective-C

    NSString *const NSProgressKindFile;

    Constants

    • NSProgressKindFile

      NSProgressKindFile

      The value for the kind property that indicates that the progress is tracking a file operation. If you set this value for the progress kind, you must set a value in the user info dictionary for the NSProgressFileOperationKindKey.

      NSProgress of this kind is assumed to use bytes as the unit of work being done, and the default implementation of localizedDescription takes advantage of that to return more specific text than it could otherwise. The NSProgressFileTotalCountKey and NSProgressFileCompletedCountKey keys in the userInfo dictionary are used for the overall count of files.

      Available in iOS 7.0 and later.

  • Set values for these keys in the user info dictionary to provide more information about file operations for the auto-generated localizedDescription and localizedAdditionalDescription strings.

    Declaration

    Swift

    let NSProgressFileOperationKindKey: String let NSProgressFileTotalCountKey: String let NSProgressFileCompletedCountKey: String

    Objective-C

    NSString *const NSProgressFileOperationKindKey; NSString *const NSProgressFileTotalCountKey; NSString *const NSProgressFileCompletedCountKey;

    Constants

    • NSProgressFileOperationKindKey

      NSProgressFileOperationKindKey

      A value is required for this key in the user info dictionary when the progress kind is set to NSProgressKindFile. The corresponding value must be one of the entries listed in “File operation kinds”.

      Available in iOS 7.0 and later.

    • NSProgressFileTotalCountKey

      NSProgressFileTotalCountKey

      The corresponding value must be an NSNumber containing an integer to represent the total number of files affected. This entry is optional; if you set a value for this key, the auto-generated localizedAdditionalDescription string will make use of it.

      Available in iOS 7.0 and later.

    • NSProgressFileCompletedCountKey

      NSProgressFileCompletedCountKey

      The corresponding value must be an NSNumber containing an integer to represent the number of completed files. This entry is optional; if you set a value for this key, the auto-generated localizedAdditionalDescription string will make use of it.

      Available in iOS 7.0 and later.

  • When tracking file operations with the progress kind set to NSProgressKindFile, you must provide a value for the NSProgressFileOperationKindKey in the user info dictionary. There are four possible values.

    Declaration

    Swift

    let NSProgressFileOperationKindDownloading: String let NSProgressFileOperationKindDecompressingAfterDownloading: String let NSProgressFileOperationKindReceiving: String let NSProgressFileOperationKindCopying: String

    Objective-C

    NSString *const NSProgressFileOperationKindDownloading; NSString *const NSProgressFileOperationKindDecompressingAfterDownloading; NSString *const NSProgressFileOperationKindReceiving; NSString *const NSProgressFileOperationKindCopying;

    Constants

    • NSProgressFileOperationKindDownloading

      NSProgressFileOperationKindDownloading

      The progress is tracking a file download operation.

      Available in iOS 7.0 and later.

    • NSProgressFileOperationKindDecompressingAfterDownloading

      NSProgressFileOperationKindDecompressingAfterDownloading

      The progress is tracking file decompression after a download.

      Available in iOS 7.0 and later.

    • NSProgressFileOperationKindReceiving

      NSProgressFileOperationKindReceiving

      The progress is tracking the receipt of a file from another source.

      Available in iOS 7.0 and later.

    • NSProgressFileOperationKindCopying

      NSProgressFileOperationKindCopying

      The progress is tracking the copying of a file from source to destination.

      Available in iOS 7.0 and later.