I am learning NSURLSession to make a custom network class and stumbled upon a very unusual error.
My aim is simple, I want to write the response of a URL in a file, once completed. So I created a download task and assigned it to a defaultSessionConfiguration. In both cases of assigning delegate to the configuration and not assigning delegate to configuration (in which case the completion handler works) works.
Now I shifted to backgroundSessionConfigurationWithIdentifier. Background sessions don't support blocks , so delegate call is mandatory.
Every time it ends up in error . The error is given below
Printing description of error:
Error Domain=NSURLErrorDomain Code=-1 "unknown error" UserInfo={NSErrorFailingURLKey=http://__________________, NSErrorFailingURLStringKey=http://__________________, NSLocalizedDescription=unknown error}
I thought I must have written the background Configuration wrong , so I tested it by creating a demo download task to download an image and adding this task to this background session. It works this time
The code that works is given below :
+ (CustomNetwork *)sharedNetworkObject
{
if(!netWorkObj)
{
netWorkObj = [[CustomNetwork alloc] init];
//[netWorkObj prepareDataSession];
//[netWorkObj prepareBackgroundSession];
}
return netWorkObj;
}
//
+ (NSOperationQueue *)responseQueue
{
if(!queue)
{
queue = [[NSOperationQueue alloc] init];
}
return queue;
}
- (void)prepareDataSession
{
if(!dataSession)
{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
configuration.HTTPMaximumConnectionsPerHost = 5; // This means 1 session can hold to 5 connections
configuration.timeoutIntervalForRequest = CONNECTION_TIME_OUT;
configuration.timeoutIntervalForResource = CONNECTION_TIME_OUT;
dataSession = [NSURLSession sessionWithConfiguration:configuration
delegate:nil //[CustomNetwork sharedNetworkObject]
delegateQueue:nil];
}
}
- (void)prepareBackgroundSession
{
if(!backgroundSession)
{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"backgroundSession"];
configuration.HTTPMaximumConnectionsPerHost = 5; // This means 1 session can hold to 5 connections
configuration.timeoutIntervalForRequest = CONNECTION_TIME_OUT;
configuration.timeoutIntervalForResource = CONNECTION_TIME_OUT;
configuration.discretionary = NO;// For optimizing
backgroundSession = [NSURLSession sessionWithConfiguration:configuration
delegate:[CustomNetwork sharedNetworkObject]
delegateQueue:nil];
}
}
+ (void)demoBackGroundSessionWorks
{
NSURL * url = [NSURL URLWithString:@"https://www.wallpapereast.com/static/images/wallpaper-photos-42.jpg"];//@"http://www.hdwallpapersinn.com/wp-content/uploads/2012/09/HD-Wallpaper-1920x1080.jpg"];
//NSURLSessionConfiguration * backgroundConfig = [NSURLSessionConfiguration backgroundSessionConfiguration:@"backgroundtask1"];
[[CustomNetwork sharedNetworkObject] prepareBackgroundSession];
NSURLSessionDownloadTask * downloadTask =[backgroundSession downloadTaskWithURL:url];
[downloadTask resume];
}
The code that fails is given :
+(void)createDownloadConnectionWithUrl:(NSString *)aUrl
operationKey:(NSString *)operationKey
jsonParam:(NSString *)jsonString
HTTPMethod:(NSString *)method
startImmediate:(BOOL)startImmediate
downloadPath:(NSString *)downloadPath
{
if([[aUrl trimmedString] length] && [self isValidMethod:method] && [[downloadPath trimmedString] length])
{
CustomURLRequest *dataRequest = [CustomNetwork requestURLWithString:aUrl];
dataRequest.downloadDestinationPath = downloadPath;
[self prepareTheDataRequest:&dataRequest
WithParameters:&jsonString
ForMethod:&method
andOpertaionKey:operationKey];
// Remove any file if present in the path
if([[NSFileManager defaultManager] fileExistsAtPath:downloadPath])
{
[[NSFileManager defaultManager] removeItemAtPath:downloadPath error:nil];
}
// PS : if you are using BackGroundSession, completion block wont work and will give to a NSGenericException. Reason: 'Completion handler blocks are not supported in background sessions. Use a delegate instead.'
[[CustomNetwork sharedNetworkObject] prepareBackgroundSession];
NSURLSessionDownloadTask *downloadTask = [backgroundSession downloadTaskWithRequest:dataRequest];
if(startImmediate)
{
[downloadTask resume];
}
}
The prepare method adds headers to the request.
The very same code that fails , will work if I use dataSession instead of backgroundSession
Q: The same request works in defaultConfiguration but fails in backgroundSession. Am I missing something or is it something to do with "Only upload and download tasks are supported (no data tasks)" doctrine of Apple Docs.