Why does my iPhone App remember its UI state partially? - objective-c

I have made a small test app with a button and a UISlider. Touching the button changes its label text.
I have added IBOutlet properties for both controls. I'm releasing all properties in viewDidUnload and also set them to nil in dealloc.
The interesting thing is now: I touch the button. Its tag is changed from "0" to "1" and, its text is updated: tag == 1 -> "B", tag == 0 -> "A". So the text says "B" now.
Then I close the App (iPhones home button) and restart it.
Still the button says "B"! How is that possible? Is the App not terminated?
Running on iOS4.1 here on an iPhone 4.
René

You're right. The app is not terminated. In iOS 4, apps are suspended when the home button is pressed. When you "relaunch" the app, it is simply moved to the foreground. This is why your application state isn't changing. Note: Once suspended, apps may be terminated by the OS without notification, so make sure to do all your saving before the app gets suspended, e.g., in applicationDidEnterBackground:.

Related

UIKeyboardWillShowNotification - iOS8 vs iOS7

With iOS8, I noticed that a view controller was no longer receiving a UIKeyboardWillSHowNotification, when it previously was with iOS7.
Here's the scenario:
1.) View Controller A is displaying a keyboard, and pushes View Controller B without resigning first responder
2.) View Controller B has a control that becomes first responder during its viewDidLoad call, while it's being created by VCA, before it's pushed onto the nav controller
3.) If VC A is NOT displaying a keyboard when pushing B, the notifications work fine. However, if A is still editing when pushing B, then B does not get a keyboard will show notification.
Without the keyboard notification, VC B is not resizing / repositioning and does not look right.
The workaround I'm using until I find a solution is to do the following from any view controllers that might be editing when pushing another view controller that might be editing:
i.e., before pushing another view controller, be sure to call:
[self.view endEditing:YES];
While it works, it doesn't seem good that the view controller (B) can be 'broken' by the state of the app prior to displaying it.
Question: Am I doing something wrong here?
As far as I can tell, one of 3 things are possible:
A.) I should be getting the notifications, but I'm not b/c I'm doing something wrong
B.) I should be getting the notifications, but I'm not b/c of a bug
C.) I can't rely on always getting the notifications...But if I don't get the notifications in VC B when it appears, I need to be able to get the keyboard dimensions of the displayed keyboard without relying on the keyboard notification info. All the apple docs say to use the notifications though (as far as I can find).... which points back to options A.) or B.).
I can create and upload sample code later tonight / early tomorrow to try and isolate / for you all to test/reproduce to see what I'm doing.
I can see the same issue with iOS8 / xCode6 (works with iOS7 and xCode5). In my case, I'm observing a systemStatus property on the model in my AppDelegate so as to log the user out and bring the user back to the login screen when the user logs out from anywhere in the app. I'm doing that by setting the window.rootViewController to the loginViewController in my App Delegate observeValueForKeyPath: method.
This works fine on iOS7 / xCode5 but on iOS8 / xCode6, I loose the keyboard in the way. Looks like my loginViewController might be registering for keyboard notifications (in its ViewWillAppear method) before the window's rootViewController switch is complete (in iOS8) thus registering to the old window's notification center...
I moved the registration for keyboard notifications to the ViewDidAppear: method instead and that seems to fix it but somehow this seems to be called twice for some reason.

Push notification while app is not running - launchOptions dictionary is empty

