Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/101.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios NSURLSession backgroundSession完成时的附加API调用_Ios_Amazon S3_Nsurlsession_Nsurlsessiondownloadtask_Nsurlsessionuploadtask - Fatal编程技术网

Ios NSURLSession backgroundSession完成时的附加API调用

Ios NSURLSession backgroundSession完成时的附加API调用,ios,amazon-s3,nsurlsession,nsurlsessiondownloadtask,nsurlsessionuploadtask,Ios,Amazon S3,Nsurlsession,Nsurlsessiondownloadtask,Nsurlsessionuploadtask,我需要通过PUT将内容上传到AWS S3,该PUT可以使用NSURLSessionUploadTask在后台会话中运行 到目前为止效果很好。然而,我需要在S3的上传完成后调用API,将其状态更改为完成 我使用AWSS3创建S3请求,然后根据将其复制到NSURLSessionPloadTask。这将在前台和后台运行,并将文件ok上传到S3 这就是我需要帮助的部分。我尝试使用URLSession:task:didcompletewitheror和urlsessiondifinisheventsfor

我需要通过PUT将内容上传到AWS S3,该PUT可以使用NSURLSessionUploadTask在后台会话中运行

到目前为止效果很好。然而,我需要在S3的上传完成后调用API,将其状态更改为完成

我使用AWSS3创建S3请求,然后根据将其复制到NSURLSessionPloadTask。这将在前台和后台运行,并将文件ok上传到S3

这就是我需要帮助的部分。我尝试使用URLSession:task:didcompletewitheror和urlsessiondifinisheventsforbackgroundurlsession委托方法来调用我的附加API请求,我使用了标准数据任务和下载任务,在我再次打开应用程序之前,它们似乎不会在后台触发请求。理想情况下,我希望他们立即开火。他们做的火的上传是在前台。我看到过神童主义者做的正是我在幕后想做的,不知道他们是怎么做的

这是我到目前为止所拥有的。。。任何帮助/建议都会令人惊讶,这让我发疯了!:)

AppDelegate.h

- (void)application:(UIApplication *)application
handleEventsForBackgroundURLSession:(NSString *)identifier
completionHandler:(void (^)())completionHandler {
}
编辑我还尝试了以下方法。任务像以前一样被创建,当我恢复任务时仍然不会触发

然后在视图控制器中

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [[NSNotificationCenter defaultCenter]
     addObserver:self
     selector:@selector(handleBackgroundTransfer:)
     name:@"BackgroundTransferNotification"
     object:nil];
}

- (void)handleBackgroundTransfer:(NSNotification *)notification {
    // handle the API call as shown in original example
    ...
}

如果后台任务在应用程序未运行时完成,则必须在AppDelegate中处理它,而您似乎没有这样做

像这样的方法应该会奏效:

- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {

    // the identifier you used to create the background session
    NSString *identifier = [NSString stringWithFormat:@"com.journeyhq.backgroundSession.%@-%@", @"S3", @"ATTACHMENT_REMOTE_ID"];

    if ([identifier isEqualToString:identifier]) {
        // call your API here
    }

    // call the handler block so the app can exit again
    completionHandler();    
}

正如
NSURLSessiondFinisheventsforBackgroundUrlSession
的文档所述:

在iOS中,当后台传输完成或需要凭据时,如果您的应用程序不再运行,您的应用程序将自动在后台重新启动,并且应用程序的
UIApplicationLegate
将发送一条
application:handleEventsForBackgroundURLSession:completionHandler:
消息。此调用包含导致启动应用程序的会话的标识符。然后,在创建具有相同标识符的后台配置对象以及使用该配置创建会话之前,应用程序应该存储该完成处理程序。新创建的会话将自动与正在进行的后台活动重新关联

当您的应用程序稍后收到
urlsessiondFinisheventsforBackgroundUrlSession:
消息时,这表示以前排队等待此会话的所有消息都已传递,现在可以安全地调用以前存储的完成处理程序,或者开始任何可能导致调用完成处理程序的内部更新

因此,
handleEventsForBackgroundURLSession
应该保存
completionHandler
并重新初始化background
NSURLSession
。然后,
urlsessiondifinisheventsforbackgroundurlsession
应调用该
completionHandler


当你的应用程序被重新唤醒并调用
handleEventsForBackgroundURLSession
时,我看不到你在任何地方重新实例化后台会话。我也看不到您实现了一个
urlsessiondifinisheventsforbackgroundurlsession
,它将调用
completionHandler

谢谢您的回复Hugo。我以前确实尝试过,虽然不是直接在应用程序委托内部,但通过handleEventsForBackgroundURLSession内部触发的通知,然后在视图控制器中进行处理。不幸的是,结果是一样的。它会创建任务,但不会启动,即使我在任务上调用resume,除非我打开应用程序,然后任务运行。我直接在handleEventsForBackgroundURLSession中尝试了它,但仍然没有启动。请将您尝试过的代码发布到app delegate方法中,好吗?您解决过这个问题吗?我也有同样的问题
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [[NSNotificationCenter defaultCenter]
     addObserver:self
     selector:@selector(handleBackgroundTransfer:)
     name:@"BackgroundTransferNotification"
     object:nil];
}

- (void)handleBackgroundTransfer:(NSNotification *)notification {
    // handle the API call as shown in original example
    ...
}
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {

    // the identifier you used to create the background session
    NSString *identifier = [NSString stringWithFormat:@"com.journeyhq.backgroundSession.%@-%@", @"S3", @"ATTACHMENT_REMOTE_ID"];

    if ([identifier isEqualToString:identifier]) {
        // call your API here
    }

    // call the handler block so the app can exit again
    completionHandler();    
}