NSURLSession didCompleteWithError: how to determine which task?

I have a class that corresponds to NSURLSession delegates for loading data and has a problem when calling more than one service when the func URLSession method call is completed (session: NSURLSession, task: NSURLSessionTask, doCompleteWithError error: NSError?), The results are analyzed and processed here to return to correct view controller.

How do I know from which session or task the results were obtained, so I can call the correct view controller?

import Foundation class Support{ // MARK - Properties var ID: Int! var SoftekID: String! var Subject: String! var LastUpdate: String! var LastUpdatedBy: String! var Priority: Int! var Impact: Int! var SupportType: String! var Importance: Int! // MARK: General init() { self.ID = 0 self.SoftekID = "" self.Subject = "" self.LastUpdate = "" self.LastUpdatedBy = "" self.Priority = 0 self.Impact = 0 self.SupportType = "" self.Importance = 0 } func getSupportTickets(){ let sp = SuppportProvider() sp.getSupportTickets() } } class SuppportProvider: NSObject, NSURLSessionDelegate, NSURLSessionDataDelegate, NSURLSessionTaskDelegate{ // MARK: - Properties var mData: NSMutableData? var session: NSURLSession! override init(){ super.init() prepareConnection() } // MARK: - Methods func prepareConnection(){ session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: self, delegateQueue:nil) } func getSupportTickets(){ var request = NSMutableURLRequest(URL: NSURL(string: "http://10.0.58.137/ISOWeb.UI/api/CSMobile/GetSupportTickets?PageNumber=0&PagingSize=10&TicketStatus=Priority")!, cachePolicy: NSURLRequestCachePolicy.UseProtocolCachePolicy, timeoutInterval: 20.0) let task = session.dataTaskWithRequest(request) mData = NSMutableData() task.resume() } func getHelpInformation(){ var request = NSMutableURLRequest(URL: NSURL(string: "http://10.0.58.137/ISOWeb.UI/api/CSMobile/GetHelpInformation")!, cachePolicy: NSURLRequestCachePolicy.UseProtocolCachePolicy, timeoutInterval: 20.0) let task = session.dataTaskWithRequest(request) mData = NSMutableData() task.resume() } func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) { mData!.length = 0 completionHandler(NSURLSessionResponseDisposition.Allow) } func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) { mData!.appendData(data) } func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) { if error != nil{ println("An error has occured completing the request") }else{ //Result for method: getSupportTickets var value = NSString(bytes: mData!.mutableBytes, length: mData!.length, encoding: NSUTF8StringEncoding) var jError: NSError? if let JSONResult: Array<NSDictionary> = NSJSONSerialization.JSONObjectWithData(mData!, options: NSJSONReadingOptions.AllowFragments, error: &jError) as? Array<NSDictionary> { if JSONResult.count > 0 { var arr = Array<Support>() for dict in JSONResult{ let item = Support() if (dict["ID"] as? Int != nil) { item.ID = dict["ID"] as! Int }else { item.ID = 0 } if (dict["SoftekID"] as? String != nil) { item.SoftekID = dict["SoftekID"] as! String }else { item.SoftekID = "" } if (dict["Subject"] as? String != nil) { item.Subject = dict["Subject"] as! String }else { item.Subject = "" } if (dict["LastUpdate"] as? String != nil) { item.LastUpdate = dict["LastUpdate"] as! String }else { item.LastUpdate = "" } if (dict["LastUpdatedBy"] as? String != nil) { item.LastUpdatedBy = dict["LastUpdatedBy"] as! String }else { item.LastUpdatedBy = "" } if (dict["Priority"] as? Int != nil) { item.Priority = dict["Priority"] as! Int }else { item.Priority = 0 } if (dict["Impact"] as? Int != nil) { item.Impact = dict["Impact"] as! Int }else { item.Impact = 0 } if (dict["SupportType"] as? String != nil) { item.SupportType = dict["SupportType"] as! String }else { item.SupportType = "" } if (dict["Importance"] as? Int != nil) { item.Importance = dict["Importance"] as! Int }else { item.Importance = 0 } arr.append(item) } } } //Result for method: getHelpInformation //How to know to which task holds the result? } } } 

UPDATE

 import Foundation class CSSupport{ // MARK - Properties var ID: Int! var SoftekID: String! var Subject: String! var LastUpdate: String! var LastUpdatedBy: String! var Priority: Int! var Impact: Int! var SupportType: String! var Importance: Int! // MARK: General init() { self.ID = 0 self.SoftekID = "" self.Subject = "" self.LastUpdate = "" self.LastUpdatedBy = "" self.Priority = 0 self.Impact = 0 self.SupportType = "" self.Importance = 0 } } class Support:NSObject, NSURLSessionDelegate, NSURLSessionDataDelegate, NSURLSessionTaskDelegate{ // MARK: - Properties var mData: NSMutableData? var session: NSURLSession! override init(){ super.init() var configuration = NSURLSessionConfiguration.defaultSessionConfiguration() session = NSURLSession(configuration:configuration, delegate: self, delegateQueue:nil) } // MARK: - Methods func getSupportTickets(){ var request = NSMutableURLRequest(URL: NSURL(string: "http://10.0.58.137/ISOWeb.UI/api/CSMobile/GetSupportTickets?PageNumber=0&PagingSize=10&TicketStatus=Priority")!, cachePolicy: NSURLRequestCachePolicy.UseProtocolCachePolicy, timeoutInterval: 20.0) let task = session.dataTaskWithRequest(request) mData = NSMutableData() task.resume() } func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) { mData!.length = 0 completionHandler(NSURLSessionResponseDisposition.Allow) } func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) { mData!.appendData(data) } func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) { if error != nil{ println("An error has occured completing the request") }else{ var value = NSString(bytes: mData!.mutableBytes, length: mData!.length, encoding: NSUTF8StringEncoding) var jError: NSError? switch task.taskIdentifier { case 1: if let JSONResult: Array<NSDictionary> = NSJSONSerialization.JSONObjectWithData(mData!, options: NSJSONReadingOptions.AllowFragments, error: &jError) as? Array<NSDictionary> { if JSONResult.count > 0 { var arr = Array<CSSupport>() for dict in JSONResult{ let item = CSSupport() if (dict["ID"] as? Int != nil) { item.ID = dict["ID"] as! Int }else { item.ID = 0 } if (dict["SoftekID"] as? String != nil) { item.SoftekID = dict["SoftekID"] as! String }else { item.SoftekID = "" } if (dict["Subject"] as? String != nil) { item.Subject = dict["Subject"] as! String }else { item.Subject = "" } if (dict["LastUpdate"] as? String != nil) { item.LastUpdate = dict["LastUpdate"] as! String }else { item.LastUpdate = "" } if (dict["LastUpdatedBy"] as? String != nil) { item.LastUpdatedBy = dict["LastUpdatedBy"] as! String }else { item.LastUpdatedBy = "" } if (dict["Priority"] as? Int != nil) { item.Priority = dict["Priority"] as! Int }else { item.Priority = 0 } if (dict["Impact"] as? Int != nil) { item.Impact = dict["Impact"] as! Int }else { item.Impact = 0 } if (dict["SupportType"] as? String != nil) { item.SupportType = dict["SupportType"] as! String }else { item.SupportType = "" } if (dict["Importance"] as? Int != nil) { item.Importance = dict["Importance"] as! Int }else { item.Importance = 0 } arr.append(item) } } } break case 2: break default: println("No task was found.") break } } } } 
+4
source share
3 answers

Yes, the absence of any custom repository is annoying, especially because the identifier is unique only for each session. There are several ways to handle this:

  • If you use background sessions or a mixture of foreground and background, I think the best you can do is a two-level search, in which you associate a mutable dictionary with each session and look up, first complete the session, then find the task by its identifier in the dictionary for each session:

    • For background sessions, specify the identifier to use as the key in top-level mutable dictionaries.
    • For other sessions, use the session object itself as a key in a mutable top-level dictionary dictionary.
  • If you use only foreground tasks (and not in the background session, that is), you should simply use the tasks as dictionary keys and look for additional data related to the tasks.

I think that both of these methods should work correctly. You can also use related objects in a task to store additional data (while you are not working with background sessions).

One thing you definitely can't do (I already posted an error about this) is a subclass of NSURLRequest and stores extra data there because NSURLSession returns its own copy of NSURLRequest (and not your custom subclass) when you request currentRequest, and returns A random case of your subclass (not related to the actual original request) when you request orginalRequest.

It's amazing how much effort everyone should spend on creating external dictionaries in order to get around the lack of a simple refCon object property for each task and each session. Of course, it’s worth writing an error to ask about this feature.

+3
source

Why not use your own custom string identifier in taskDescription, which is a member of NSURLSessionTask?

+3
source

All Articles