Swift中能否为application(_:didReceiveRemoteNotification:fetchCompletionHandler:)实现自定义completionHandler?
关于iOS静默推送中
didReceiveRemoteNotification的completionHandler疑问解答 你提供的这个方法是iOS处理静默推送的核心回调:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { ...some tasks... // want to call completionHandler here! }
能否在方法执行完毕后运行自定义completionHandler?
不行。这个completionHandler是iOS系统传入的不可修改、不可自定义的闭包,你无法替换它为自己的实现。你唯一能做的是:在你需要完成的所有任务(不管是同步还是异步任务)结束后,调用系统提供的这个闭包,告知系统任务处理状态。
比如如果你的任务是异步网络请求,不能直接在方法末尾调用completionHandler,必须等网络请求的回调完成后再调用,否则系统会误以为你已经处理完任务,可能提前终止你的后台进程。
系统提供的completionHandler作用是什么?
- 告知系统处理结果:通过传入
UIBackgroundFetchResult枚举值,告诉iOS你处理静默推送的状态:UIBackgroundFetchResultNewData:表示成功获取并处理了新数据UIBackgroundFetchResultNoData:表示没有获取到新数据UIBackgroundFetchResultFailed:表示处理任务失败
- 影响后台刷新频率:系统会根据你返回的结果调整后续静默推送的频率。比如频繁返回
NewData,系统可能会增加推送次数;如果多次返回Failed或超时未调用,系统可能会降低推送频率甚至暂停给你推送。 - 避免进程被强制终止:系统给这个方法的后台执行时间有限(约30秒),如果超时未调用
completionHandler,系统会直接终止你的应用进程。
为什么大家都在方法末尾调用completionHandler?
如果你的处理任务是同步执行的(比如直接解析本地数据、修改本地缓存),方法执行到末尾时任务已经完成,所以直接在这里调用completionHandler是合理的。但如果是异步任务,必须等异步操作完成后再调用,不能直接放在方法末尾。
内容的提问来源于stack exchange,提问作者M Rahman
相关产品推荐
相关产品推荐

