iOS: not getting touchesCancelled when getting a native popup - ios

I'm not used to working on native iOS code. So excuse me for missing something obvious here.
The issue I'm having right now, is when a user is holding down a touch, and then before releasing, a native popup appears (low battery, timer, ...), this does not fire a call to touchesCancelled.
Instead, it fires a touchesEnded when the user stops touching the screen.
However, this touchedEnded was a user reaction to the popup, not an active decision for using the app, and this might lead to incorrect and frustrating behaviour.
As far as I can tell, the touchesCancelled should be fired when focus is lost, but it seems focus is not completely lost in this case.
I am wondering if there is any other way to detect that a native popup was opened, and have my app act like touchesCancelled was fired, and avoid unintentional behaviour.
I've tested some apps from Apple and they have the same (in my opinion) wrong behaviour. So maybe it's something I have to live with, but I want to reach out to more experienced native iOS devs, and be sure of it.
Thanks,
Sascha

I returned back to this issue today. I found out that when a native popup appears, there is a call into the app to applicationWillResignActive and applicationDidBecomeActive respectively.
In my solution, at the moment applicationWillResignActive is called, I basically make the app act as if there was a touchesCancelled for each touch that had a began without an end or cancel. When the actual touchesEnded gets called, it gets ignored as it no longer matches a touchesBegan in my app.
It feels a bit like jumping hoops, but this does the trick quit nicely for me.

Related

How iOS handles events that occurs just right before the background?

First of all I'd like to say sorry in case my question is dummy, I'm really new to iOS and what to understand how thing are going on. Imagine such a situation - user taps on home button and the app starts to collapse, but immediately after taping on home button user taped on some UI element. So, I'm wondering how the iOS will handle this? I tried to do some tests using breakpoints, but since it just test I can't be 100% sure. It seems that if the UI interaction event will happen before the system will call willResignActive then the event will be fully processed and if the system will call willResignActive first, then the even will be discarded and won't be handled at all. Is this correct, or I missed something? Thanks
First, why do you want to use this in your app? If a user presses a button exactly in this time, it's okay that the action is not handled.
The only thing you have to keep track of is that whenever the button gets pressed and let's say you store a file without a completion handler it could be that you present an alert which is saying that everything went well but you actually not saved the file because the user left the app in this time.
But since you're never doing critical actions without completion handlers, in my opinion, there's no need to make sure that this doesn't happen.
If I got you wrong, just comment!

App view seems to reload back to default after some time

I've come across a strange error while programming my iPhone application. Basically when I leave my application in the background and then access it after a long time (i.e. the entire night while I'm sleeping), the viewDidLoad method seems to be called again even though I did not exit the app (I only double tapped the Home button or I tapped the Home button once) but still left the app in the background. However, if I leave the app on for a short period of time (anytime between a few minutes to a few hours), the viewDidLoad method is not called again and everything is as it should be. After doing some research, I found that it is because the viewDidUnload method is called (after the OS finds that the app is suspended for a long time), which calls viewDidLoad again when we bring the app back up. I found this out through this link: view seems to reload itself but it doesn't seem that there's a way to prevent viewDidLoad from being called when the viewDidUnload is called. Is there any way to prevent this viewDidUnload method from being called again? The thing is I want my app to be running for a long time in the background (i.e. a few days in the background) to collect data. Or, is there no way around this? Any help would be appreciated. Thanks!
EDIT: I have realized that after iOS 5, viewDidUnload is deprecated but this phenomenon still occurs. Any ideas on how to fix it? Thanks!
If you want to do stuff in the background you should look into background tasks.

Should touchID be displayed if app minimized