I've read a number of questions here on SO regarding receiving push notifications while the application is not running (more than in the background, meaning it is shut down completely). This question in particular is most helpful in figuring out how to determine if one was receiving using the launchOptions dictionary.
However, I'm very confused, and I fully admit this may be a massive oversight on my part: when my device receives a push notification for this application while the app is shut down, and I later open my application, the launchOptions dictionary is a null pointer. From the description of the accepted answer in the previously mentioned link, and other places too, I gather that I should be able to see a notification payload; however there is nothing. I am developing for iOS 5.1.1.
My only other thought is to check the number of badges on start up (greater than zero, do something...), but this seems very unreliable.
Can anyone tell me what I am missing? Thank you in advance for your help!
application:didFinishLaunchingWithOptions: will only be called with payload information when app is launched due to notification. E.g. this could happen if user taps over notification alert (added in notification center) or notification received with content-avialble = 1 in payload (Newsstand notification) & provided your app is not in foreground as well in background.
If your app receives notification when app is in background. If it is Newsstand notification or if user taps over action button of alert below method is called
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
with [[UIApplication sharedApplication] applicationState] not equal to UIApplicationStateActive.
In above case if user does not tap over action button of notification alert and launch app by tapping over it, neither didFinishLaunchingWithOptions or didReceiveRemoteNotification is called.
If your app receives notification while in foreground didReceiveRemoteNotification is called [[UIApplication sharedApplication] applicationState] will be equal to UIApplicationStateActive.
For badge in notification, if your app is not running no code is executed and the badge is incremented by 1 in app icon. When you launch app (tap on app icon) didFinishLaunchingWithOptions is called with normally. (If app is in background or foreground when notification received, same as above)
So I think this covers every possible case. Also note that the background case is valid for iOS SDK >= 4.0

iOS: Changing a view on backgroung does not refresh what is being seen before the app returns to foreground

Ok, I got this issue: I have an application with a login screen that is suposed to show everytime the app goes to background and return. The problem is, the previous screen appears for a fraction of second after the app return to foreground, because the system only refresh what is being seen after loading. What is need is a complete transition before the app returns to foreground. Yes, I am doing the transition on app delegate, at applicationDidEnterBackground. tried at every single other back/fore transition method, same results. The code works fine, but theres a flash of the screen before the login screen showing up.
The full code is as follows:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
if (!([LogicCore loadPass] == nil || [[LogicCore loadPass] isEqualToString:#""])) //a password is set,
{
[self.window.rootViewController dismissModalViewControllerAnimated:YES];//go back to the rootview, the login screen
}
}
I forgot about this, but you can have your app exit when the user backgrounds it. The only real problem here is they see your splash screen again while the app loads.
To have your app exit when backgrounded (suspended) put the key "Application does not run in background" - raw key: UIApplicationExitsOnSuspend to YES.
Not an ideal solution, but the only one I can find at the moment.
Try making the call in applicationWillEnterForeground: which "lets you know that your app is moving out of the background and back into the foreground, but that it is not yet active."
You're doing it after the transition has occurred (the change will be "queued" to happen after displaying the view)—you want to do it before, so you go with the will methods.

How to differentiate lock screen and home button (background multitasking) on applicationWillResignActive in the app delegate

I am writing an alarm clock app.
Please correct me if I am wrong:
On both events (lock & home button in iOS 4.x) the applicationWillResignActive: method is called. When locked my app can keep on running (forever if DeepSleepPreventer.h is used) to check if the alarm should go off. When home is pressed it has to stop working at some time (apart from some basic background calculations). So in this case I have to set a local UILocalNotification to trigger the alarm.
So my question: How to differentiate between those two events?
Thank you!
Have you tried implementing -applicationDidEnterBackground: in your app delegate?

Application Termination

I am running my app on a device. When I am in second view and terminate the app, the app quits but then when i launch it, it goes straight back to second view and not the first view (login view). I checked to see if the control goes to applicationWillTerminate method, but it does not go into that method. How can i make my program go into it?
This is probably due to iOS 4's multitasking. When you tap the Home button, your application is by default suspended on supported devices (if you double tap Home, you can see all suspended applications). You can set the plist key UIApplicationExitsOnSuspend to force UIKit to quit your application, rather than suspend, when the home button is pressed.
If you want to support the multitasking modes, look at the applicationDidEnterBackground: method of your UIApplicationDelegate implementation.