I need to find out progress of an upload task. But I can only use the URLSession's dataTask
method (instead of uploadTask
method) to create the task. I can't use delegate initializer to create the session also. To find the progress I'm using KVO on the URLSessionDataTask's progress variable as in the code below.
But I'm getting KVO value starting from 0.95 only (not from 0). Appreciate any help on how to find the progress in this case.
I'm using this sample code, and changed it for my needs:
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, URLSessionDelegate, URLSessionTaskDelegate, URLSessionDataDelegate {
private var progressKVOContext = 0
@IBOutlet weak var myImageView: UIImageView!
@IBOutlet weak var uploadButton: UIButton!
@IBOutlet weak var imageUploadProgressView: UIProgressView!
@IBOutlet weak var progressLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func uploadButtonTapped(_ sender: AnyObject) {
let myPickerController = UIImagePickerController()
myPickerController.delegate = self;
myPickerController.sourceType = UIImagePickerControllerSourceType.photoLibrary
self.present(myPickerController, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [AnyHashable: Any])
{
myImageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage
myImageView.backgroundColor = UIColor.clear
self.dismiss(animated: true, completion: nil)
uploadImage()
}
func uploadImage()
{
let imageData = UIImageJPEGRepresentation(myImageView.image!, 1)
if(imageData == nil ) { return }
self.uploadButton.isEnabled = false
let uploadScriptUrl = URL(string:"http://www.swiftdeveloperblog.com/http-post-example-script/")
var request = URLRequest(url: uploadScriptUrl!)
request.httpMethod = "POST"
request.setValue("Keep-Alive", forHTTPHeaderField: "Connection")
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration)
let task = session.dataTask(with: request) { (data, urlResp, error) in
print("\(String(describing: data))")
}
if #available(iOS 11.0, *) {
task.progress.addObserver(self, forKeyPath: #keyPath(Progress.fractionCompleted), options: [.new], context: &progressKVOContext)
print("KVO set here")
} else {
// Fallback on earlier versions
}
task.resume()
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if context == &progressKVOContext && keyPath == #keyPath(Progress.fractionCompleted), let progress = object as? Progress {
var progressFractionCompleted = (progress.totalUnitCount == -1) ? 1.0 : progress.fractionCompleted
if progressFractionCompleted == 1 {
print("progressFractionCompleted here = \(progressFractionCompleted)")
// try? removeObserver(self, forKeyPath: #keyPath(Progress.fractionCompleted), context: &progressKVOContext)
}
if progressFractionCompleted > 1 {
print("Inside greater \(progressFractionCompleted)")
progressFractionCompleted = 1/progressFractionCompleted
}
print("progressFractionCompleted = \(progressFractionCompleted)")
} else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}
}