Im implementing touch ID to "unlock" my app, and im not sure if ive run into an apple bug or something i need to handle myself. If i tap the Home button and minimize my app before evaluatePolicy can load the Touch ID prompt, it appears over the home screen.
![not enough reputation to display screenshot, so heres a link]https://www.dropbox.com/s/zrhc60lx87ze7mt/IMG_0016.PNG
Successful/failure/cancel evaluation of this policy does nothing, but when i re-enter the app and cancel it again, touchID seems to be disabled forever until i restart the phone.
Anyone else running into this issue or have an ideas?
P.S. Theres an open radar where errSecUserCanceled is never returned from a cancel button tap, so right now i fall into my errSecAuthFailed case, which could also be the cause.
Answer is no. It should not be be displayed, when minimized.
The problem is IMHO that the code segment is being called again from your app when it goes to the background. For example loadView , didLoad and so on.
Try moving the code, that calls the authentication somewhere else in the program (different method).
For example, if your code uses a textView to enter password, you can implement the authentication within keyboardWillShow or similar.
Hope it helps.

Getting touches at launch on iOS

On Mac, one can always get the location of the mouse "outside the event stream" (ie, even if you've not subscribed to any delegate methods for mouseUp: et al) by calling [NSEvent mouseLocation].
Is there any way on iOS to get current touch events without listening to touchesBegan:?
I ask because there is at least one situation in which touchesBegan is not called: at app launch, if a touch is already in progress, touchesBegan is never called. In fact, neither are any of the touch-related UIEvent methods called as near as I can tell (nor UIApplication's / UIWindow's sendEvent:, apparently).
I would like to vary the behavior of my app slightly based on whether a touch is in progress at launch. Is there any way to detect an in-progress touch at app launch?
This cannot be done. The simple reason: The touch events don't belong to your app. Each touch belongs to some UI element (or responder). As you already know, this element gets the began, moved, ended, cancelled messages.
This is even true within a properly programmed app: All events regarding one touch are delivered to the very same object. After all, how would another object know what to do with that event, and how should the first object properly finish its expected behavior?
While you can (or could, but probably shouldn't) find a work around within your app, there's just no way for cross-app-touch passings.
And on the Mac you may query the mouse position, but in normal application flow there'll always be a mouse down before you get a mouse up event.
To be honest, I don't see any reason why this would be needed anyway... oh wait... I could split my app icon into several areas... not sure if it would already break privacy laws, though, if you get to know where the user has his icon on screen.
I think you could simply "extend" the application launch. When I had time consuming tasks during my application launch, I used to show the same splash screen with a UIActivityIndicator while the action was being carried out.
You could simply create a NSTimer, wait for about 2 seconds and during this time, check for touches, while the splash screen will still be showing.
To do this, in applicationDidFinishLaunch, push a ViewController that looks exactaly like the splash screen and check for touches in this ViewController. After those 2 seconds, proceed with normal initialisation. This behaviour also helps if you have time consuming tasks during initialisation.
I know, it`s a workaround, but my guess, is that it is not possible to check for touches because application will be working on the main thread and the touches also processes on the main thread. This could happen also because there are no ViewControllers or UIWindow initialised and ready to listen to touches.
Hope it helps.
You might try handling the hitTest:withEvent: instead.
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
Since according to apple doc "Returns the farthest descendant of the receiver in the view hierarchy (including itself) that contains a specified point."

UILocalNotifcation custom fire event, or struggle on with NSTimer

I have a state-transition problem with NSTimer, of which I find difficult to keep track of during applicationWillResignActive / applicationDidEnterBackground, according to the context of my app.
I was wondering if it might not be a better idea to utilise UILocalNotification, especially given it's background/inactive firing. However, I wanted to know whether we have the ability to provide a custom method to UILocalNotification, of which does not present a dialog box (would damage the whole point of my app). In effect, i'd like to only make use of the timer-fire capabilities of UILocalNotification, and handle the fire event with my own method which does something very "undialog-friendly"
Have checked the ADC docs and it alludes to the dialog being presented every time.
Any advice you can give on this would be appreciated.
thanks
sc.
The dialog box is presented when your app is in the background. But it is not presented when your app is running - instead your app is free to deal with the notification however it sees fit. So it would be perfectly possible to hook it up to a custom method of your own making.
The main reason for this behaviour is a user may not want to go into your app if it's in the background. Of course, with iOS 5 the notification may not be a dialog box - it could be one of the new notification styles.

Resources