【发布时间】:2016-11-07 06:44:34
【问题描述】:
我正在学习 NSURLSession 来制作一个自定义网络类,并偶然发现了一个非常不寻常的错误。
我的目标很简单,一旦完成,我想将 URL 的响应写入文件中。所以我创建了一个下载任务并将其分配给一个defaultSessionConfiguration。在将委托分配给配置和不将委托分配给配置的两种情况下(在这种情况下完成处理程序工作)都有效。
现在我转到 backgroundSessionConfigurationWithIdentifier。后台会话不支持 blocks ,因此必须调用委托。
每次都会出错。 错误如下所示
Printing description of error:
Error Domain=NSURLErrorDomain Code=-1 "unknown error" UserInfo={NSErrorFailingURLKey=http://__________________, NSErrorFailingURLStringKey=http://__________________, NSLocalizedDescription=unknown error}
我想我一定是后台配置写错了,所以我通过创建一个演示下载任务来下载图像并将这个任务添加到这个后台会话中来测试它。 这次成功了
有效的代码如下:
+ (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];
}
给出失败的代码:
+(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];
}
}
prepare 方法将标头添加到请求中。
如果我使用 dataSession 而不是 backgroundSession
,同样的代码会失败问:同样的请求在 defaultConfiguration 中有效,但在 backgroundSession 中失败。我是否遗漏了什么,或者与 Apple Docs 的“仅支持上传和下载任务(无数据任务)”学说有关。
【问题讨论】:
-
您不能将
data task与backgroundsessionconfiguration一起使用,因为您必须将fileurl提供给upload from或download to。显示您的代码,以便有人可以提供帮助! -
我已经添加了一些代码,但仍然不是很清楚。如果我想下载数据响应,BackgroundSessions 将不起作用,但如果我想下载图像或文件,BackgroundSessions 将起作用?
-
如果您使用默认会话配置而不是后台调用
createDownloadConnectionWithUrl会发生什么? -
当我使用 defaultConfiguration 时它可以工作。调用委托方法 - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location 并在“location”中创建 *.tmp 文件
标签: ios objective-c nsurlsession