问题
I want to make a request when the application enters the onBackground
or onAppWillTerminate mode. I added an observer to AppDelegate method but did not work. Simply I want to send a request and push notification as a response. How can I do this? My request is not news or music, simple JSON.
`func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
Fabric.with([Crashlytics.self])
GADMobileAds.configure(withApplicationID: "ca-app-pub-8446699920682817~7829108")
let onesignalInitSettings = [kOSSettingsKeyAutoPrompt: false]
//ONE SIGNAL
OneSignal.initWithLaunchOptions(launchOptions,
appId: "f5854e88-0b58-495f-8d3f-e7899202d",
handleNotificationAction: nil,
settings: onesignalInitSettings)
OneSignal.inFocusDisplayType = OSNotificationDisplayType.notification;
OneSignal.promptForPushNotifications(userResponse: { accepted in
print("User accepted notifications: \(accepted)")
})
UIApplication.shared.statusBarStyle = .lightContent
UIApplication.shared.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)
mS.StartTimer()
//NotificationCenter.default.addObserver(self, selector:#selector(AppDelegate.applicationWillTerminate(_:)), name:NSNotification.Name.UIApplicationWillTerminate, object:nil)
NotificationCenter.default.addObserver(self, selector:#selector(AppDelegate.applicationWillEnterForeground(_:)), name:NSNotification.Name.UIApplicationWillEnterForeground, object:nil)
return true
}
func applicationWillTerminate(_ application: UIApplication) {
//mS.StartTimer()
}
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
self.mS.StartTimer()
if let vc = window?.rootViewController as? LiveScores{
vc.getLiveMatches(url : URL(string: "http://test.com/test/index.php/Service/lastLive"))
}
completionHandler(.newData)
}
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void){
completionHandler(UIBackgroundFetchResult.newData)
}
func applicationDidEnterBackground(_ application: UIApplication) {
if let vc = window?.rootViewController as? LiveScores{
vc.getLiveMatches(url : URL(string: "http://opucukgonder.com/tipster/index.php/Service/lastLive"))
}
mS.StartTimer()
}
func applicationWillEnterForeground(_ application: UIApplication) {
if let vc = window?.rootViewController as? LiveScores{
vc.getLiveMatches(url : URL(string: "http://opucukgonder.com/tipster/index.php/Service/lastLive"))
}
mS.StartTimer()
}
}`
回答1:
If you want to contact the server when the app is going into the background, that is certainly possible. Implement UIApplicationDelegate.applicationDidEnterBackground
. See Strategies for Handling App State Transitions for full details. This is a very common and supported operation and should be what you need.
However, it is not possible to contact the server when the app is killed in the background. applicationWillTerminate
is generally never called in any case since iOS 4. Prior to iOS 4, there was no "background" mode. When the user pressed the home button, the app was immediately terminated after calling this method, and that's why it still exists. But it's all-but-useless in modern apps. (You can still get this ancient behavior by setting UIApplicationExitsOnSuspend
in your Info.plist, but this does nothing to help your problem.)
When your application is killed in the background it is just killed. It is not woken up, and no methods are called on it. It is unceremoniously terminated and removed from memory. You cannot respond to this event. The same happens when the user force-quits your app from the app-switcher.
I'm a little curious about why you would want a push notification when the app goes into the background, and particularly when the app terminates. When I've seen people try to do this in the past, they often were trying to use push notifications to keep the app launched at all times. This is not possible. Even if you found a work-around to make it technically possible, it is explicitly forbidden by Apple.
回答2:
Actually application is forcefully killed after 3-4 seconds when applicationWillTerminate is called. so thats why API is not called.
One solution you can try is to add sleep at the end of the applicationWillTerminate function like this :
func applicationWillTerminate(_ application: UIApplication) {
//call API Here
// 5 is the number of seconds in which you estimate your request
// will be finished before system terminate the app process
sleep(5)
print("applicationWillTerminate")
}
来源:https://stackoverflow.com/questions/50288554/swift-send-request-to-server-when-app-killed