iOS 8 扩展的 AFNetworking 后台会话配置

Posted

技术标签:

【中文标题】iOS 8 扩展的 AFNetworking 后台会话配置【英文标题】:AFNetworking Background Session Configuration for iOS 8 Extension 【发布时间】:2014-08-22 02:27:07 【问题描述】:

我目前正在开发一个 ios 8 应用程序扩展,但在最后一个方面遇到了困难。在我的应用程序的其余部分,我使用了一个 AFHTTPSessionManager 子类,我像这样实例化它:

+ (MYAPIClient *)sharedClient 
    static MYAPIClient *_sharedClient = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^
        _sharedClient = [[MYAPIClient alloc] initWithBaseURL:[NSURL URLWithString:kMYBaseURL]];
        _sharedClient.requestSerializer = [[MYAPIRequestSerializer alloc] init];
        _sharedClient.responseSerializer = [[MYAPIResponseSerializer alloc] init];
    );
    return _sharedClient;

当我刚刚使用这个常规 API 客户端时,只是发布一些文本形式的共享扩展工作正常,它有时甚至适用于图像(但通常会失败),但我知道我需要使用后台会话配置。所以我做了一个非常相似的 api 客户端,后台配置设置如下:

+ (MYAPIClient *)sharedBackgroundClient 
    static MYAPIClient *_sharedClient = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^

        NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.me.myapp.backgroundconfiguration"];
        _sharedClient = [[MYAPIClient alloc] initWithBaseURL:[NSURL URLWithString:kMYBaseURL] sessionConfiguration:sessionConfiguration];
        _sharedClient.requestSerializer = [[MYAPIRequestSerializer alloc] init];
        _sharedClient.responseSerializer = [[MYAPIResponseSerializer alloc] init];
    );
    return _sharedClient;

问题是,当我使用这个客户端进行 POST 时,我每次都会收到这些错误。

Aug 21 19:19:07 MY-iPhone Share[6290] <Notice>: Attempted to create a task in a session that has been invalidated
Aug 21 19:19:07 MY-iPhone Share[6290] <Warning>: *** Assertion failure in -[MYAPIClient setDelegate:forTask:], /Users/me/Documents/myproject/myproduct/Pods/AFNetworking/AFNetworking/AFURLSessionManager.m:337
Aug 21 19:19:07 MY-iPhone Share[6290] <Error>: *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: task' 

关于如何让它发挥作用的任何建议?非常感谢。

【问题讨论】:

【参考方案1】:

来自the docs:

如果您的应用扩展程序启动后台 NSURLSession 任务,您还必须设置一个共享容器,该扩展程序及其包含的应用程序都可以访问。使用NSURLSessionConfiguration 类的sharedContainerIdentifier 属性为共享容器指定一个标识符,以便您以后可以访问它。

还有:

如果您尝试使用从应用扩展创建 URL 会话,但未能将此属性设置为有效值,则 URL 会话在创建时无效。

有关设置共享容器的指导,请参阅 Sharing Data with Your Containing App。

在您的示例中,您将添加如下内容:

sessionConfiguration.sharedContainerIdentifier = @“com.me.myapp.containerIdentifier”;

您需要一个用于包含应用的后台会话和一个用于其扩展的后台会话。

【讨论】:

随时提交错误报告以获得更好的错误消息。真的这应该抛出一个异常并告诉你设置属性。 你能分享代码我们如何在分享照片扩展中使用广告网络上传图片 Aaron Brager:嗨,我做了所有这些事情,但仍然没有共享图像。我需要调用两个 api 来共享图像。在第一个 api 中,我上传了图像,我会得到“图像路径”,然后我需要在另一个 api 中发送图像路径。你能帮我解决我的问题吗? @AaronBrager :嗨,我做了所有这些事情,但仍然没有共享图像。我需要调用两个 api 来共享图像。在第一个 api 中,我上传了图像,我会得到“图像路径”,然后我需要在另一个 api 中发送图像路径。你能帮我解决我的问题吗?×评论只能编辑5分钟×评论只能编辑5分钟×评论只能编辑5分钟 您找到解决方案了吗?【参考方案2】:

确保您的 sharedContainerIdentifier 与您为主机应用和扩展应用注册的组标识符相同。

config.sharedContainerIdentifier = @“com.mycompany.myappgroupidentifier”;

您可以在 Xcode 功能项目选项卡中注册组标识符。

【讨论】:

我遇到了与原始海报相同的问题,并且确实为具有相同标识符的应用程序和扩展程序设置了应用程序组。一旦我按照说明更新了共享容器标识符,我现在收到以下错误:任务:<__nscfbackgrounddownloadtask>taskIdentifier:1完成错误:未知错误和任务:<__nscfbackgrounddownloadtask>taskIdentifier:1完成出现错误:失去与后台传输服务的连接 为什么要使用下载任务进行分享?我想你需要一个上传任务 嗯,这是一个动作扩展,不是用来分享的。 @mgcm 我遇到了同样的错误。你有什么解决办法吗?

以上是关于iOS 8 扩展的 AFNetworking 后台会话配置的主要内容,如果未能解决你的问题,请参考以下文章

AFNetworking 进入后台后继续上传

使用 AFNetworking 在 iOS 8 中登录时解析服务器提供未经授权的 (401)

如何在 Xcode 8 和 iOS 10 中使用 AFNetworking 类和 Swift 3 上传图像

swift iOS - AFNetworking扩展 - 使用网址取消请求,需要https://gist.github.com/danielgomezrico/ae53fae471168dde6c

swift iOS - AFNetworking扩展 - 使用网址取消请求,需要https://gist.github.com/danielgomezrico/ae53fae471168dde6c

swift iOS - AFNetworking扩展 - 使用网址取消请求,需要https://gist.github.com/danielgomezrico/ae53fae471168dde6c