当用户终止应用程序(强制关闭)时,我需要进行API调用。我所做的直接实现如下。
在应用程序委托中,我添加了以下代码。
func applicationWillTerminate(_ application: UIApplication) {
print("________TERMINATED___________")
testAPICall()
}
func testAPICall(){
let url = getURL()
let contentHeader = ["Content-Type": "application/json"]
Alamofire.request(url,
method: .put,
parameters: ["username": "abc@xyz.com"],
encoding: JSONEncoding.default,
headers: contentHeader).responseJSON { (response) -> Void in
print("-----")
}
}
但是,没有拨打电话。并且在进行documentation时,我发现在此方法中完成任务仅5秒,最重要的是,在这里进行api调用不是要完成的任务。所以我想知道这样做的方式是什么。
答案 0 :(得分:3)
这是一个双重问题
阶段1:确保API调用在用户每次退出应用程序/之前就开始启动
您始终可以在自己的appdelegate中使用expiration handler
的{{1}}背景模式
声明
iOS application
和您的appdelegate
var bgTask: UIBackgroundTaskIdentifier = UIBackgroundTaskIdentifier(rawValue: 0);
背景过期处理程序将确保您每次将应用程序置于非活动状态或被终止时,都有足够的时间来启动API调用
阶段2:确保API调用成功完成
尽管到期处理程序可能会确保您有足够的时间来启动API调用,但不能确保API调用成功完成。如果API调用花费的时间更长,并且在请求进行中且时间用完了怎么办?
确保API调用一旦启动成功的唯一方法是确保为 func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
bgTask = application.beginBackgroundTask(withName:"MyBackgroundTask", expirationHandler: {() -> Void in
// Do something to stop our background task or the app will be killed
application.endBackgroundTask(self.bgTask)
self.bgTask = UIBackgroundTaskIdentifier.invalid
})
DispatchQueue.global(qos: .background).async {
//make your API call here
}
// Perform your background task here
print("The task has started")
}
使用正确的配置
根据文档
通过后台会话,您可以执行内容的上载和下载 在您的应用未运行时在后台运行。
链接:https://developer.apple.com/documentation/foundation/nsurlsession?language=objc
因此,请使用后台会话并使用上载任务。让后端开发人员接受一个文件,然后将所有参数数据放入该文件(如果有的话)中,然后使用后台会话启动上载任务,而不是使用将用某些参数命中的普通get / post API。
一旦上传任务从后台会话开始,即使您的应用被杀死,iOS也会负责完成它(除非您显然要遇到身份验证挑战)。
我认为这是确保您启动API调用并确保在应用程序处于非活动状态/终止时完成调用的最接近方法。我与苹果开发商就此进行了讨论,他们同意这可能是一种解决方案:)
希望有帮助
答案 1 :(得分:-1)
主要思想是在应用终止之前进行同步调用
func applicationWillTerminate(_ application: UIApplication) {
let semaphore: dispatch_semaphore_t = dispatch_semaphore_create(0)
let request = NSMutableURLRequest(URL:url)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request,
completionHandler: {
taskData, _, error -> () in
dispatch_semaphore_signal(semaphore);
})
task.resume()
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
}