While the code I wrote works perfectly, a lot of it based on many different tutorials. Am now in the "cleaning up phase", so am wondering if I need section 2 in the following?
At the top of my UIViewController, (myMain) I have the following lines:
1- let uploadService = UploadService()
2- lazy var uploadSession: URLSession = {
let configuration = URLSessionConfiguration.default
return URLSession(configuration: configuration, delegate: self,
delegateQueue: .main)
}()
Later in the my code, when it's time to send a POST request I proceed from the "upload" button in myView:
uploadService.start(upFile: xFile!, script: "uploadOrig.pl", myView: self)
The UploadService is:
class UploadService {
var uploadSession = URLSession.shared
func start(upFile: XFile, script: String, myView: UploadInv) {
var request = upFile.makeUrlReq(upFile: upFile, script: script)
uploadSession.uploadTask(with: request, from: request.httpBody )
{ (data, response, error) in
if let response = response {
myView.upResp(resp: response) }
if let error = error {
myView.upErr(error: error) }
if let data = data {
myView.upData(data: data) }
}.resume()
}}
All the methods inside of myView that are called by UploadClass, are wrapped in :
DispatchQueue.main.async { [self] in
do { ... }
So my uncertainty is this:
The class that handles the uploading has its own completion handler, ergo I don't believe I need to set a delegate. As well, Swift runs it on a background thread automatically.
Everything works, whether I comment out section 2 above or not. But that doesn't mean that both ways are correct.
Must I set the delegate and delegateQueue? Or may I keep it commented out and allow the Upload?
CodePudding user response:
There are two separate questions:
Do you need
uploadSession
defined where you have it?No. If you can comment it out and your code still compiles, that means you’re not using it anywhere and that you can, and should, remove it entirely. You do not want unused code in your project.
Besides, if you did need a custom
URLSession
instance, it seems thatUploadService
might be a more logical place to keep it. We generally strive for highly cohesive objects and clear separation of responsibilities, and you probably want to keep all of your networking code in a network layer, not scattered about in your project.The
UploadService
has its ownURLSession
. Should you use.shared
or define your ownURLSession
instance with its own configuration and delegate?If you don’t need to customize your
URLSession
at all, then using.shared
is fine and is easiest. I would only suggest introducing your own customURLSession
instance if you need one of those features.But if you are not implementing any delegate methods, then, no, you do not need to (nor would you want to) introduce a delegate that does nothing. It just makes the code harder to read.
So, when might you want to use your own URLSession
instance? There are a variety of situations. See “Types of URL Sessions” and “Using a Session Delegate” in the documentation for a few examples of when you might do that. Personally, I only use custom URLSession
instances when doing background URLSession
requests that need to continue to run when I leave the app. Or I need progress reporting. Or in those rare situations where I want to customize the URLSessionConfiguration
.
But manually instantiating URLSession
instances requires a little more housekeeping (e.g., you have to “finish and invalidate” them when you’re done with them or else you will leak). And delegate-based URLSession
is a little more complicated than the completion-handler or the Swift concurrency renditions, so only do that where needed.
Delegate-based URLSession
provides richer set of features (special handling of redirects, custom authentication challenge authentication, progress reporting, etc.), but it comes at the cost of greater code complexity. I would advise only introducing this complexity where you need the additional functionality.