You can use "callbacks", either using Delegation design pattern
https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html
Or Swift's closures (Objective-C blocks)
You can return a "closure" from the function, this closure creates the progress. To be used on the view/viewController
func addProgressBar() -> (UIView) -> () {
return { view in
let rect = CGRect(x: 10, y: 70, width: 250, height: 0)
let progressView = UIProgressView(frame: rect)
progressView.progress = 0.0
progressView.tintColor = UIColor.blue
view.addSubview(progressView)
}
}
Then use this return value, in the view controller for example:
(networkHelper.addProgressBar())(self.view)
The is if you want to make the progress view on the view controller, and manage it there.
class NetworkHelper {
...
func doAnythingWithNetwork(withProgress: @escaping (NSProgress) -> (),
completion: @escaping (Data?, Error?) -> ()) {
...
// When you get any progress (like in Alamofire for example).
// Pass it to the callback
withProgress(progress)
...
}
}
Then in your viewController:
let networker = NetworkHelper()
...
@IBAction func buttonClicked(_ sender: Any?) {
networker.doAnythingWithNetwork(withProgress: { [weak self] progress in
// You can use your viewController here (note: use 'self?', not
// 'self', here self is "weak", only to avoid memory leaks).
// Note: Any update of the view must be in DispatchQueue.main
}, completion: { [weak self] data, error in
// Your usual completion handler.
})
}
But the recommended solution is to make your NetworkHelper
just a model, just to handle web requests and data. SOLID principles has a "Single Responsibility Principle", i.e. Design each object to have only one single responsibility.
The view (or viewcontroller) should handle the addProgressBar
, and the NetworkHelper should pass this progress via a delegate or closure/block to the viewcontroller where the view is updated.