Last active
January 4, 2018 17:37
-
-
Save odrobnik/a02ac1e49ff90ec4f8a7 to your computer and use it in GitHub Desktop.
Upload progress reporting NSProgress for NSURLSessionTask
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
public class UploadProgress: NSProgress | |
{ | |
var sessionTask: NSURLSessionTask! | |
required public init(sessionTask: NSURLSessionTask) | |
{ | |
super.init(parent: nil, userInfo: nil) | |
self.sessionTask = sessionTask | |
self.cancellationHandler = { [weak self] in | |
self?.sessionTask?.cancel() | |
} | |
addObserver() | |
updateValues() | |
} | |
deinit | |
{ | |
removeObserver() | |
} | |
func addObserver() | |
{ | |
sessionTask.addObserver(self, forKeyPath: "countOfBytesExpectedToSend", options: NSKeyValueObservingOptions.New, context: nil) | |
sessionTask.addObserver(self, forKeyPath: "countOfBytesSent", options: NSKeyValueObservingOptions.New, context: nil) | |
sessionTask.addObserver(self, forKeyPath: "state", options: NSKeyValueObservingOptions.New, context: nil) | |
} | |
func removeObserver() | |
{ | |
if sessionTask != nil | |
{ | |
sessionTask.removeObserver(self, forKeyPath: "countOfBytesExpectedToSend", context: nil) | |
sessionTask.removeObserver(self, forKeyPath: "countOfBytesSent", context: nil) | |
sessionTask.removeObserver(self, forKeyPath: "state", context: nil) | |
// we can also give up the strong reference | |
sessionTask = nil | |
} | |
} | |
func updateValues() | |
{ | |
self.totalUnitCount = sessionTask.countOfBytesExpectedToSend | |
self.completedUnitCount = sessionTask.countOfBytesSent | |
} | |
override public func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) | |
{ | |
if keyPath == "state" | |
{ | |
if sessionTask.state == .Canceling || sessionTask.state == .Completed | |
{ | |
// we are don with the observing | |
removeObserver() | |
} | |
} | |
else | |
{ | |
updateValues() | |
} | |
} | |
} | |
import ObjectiveC | |
// Declare a global var to produce a unique address as the assoc object handle | |
var UploadProgressAssociatedObjectHandle: UInt8 = 0 | |
public extension NSURLSessionTask | |
{ | |
var uploadProgress: UploadProgress | |
{ | |
get | |
{ | |
if let existingProgress = objc_getAssociatedObject(self, &UploadProgressAssociatedObjectHandle) as? UploadProgress | |
{ | |
return existingProgress | |
} | |
let progress = UploadProgress(sessionTask: self) | |
self.uploadProgress = progress | |
return progress | |
} | |
set | |
{ | |
objc_setAssociatedObject(self, &UploadProgressAssociatedObjectHandle, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) | |
} | |
} | |
} | |
usage: let progress = dataTask.uploadProgress and observe fractionPercentage | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment