Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for NSProgress #97

Open
VilemKurz opened this issue Feb 9, 2016 · 2 comments
Open

Support for NSProgress #97

VilemKurz opened this issue Feb 9, 2016 · 2 comments

Comments

@VilemKurz
Copy link

Please, implement reporting of upload/download progress also via NSProgress. It should not be that hard, and would help tremendously.

http://oleb.net/blog/2014/03/nsprogress/
https://developer.apple.com/videos/play/wwdc2015-232/

@priore
Copy link
Owner

priore commented Feb 17, 2016

We just released the new version 1.26 of the framework 017ccf1

@VilemKurz
Copy link
Author

Thank you for a quick response. Today I tried the 1.26, but I had to revert back, due to NSProgress. In the meantime, I have implemented NSProgress on my own, let me explain how. After that I have some suggestions how to improve SOAPEngine's handling of NSProgress. The food for discussion, hopefully.

1 Create a progress object in a view controller with KVO hooked on this progress object and listening to "fractionCompleted" in order to show progress to the user.

self.progress = NSProgress(totalUnitCount: 1)
self.progress?.becomeCurrentWithPendingUnitCount(1)            
//now fire SOAP request elsewhere
self.progress?.resignCurrent()

2 Here is a fire SOAP request part, elsewhere in the app. Here is created another NSProgress object, with current one from 1. set as parent. This helps to decouple the UI part from the network part of the app.

self.progress = NSProgress.init(parent: NSProgress.currentProgress(), userInfo: [NSProgressFileOperationKindKey: NSProgressFileOperationKindDownloading])
self.progress?.kind = NSProgressKindFile
self.progress?.cancellable = true
self.progress?.cancellationHandler = {
    self.cancelRequest(requestUUID)
    completion(.Cancelled)
    self.progress = nil
}

Then SOAPEngine object is created, configured and fired. I make some last minute changes in

@objc func soapEngine(soapEngine: SOAPEngine!, didBeforeSendingURLRequest request: NSMutableURLRequest!) -> NSMutableURLRequest! {

    /*manually re-creating MTOM multipart request from SOAPEngine-prepared-request
    .....
    ....
    */
    if let bodyLength = request.HTTPBody?.length {
        setProgressTotalUnitCount(Int64(bodyLength))
    }
    return request
}

3 The last step is to update this child NSProgress object in sendedDataSize

sendedDataSize: { (uploaded: UInt, total: UInt) in
                print("uploaded \(uploaded) from \(total) bytes")
                self.progress?.completedUnitCount = Int64(total)  
}

Suggestions:

  1. make sure, that you create your NSProgress object with parent: NSProgress.currentProgress(), so that possible UI clients can be wired automatically
  2. make sure, that you create your NSProgress object until the requestURL.. family of functions return. For parent (="UI client") NSProgress it is crucial to resignCurrent() asap, to avoid possible interferences with system libraries. That is why yours should be created early.
    3 a very nice feature of NSProgress is a decoupled cancelling of the task. It would be nice, if you provided a hook for setting external cancellationHandler.
    4 maybe for those, who have hierarchies of NSProgress objects, or some wild configuration requirements, you might add a possibility to disable your NSProgress object (?)

NSProgress is amazing addition, and it would be great if we figure out how to make the best of it :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants