Asymmetry in connect/disconnect in GCM iOS example - ios

In the GCM client guide for iOS, it shows you to call [[GCMService sharedInstance] connectWithHandler:...] in -applicationDidBecomeActive:, and later it shows you to call [[GCMService sharedInstance] disconnect]; in -applicationDidEnterBackground:.
The placement of connect and disconnect seems asymmetric to me. Is there a reason it is done this way? I feel that it should either be
Connect in -applicationDidBecomeActive: and disconnect in -applicationWillResignActive:, or
Connect in -applicationWillEnterForeground: and disconnect in -applicationDidEnterBackground:

If you look at the Execution States for Apps in Apple's App Programming Guide for iOS, it states that:
applicationWillResignActive:—Lets you know that your app is transitioning away from being the foreground app. Use this method to put your app into a quiescent state.
Compare to
applicationDidEnterBackground:—Lets you know that your app is now running in the background and may be suspended at any time.
For example, if you press the Home button of your device twice, the applicationWillResignActive method will be call immediately, your app is in a transitioning state now. see the image below (Your app leave foreground, but not yet in background):
If you select other app, the applicationDidEnterBackground of your app will be called, and your app enters background. So it is better to call GCMService.sharedInstance().disconnect() when your app is actually in a background state compared to a transitioning state.
Similarly, applicationWillEnterForeground vs applicationDidBecomeActive.
If you are in other app now, and you switch back to your own app, the applicationWillEnterForeground will be called immediately, but your app is might still in an inactive state(which is currently not receiving events).
It might only last for less than half a second, and applicationDidBecomeActive will called immediately after. Because applicationWillEnterForeground is more a transitioning state. So it is better to call GCMService.sharedInstance().connectWithHandler() when your app is actually in an active state(app is running in the foreground and is receiving events).
You might think applicationDidBecomeActive and applicationDidEnterBackground are asymmetric, but these two methods all have a word Did. But two other methods have the word Will, which means a transitioning state.
You can also see the Life Cycle picture from this StackOverflow answer.
Edit after #user102008's comment:
If you do connect in the applicationWillEnterForeground method, then connect method wont be called when the app is first launched. Also, the GCM doc says that Call disconnect when the client app is in the background or when it needs to stop exponential background connection retry, so I think its better to call disconnect when the app is in background, instead of when phone call comes? I think you can use enum with 3 different states connecting , not connected and connected, when the applicationDidBecomeActive method is called, you can check if its not connected or connecting, then you call the connect method again.

Related

DidRecieveRemoteNotification not inwoked immediately when app in background

I'm trying to use Apple push notifications. Everyting works fine except when app is in background.
The callback method DidRecieveRemoteNotification is sometimes not called immediately after notification is received. Sometimes it takes more then 5 minutes to be invoked. Is this standard behavior?
When the app is running in foreground callback method is called right after receiving notification. I would like the same behavior even when app is in background.
Silent notifications will invoke their callback immediately when in the background as their purpose is to wake the app up for a short period of time.
In order to save battery, regular push notifications won't invoke the callback while in the background (unless your app is executing something else in the background). The callback will be called the next time the app is opened, whether from tapping the notification or otherwise.
This is not something you can fix, this is how the eco-system works. If you need your app to do something immediately, you will have to use silent notifications

how to execute code when my app terminated in background in ios

In iOS, we all know that there is AppDelegate method applicationWillTerminate, and it is called when my app is closed by user when it is currently running(i.e. not in background). But I want to do something(save data, for example) when my app is terminated(closed by user or killed by OS) when it runs in background.
PS: my app can run in background.
Do you have any solutions? thanks.
Sorry but you should use applicationWillTerminate:
This method lets your app know that it is about to be terminated and
purged from memory entirely. You should use this method to perform any
final clean-up tasks for your app, such as freeing shared resources,
saving user data, and invalidating timers. Your implementation of this
method has approximately five seconds to perform any tasks and return.
If the method does not return before time expires, the system may kill
the process altogether.
For apps that do not support background execution or are linked
against iOS 3.x or earlier, this method is always called when the user
quits the app. For apps that support background execution, this method
is generally not called when the user quits the app because the app
simply moves to the background in that case. However, this method may
be called in situations where the app is running in the background
(not suspended) and the system needs to terminate it for some reason.
So if you need to save data ALSO when user manually kill the app use applicationDidEnterBackground that it's called if your app support background mode.
If you need to execute code when your app isn’t running, there are
several options open to you depending on what you’re trying to do.
Background fetch will let your app run in the background for about 30 seconds at scheduled intervals. The goal of this is to fetch data
and prepare your UI for when the app runs next.
Push notifications let your app fetch fresh data from your server. You can make a message appear on the device if you want, but it’s not
required – silent push notifications let you skip that part.
Local notifications let you display an alert to the user, along with any media attachments you want and some options for the user to
select from. If they choose those options then your app can be
launched in the foreground or background to handle them.
From:
https://www.hackingwithswift.com/example-code/system/how-to-run-code-when-your-app-is-terminated
You can also use Silent Push Notification
as I mentioned in a similar question: https://stackoverflow.com/a/57245980/6157415

