Determining if assets need to be re-cached in memory - ios

Assume a game app, where user loads some contents into memory during first open. Afterwards they can:
Move app into background
Lock device
Close app completely
Get a phone call
etc...
Is there a way to know when our app's contents are no longer in memory or something of similar sorts to determine when re-caching of assets is required?
I studied few game apps and they tend to do one of the following
Show loading screen every time app comes back from background
Show loading screen only if device was locked or closed (app is still in the background)
And I'm interested in achieving no.2 to not show loading screens unnecessarily each time app comes back from the background.

You can use AppDelegate method applicationWillTerminate
https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623111-applicationwillterminate
And notification willTerminateNotification
https://developer.apple.com/documentation/uikit/uiapplication/1623061-willterminatenotification
If Application not terminate you don't need show any loading screen.

Related

Application starts from Home Screen if app remains in the background for more than 30 seconds instead of showing the screen when it went to background

My iOS application is kind of messaging app, so user can send audio, video, images, etc. When user typing the message and app went background for more than 30 seconds then app launches from Home screen and all that messages, everything will be lost. Before 30 seconds app launches at the exact point where it went background. So how to do that same after 30 seconds also, at least I should maintain this state for 30 minutes.
Is using background process and schedule task will be a good method here in iOS 13+?
I particularly don't want to do anything on the background but when app comes from background to foreground within 30 minutes I want to maintain that state.
Messages Disappearing
Well, first of all, why are all the messages lost? if your trying to make a snapchat like experience where the messages disappear after you see them then that's fine but otherwise it might be worth adding a local storage for these messages using CoreData.
Cause
The main issue, after a little while iOS will but an app to sleep so to say, in this scenario it will remove all temporary data within your app, this means when you re-open it it will start from the beginning, it does this to save memory.
Solution
There are a few ways to solve this, you could use State Restoration
For a beginner though this could be quite tricky as the documentation on it is quite sparse.
Another option would be to save the last screen in UserDefaults and then when the app re-launches you can use the value to push the last screen the user was on. For both these solutions though you will need a way to persist the messages and re-fetch them (a database) CoreData would probs be your best bet
I do personally think State Restoration is the best option especially since it sounds like that's exactly what you want to do:
but when app comes from background to foreground within 30 minutes I want to maintain that state.

Questions about app state after tapping on app icon after apps enters suspended state

I’m putting an app into background.
Assuming that I’m not doing anything to keep the app alive in the background, then the app goes through suspended state in a matter of 5 seconds. Right?
What happens if I then tap on the app icon? That’s not suppose to trigger a didFinishLaunch right? It will just bring me back to the last screen I was at and also trigger didbecomeActive & willenterforeground notifications. I won't be getting any other callback. Right?
Assuming there is no restart of the phone, point 2 is true even if there are hours between me tapping home and then tapping back the app icon. Right? Does it also persist device restarts but not force-restart?
The only time I won’t be brought back to the screen I was at (before hitting home) is if the device receives a memory warning and my app is flushed out of suspended state. At this point tapping on the app icon will result in didFinishLaunch. Right?
(I’m asking all of this because sometimes after putting the app in the background and tapping the app icon again (e.g. 10 minutes later), the app is going through it’s launch phase. Most of the time it just goes back to its previous screen)
I've already seen Will ios terminate the app running in background after a specific time? but that doesn't address all aspects I want.
It will just bring me back to the last screen I was at and also trigger didbecomeActive & willenterforeground notifications.
Right, if your app was not terminated in the background.
I won't be getting any other callback.
Not necessarily true. If you were summoned to the front by a local notification, for example, you'll also get an event about that.
Assuming there is no restart of the phone, point 2 is true even if there are hours between me tapping home and then tapping back the app icon.
Not necessarily. The app might well be terminated silently in the background.
Does it also persist device restarts but not force-restart?
Absolutely not. How can the app run when the device is off? Shutting down the app terminates every app.
I’m asking all of this because sometimes after putting the app in the background and tapping the app icon again (e.g. 10 minutes later), the app is going through it’s launch phase
It's not a matter of time. The watchdog process is constantly combing the suspended apps looking for the ones that take up too much memory so that other apps can run. You must not be surprised if yours is one of them.
You can come back to the front launching from scratch or by coming back to life from suspension; it's the most basic fact of iOS app life! You just need to accept it.
But there are lots of things you can do to reduce your chances of being terminated in the background. Giving up memory-consuming objects as you background is first on the list.

What really happen to loaded data when the app becomes in background

