ApplicationWillTerminate NSURLSession可能吗?

时间:2015-02-11 22:39:32

标签: ios objective-c nsurlconnection uiapplicationdelegate

我正在尝试在应用程序终止时通过NSURLSession进行快速POST。应用程序终止定义为用户在主屏幕上将其滑出。此外,applicationWillTerminate被示范性地调用(因此不存在问题)。

我的目的是通知服务器该用户现在正在脱机。

然而,这不起作用..因为我的后端没有收到POST。我想弄清楚为什么这不起作用..或者即使它应该?根据Apple文档,这应该可以工作,如果它可以在5秒内执行..虽然我甚至没有完成处理程序,所以它应该被执行。任何帮助或建议将不胜感激。

我的实施如下(供参考)。

- (void)applicationWillTerminate:(UIApplication *)application {

    NSMutableDictionary * gatherAllInputs = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
                                             @"blah@df.com, @"emailEntry",
                                             @"False", @"isPersonAvailable",
                                             nil];

    NSError *error;
    NSData *gatherAllInputsJSON = [NSJSONSerialization dataWithJSONObject:gatherAllInputs options:0 error:&error];

    NSString* theDataSentToServer;
    theDataSentToServer = [[NSString alloc] initWithData:gatherAllInputsJSON encoding:NSUTF8StringEncoding];

    NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *postingSession = [NSURLSession sessionWithConfiguration:sessionConfiguration];

    NSURL *url = [NSURL URLWithString:@"https://blahblahblah.com/someblah"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:[theDataSentToServer dataUsingEncoding:NSUTF8StringEncoding]];

    NSURLSessionDataTask *postSomething = [postingSession dataTaskWithRequest:request];
    [postSomething resume]; 
    NSLog(@"Got here!"); //<-- THIS GETS OUTPUTTED.. SO I KNOW THIS CODE IS BEING CALLED!

}

编辑:

同样,我们使用XMPP框架发送消息传递应用程序。 需要在applicationWIllTerminate委托上终止/断开XMPP连接。实际上,当应用程序处于前台并且用户切换到多任务UI(双击主页按钮)时,将调用applicationWIllTerminate。尝试通过调用XMPP断开连接,但没有运气。

不能使用WillResignActive断开连接,在任何时间扩展时,不允许在DidEnteredBackground委托中使用此情况。

服务器 - 客户端乒乓球每2分钟就会动作一次。

在用户强制下找出一个可行的解决方案来断开XMPP退出应用。

3 个答案:

答案 0 :(得分:8)

可能会发生很多事情:

首先,Apple说:&#34;您执行此方法大约五秒钟来执行任何任务并返回。&#34; Apple Docs

我强调&#34;大约&#34;因为将这5秒视为理所当然不是你通常想做的事情。此超时可能依赖于多种因素,例如资源的整体可用性(受您的应用无法控制的细节影响,例如正在运行的其他应用)。

其次,你说:&#34;虽然我甚至没有完成处理程序所以它应该被执行&#34;。

这意味着您正在执行同步通话,即在放手之前必须等待的通话。你确定这个电话的零到大约 5秒就足够了吗?我知道这听起来太多了,但网络可用性/可靠性/速度也是我们通常不应该理所当然的事情。

您是否尝试过做其他事情而不是网络电话?例如,用户默认值写一些东西?放一个计时器,寻找你真正给予多少时间的任何变化。

答案 1 :(得分:6)

问题不是5秒钟(或5秒钟左右)还不够。而且您不会同步启动任务,因为您没有处理程序。它仍然是一个异步调用。

-applicationWillTerminate:在应用关闭时发送。当它返回时,即使有其他后台任务,应用程序也会被击倒。因此,后台任务也停止了。因此,后台任务只需几毫秒或更短的时间即可完成。

您可以使用同步请求,因此在完成请求之前,-applicationWillTerminate:不会返回。但是,这从来都不是个好主意,当然,-applicationWillTerminate:中肯定没有。如果您想告诉服务器该应用程序已消失,只需实施一个心跳。这样做还有一个好处,就是不发送-applicationWillTerminate:而退出的应用程序也将被注销。 (即崩溃)。

答案 2 :(得分:0)

我遇到了完全相同的情况:NSURLSession在applicationWillTerminate:过程中不起作用。

但是,如果iOS并没有给您5秒的时间来完成任务,则您可以自己承担任务:

sleep (3);
applicationWillTerminate:结尾的

给了我足够的时间来执行所有最终的网络活动。实际上,即使延迟1秒也可以。