- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在学习 NSURLSession 以制作自定义网络类,并偶然发现了一个非常不寻常的错误。
我的目标很简单,我想在完成后将 URL 的响应写入文件中。所以我创建了一个下载任务并将其分配给一个defaultSessionConfiguration。在将委托(delegate)分配给配置和不将委托(delegate)分配给配置的两种情况下(在这种情况下完成处理程序起作用)都有效。
现在我转向了backgroundSessionConfigurationWithIdentifier。后台 session 不支持 block ,因此委托(delegate)调用是强制性的。
每次都以错误结束。报错如下
Printing description of error:
Error Domain=NSURLErrorDomain Code=-1 "unknown error" UserInfo={NSErrorFailingURLKey=http://__________________, NSErrorFailingURLStringKey=http://__________________, NSLocalizedDescription=unknown error}
我想我一定是后台配置写错了,所以我通过创建一个下载图像的演示下载任务并将这个任务添加到这个后台 session 来测试它。 这次成功了
下面给出了有效的代码:
+ (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 方法向请求添加 header 。
如果我使用 dataSession 而不是 backgroundSession
,同样失败的代码将起作用Q: 同一个请求在defaultConfiguration中有效,在backgroundSession中失败。我是不是遗漏了什么,或者与 Apple Docs 的“仅支持上传和下载任务(无数据任务)”有关。
最佳答案
后台 session 不关心他们正在下载什么(文件或任意数据或其他)。您只需要使用下载任务或上传任务,而不是数据任务。但你正在这样做。
在没有看到其余代码的情况下,我的猜测是 CustomURLRequest
是 NSURLRequest
的子类。不幸的是,NSURLRequest
的子类不被NSURLSession
支持——尤其是那些实际直接添加属性的子类。在各种版本的 iOS 和 OS X 中,您会遇到的错误从严重到完全损坏不等。我什至见过这样的情况:您从一个请求中取回自定义属性值,同时从另一个完全不同的请求中取回 URL 和 header 。
您应该在 NSURLRequest
上创建一个自定义类别,而不是子类化。在该类别中,创建 getter 和 setter 方法。
[NSURLProtocol propertyForKey:inRequest:]
作为你的 getter。[NSURLProtocol setProperty:forKey:inRequest:]
作为你的 setter。重要:使用这些方法存储在 NSURLRequest
中的所有对象必须是属性列表可序列化的。如果您需要将自定义类的实例与 NSURLRequest
相关联,您应该将它们存储在单独的 NSDictionary
中,并使用任意字典键(例如调用 [[NSUUID UUID] UUIDString]
),您可以安全地将其存储在 NSURLRequest
对象中,稍后用于从外部字典获取自定义类。
关于ios - NSURLSession 后台 session 中的 NSURLSessionDownloadTask 出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40459260/
我正在使用 node.js 和 mocha 单元测试,并且希望能够通过 npm 运行测试命令。当我在测试文件夹中运行 Mocha 测试时,测试运行成功。但是,当我运行 npm test 时,测试给出了
我的文本区域中有这些标签 ..... 我正在尝试使用 replaceAll() String 方法替换它们 text.replaceAll("", ""); text.replaceAll("", "
早上好,我是 ZXing 的新手,当我运行我的应用程序时出现以下错误: 异常Ljava/lang/NoClassDefFoundError;初始化 ICOM/google/zxing/client/a
我正在制作一些哈希函数。 它的源代码是... #include #include #include int m_hash(char *input, size_t in_length, char
我正在尝试使用 Spritekit 在 Swift 中编写游戏。目的是带着他的角色迎面而来的矩形逃跑。现在我在 SKPhysicsContactDelegate (didBegin ()) 方法中犯了
我正在尝试创建一个用于导入 CSV 文件的按钮,但出现此错误: actionPerformed(java.awt.event.ActionEvent) in cannot implement
请看下面的代码 public List getNames() { List names = new ArrayList(); try { createConnection(); Sta
我正在尝试添加一个事件以在“dealsArchive”表中创建一个条目,然后从“deals”表中删除该条目。它需要在特定时间执行。 这是我正在尝试使用的: DELIMITER $$ CREATE EV
我试图将两个存储过程的表结果存储到 phpmyadmin 例程窗口中的单个表中,这给了我 mariadb 语法错误。单独调用存储过程给出了结果。 存储过程代码 BEGIN CREATE TABLE t
我想在 videoview 中加载视频之前有一个进度条。但是我收到以下错误。我还添加了所有必要的导入。 我在 ANDROID 中使用 AIDE 这是我的代码 public class MainActi
我已经使用了 AsyncTask,但我不明白为什么在我的设备 (OS 4.0) 上测试时仍然出现错误。我的 apk 构建于 2.3.3 中。我想我把代码弄错了,但我不知道我的错误在哪里。任何人都请帮助
我在测试 friend 网站的安全性时,通过在 URL 末尾添加 ' 发现了 SQL 注入(inject)漏洞该网站是用zend框架构建的我遇到的问题是 MySQL -- 中的注释语法不起作用,因此页
我正在尝试使用堆栈溢出答案之一的交互式信息窗口。 链接如下: interactive infowindow 但是我在代码中使用 getMap() 时遇到错误。虽然我尝试使用 getMapAsync 但
当我编译以下代码时出现错误: The method addMouseListener(Player) is undefined for the type Player 代码: import java.
我是 Android 开发的初学者。我正在开发一个接收 MySql 数据然后将其保存在 SQLite 中的应用程序。 我将 Json 用于同步状态,以便我可以将未同步数据的数量显示为要同步的待处理数据
(这里是Hello world级别的自动化测试人员) 我正在尝试下载一个文件并将其重命名以便于查找。我收到一个错误....这是代码 @Test public void allDownload(
我只是在写另一个程序。并使用: while (cin) words.push_back(s); words是string的vector,s是string。 我的 RAM 使用量在 4 或 5
我是 AngularJS 的新手,我遇到了一个问题。我有一个带有提交按钮的页面,当我单击提交模式时必须打开并且来自 URL 的数据必须存在于模式中。现在,模式打开但它是空的并且没有从 URL 获取数据
我正在尝试读取一个文件(它可以包含任意数量的随机数字,但不会超过 500 个)并将其放入一个数组中。 稍后我将需要使用数组来做很多事情。 但到目前为止,这一小段代码给了我 no match for o
有些人在使用 make 命令进行编译时遇到了问题,所以我想我应该在这里尝试一下,我已经在以下操作系统的 ubuntu 32 位和挤压 64 位上尝试过 我克隆了 git 项目 https://gith
我是一名优秀的程序员,十分优秀!