Which event is called when iOS app is swiped from app switcher?

I was wondering which event in my AppDelegate is called when I swipe out my running app from within the app switcher? My target iOS is >= 7.0 (i.e. with multitasking support).
Maybe I just don't understand the multitasking paradigm itself... When I swipe out my app from within the app switcher, the app is going to be terminated, right? Or does it continue running in the background?
EDIT-1: Why I am asking: During startup of the app, I connect to my Linux game server by plain sockets. I want to disconnect the socket when the app terminates.
EDIT-2: I am not sure if I am using background execution. I register my network socket within a run-loop object to asynchronously receive inputs from the server socket. Moreover I have a kind of network service installed that periodically tests for network connectivity. This service is using SCNetworkReachabilityScheduleWithRunLoop.
There are situations where applicationWillTerminate: will be called and sometimes not.
More can be read up from the Apple documentation here
Excerpt:
For apps that do not support background execution or are linked
against iOS 3.x or earlier, this method is always called when the user
quits the app. For apps that support background execution, this method
is generally not called when the user quits the app because the app
simply moves to the background in that case. However, this method may
be called in situations where the app is running in the background
(not suspended) and the system needs to terminate it for some reason.
What's interesting to note is that
After calling this method, the app also posts a
UIApplicationWillTerminateNotification notification to give interested
objects a chance to respond to the transition.
It is - (void)applicationWillTerminate:(UIApplication *)application

When is applicationDidBecomeActive called?

When does the method applicationDidBecomeActive get called? What is the purpose of this method?
Understand the states and transitions of an iOS
States
Non-running - The app is not running.
Inactive - The app is running in the foreground, but not receiving events. An iOS app can be placed into an inactive state, for example, when a call or SMS message is received.
Active - The app is running in the foreground, and receiving events.
Background - The app is running in the background, and executing code.
Suspended - The app is in the background, but no code is being executed.
The seven most important application delegate methods
The operating system calls specific methods within the application delegate to facilitate transitioning to and from various states. The seven most important application delegate methods a developer should handle are:
application:willFinishLaunchingWithOptions
Method called when the launch process is initiated. This is the first opportunity to execute any code within the app.
application:didFinishLaunchingWithOptions
Method called when the launch process is nearly complete. Since this method is called is before any of the app's windows are displayed, it is the last opportunity to prepare the interface and make any final adjustments.
applicationDidBecomeActive
Once the application has become active, the application delegate will receive a callback notification message via the method applicationDidBecomeActive.
This method is also called each time the app returns to an active state from a previous switch to inactive from a resulting phone call or SMS.
applicationWillResignActive
There are several conditions that will spawn the applicationWillResignActive method. Each time a temporary event, such as a phone call, happens this method gets called. It is also important to note that "quitting" an iOS app does not terminate the processes, but rather moves the app to the background.
applicationDidEnterBackground
This method is called when an iOS app is running, but no longer in the foreground. In other words, the user interface is not currently being displayed. According to Apple's UIApplicationDelegate Protocol Reference, the app has approximately five seconds to perform tasks and return. If the method does not return within five seconds, the application is terminated.
applicationWillEnterForeground
This method is called as an app is preparing to move from the background to the foreground. The app, however, is not moved into an active state without the applicationDidBecomeActive method being called. This method gives a developer the opportunity to re-establish the settings of the previous running state before the app becomes active.
applicationWillTerminate
This method notifies your application delegate when a termination event has been triggered. Hitting the home button no longer quits the application. Force quitting the iOS app, or shutting down the device triggers the applicationWillTerminate method. This is the opportunity to save the application configuration, settings, and user preferences.
need additional information ref this link1 or apple link2
When a user is using an application he is in an active state. The user switch to inactive state from a resulting phone call or when a pull down notification center is pulled or when the home screen is pressed(This is when the app is told to be in background state) and then the app is opened again(This is when the app is told to be back to foreground state).
So every time the user switches from inactive state to active state
applicationDidBecomeActive this delegate is called

Why does my iphone app not receive background fetch events after being terminated?

I've built a small ios app which perform periodic updates.
I'm registering my app for background fetches with a callback handler.
When app goes background I'm continue to receive callbacks over the time (every 20-30 minutes, event days later).
Once my app is terminated - the callback handler will be not executed any more.
Is it excepted behavior? I failed to find any mentions about activation from terminated state in Apple documentation on this.
ps: activation from the terminated state is crucial for my app. The approach of the activation could be any, except of user interaction.
It seems that if an app is terminated it will be awaken neither by background fetch nor push notification. No official documentation on this though.
Also keep in mind that if you kill your app from the app switcher
(i.e. swiping up to kill the app) then the OS will never relaunch the
app regardless of push notification or background fetch. In this case
the user has to manually relaunch the app once and then from that
point forward the background activities will be invoked.
Source here

Resources