I am new to IOS development. I am still confused about data lifecycle inside the UIViewController. If I had a property called "userData" and I identified it as following
let userData : UserData! {
didSet {
// do something
}
}
and I used this data to handle click events later. What could happen if the app went to background then -say after 1 hour- the user reopened the app and found the page still displaying the content, then he clicked a button inside page. I am not sure if userData will be kept or the page lost it when it went to background!?
My app crashes when I come later and open it, but I am not sure if that's because of identifying variables like this or not
The term background is confusing. Apple generally uses it to mean a state where your app is still getting processor time but another app is front-most. You have to ask if you want more than a few seconds of background time when the user hits the home button.
If the user presses the home button and then swaps to another app your app gets a few seconds of background time to save it's state, and then it moves to the "suspended" state, where it is still in memory, but no longer gets processor time.
Once you've been suspended, if the user switches back to your app while it's still in memory you get a resume message and then you continue running, with everything that was in memory still in memory.
However, once you've been suspended your app can be terminated at any time after that without any warning. That's why you have to save your app state when you get suspended.
If you do get terminated then the next time the user selects your app you get re-launched. You are usually expected to restore state and make it look like the app simply picked up where it left off, but it is a cold launch.
If you are crashing after your app is resumed (not terminated) then you might need help debugging that crash.

Appending data inside a tableView in the background - iOS

My app works like this - you press an uibutton and it starts appending data inside a tableView with a specific delay, cell by cell. Sometimes it may take hours to append, because of the manually set delay parameter.
The problem is each time i switch it to background - the app gets suspended after several minutes (up to five usually) and the whole process breaks.
Is there any approach to handling this situation?
Thank you.
That's the designed behavior, an app return to background normally only have very short active time, then it will be suspended, but there are some exceptions:
Apps that play audible content to the user while in the background, such as
Music player app
Apps that record audio content while in the background
Apps that keep users informed of their location at all times, such as a navigation app
Apps that support Voice over Internet Protocol (VoIP)
Apps that need to download and process new content regularly
Apps that receive regular updates from external accessories
Basically speaking, if your app need to interact with outside for resource that can not be generated inside your app, you can apply for background running.
Any every app can legally apply a background task to run for a short time when the app enter background mode.
In your case, even if you implemented the background running, your app will possibly be rejected. If your app is doing the adding to table action controlled by a timer, you should be able to simulate the behavior yourself.
save a the system time stamp locally, maybe in UserDefault
when app launch or enter foreground, get the system time, you can calculate the time difference and figure out how many actions you should take and perform that with a batch action.
after that, clear the saved time stamp ensure next time your data won't be messed up.

Launch iOS app faster

I figured out that some iOS apps are launching really faster (e.g. YouTube-from google,Skype,iTunes).
I created an empty application (used standard tabbed application template) and i did not change any code at all, just added splash images. When i tested (tried both developer and Ad-Hoc provisioning profiles to sign to check whether if there any difference), it did not launch as fast as the above mentioned apps.
When i tap the app icon on the device app icon get darker for about 0.2-0.5 seconds and then start showing splash image.
My question is how to make my app launch really fast, and is there any trick to show splash image very quickly? (i wonder how my empty application launches slower than above mentioned apps?)
Thanks
I think you also may be falling for a trick: at least for the iTunes app, Apple is overwriting the splash image with one that looks very much like the app while running, which creates the illusion that the app loads immediately. Try it:
Launch iTunes (or "Music") and start it playing, then go do something else to cause the system to swap the process out as much as possible (say, browse some heavy websites). Then relaunch iTunes and immediately try to pause the audio. On my iPhone 4, it takes about 3 seconds before the controls catch up: the position indicator will jump to the correct location, and until that time, the "play" button is inactive - you can't pause the audio. You're seeing a splash image that is meant to make you think that the app is launching immediately, even though it's really taking a few seconds to launch.
I've also noticed Chrome for iOS doing the same thing. I actually dislike this design decision, because it communicates that the app is ready before you can do anything with it.
i did not changed any code at all just added splash images
The loading images are not intended to show splash images, they are intended to show a static version of your application's interface to give the illusion that your application is loading more quickly than it really is.
Splash images are specifically warned against by Apple in the HIG.
Stop abusing loading images to show splash images, start using them properly, and your application will look as if it is loading more quickly.
link to as few frameworks as possible, we tried this at WWDC and linking to many frameworks creates a noticeable delay even before the main() method is called!
no matter how fast your code itself is!

Resources