我正在尝试在应用程序终止时通过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退出应用。
答案 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秒也可以。