how to catch the power button and home button on iPhone? - iphone

Today I went to job interview, I encountered three questions now.they hope i provide some Solutions or
Thinking.
1.when user press Home button,app don't go back the main interface or delay 5 seconds to go back the
main interface.
2. when the screen is black ,how to auto activation screen(how to catch power button press event) .
3.how direct launch my app when iPhone is start-up
My english is very bad, i hope everyone can understand what i said above.Thank you very much

None of these are possible on an iOS device, unless it's jailbroken.

Q1 and Q2: not possible
Q3: The closest you can get to desired behaviour is kiosk (store demo) mode of operation.
See more here:
Lock-down iPhone/iPod/iPad so it can only run one app
It's not exactly what you're looking for - it limits the device to use only certain app - but to my knowledge the only way to auto-start an app without jailbraking the device.

I know that this question is old, but there are easy work arounds for every question on here that work for at least iOS 7+, although there is no way to do question 2 without using private APIs. You can successfully answer questions 1 and 3 with public API answers (although they are admittedly hacky)!!
1. When user presses home button, how do you delay 5 seconds before returning to the main screen?
Oscar Gomez's answer was spot on. While you cannot delay the UI from returning to the home screen without blocking the core run loop (which will get you rejected from the app store), you can use some background process techniques if needed to get your extra 5 seconds, just not with UI.
2. How do you catch the Power Button presses?
This is for sure using a private API, and while you can PROBABLY get into the App Store, you probably won't last long once Apple gets wind of you doing this. It is also a hack. You cannot listen directly to the power button, but you CAN listen to the screen going on or off, or both at once. Here is a small code snippet that I have in an Enterprise App:
Inside UIAppDelegate
static int const DisplayOnOffObserver = 54321876;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, &PLDisplayOnOff, CFSTR("com.apple.springboard.hasBlankedScreen"), NULL, 0);
...
return YES;
}
static void PLDisplayOnOff(CFNotificationCenterRef center, void* observer, CFStringRef name, const void* object, CFDictionaryRef userInfo) {
...
DO SOME MAGIC
...
}
- (void)applicationWillTerminate:(UIApplication *)application {
...
CFNotificationCenterRemoveEveryObserver(CFNotificationCenterGetDarwinNotifyCenter(), &DisplayOnOffObserver);
...
}
Obviously you have to have the application ALWAYS running in the background (which can get tricky) or you have to only care to do it within the time that you ask for to run in the background (which isn't hard)
First step is listening to the darwin notification for the screen being toggled on/off.
Second step is implementing the callback.
Third step is stopping listening for the call back.
NOTE: DisplayOnOffObserver is a random number (not very random in my case)
3. How can you directly launch your app when the iPhone starts up?
Assuming that by directly launch, you mean launch in the background, there is actually an Apple supported way of doing this. You first have to enable Background Services for location. Second, you have to start listening for significant location changes. I don't know how well this is documented, but as soon as the iPhone boots, it tries to get it's location. When it does this, it goes from not having a location to having one (which is a significant change). Your app will launch in the background which includes calling the application:didFinishLaunchingWithOptions: method, where you can ask for more time and start other processes to permanently run in the background until the user kills your application manually. If you do permanently run in the background using this method, you do stand a chance of being rejected by Apple.
Hope any of this helps someone! If anyone needs more information, just leave a comment and I will update my answer.

When user press Home button,app don't go back the main interface or delay 5 seconds to go back the
You can't, unless you don't want your app in the appstore... The only thing you CAN do is ask for more time to save your data before your application is terminated, but the UI experience will still be the same - the iphone will go back to the main interface.
when the screen is black ,how to auto activation screen(how to catch power button press event) .
Not possible.
3. How direct launch my app when iPhone is start-up
I don't think you can do this even, with private APIs, and of course with your app not accepted in the appstore.

Related

In Corona SDK How to hide a group if application suspended?

I am building a word game and I want to hide the board when application is suspended?
the code looks fine however it givs a strange behaviour!!,
when I suspend the app nothing will happen but when i resume the application then the board will hide!!
local onSystem = function( event )
if event.type == "applicationSuspend" then
print("suspend")
board_group.alpha = 0
end
end
Runtime:addEventListener( "system", onSystem )
Note: you might wonder how do I know how the application looks when suspended?
the answer is: by pressing the home button twice.
example
SpellTower in normal state
https://dzwonsemrish7.cloudfront.net/items/430k0c0b0y0b413d0b42/Image%202012.11.12%208:08:24%20AM.png?v=4822f549
SpellTower after pressing the home button twice
https://dzwonsemrish7.cloudfront.net/items/280a1y0r2U3W321y1B2z/Image%202012.11.12%208:08:31%20AM.png?v=09c37567
you can see how they are hiding the letters, this is exactly what I want to do for my game, the only difference is i am using Corona SDK
When you do board_group.alpha = 0 you only has set a variable, the result will only take effect after a screen update.
But since the application is suspended... it won't update! So, changing any graphics on applicationSuspend don't work.
I believe the reason is because the application is not considered as suspended. In normal objective c programming it means that applicationWillResignActive is called when the user double clicks on the home button. So what you want to do is to add that code for this part.
Here is a flow of events:
http://www.cocoanetics.com/2010/07/understanding-ios-4-backgrounding-and-delegate-messaging/
Corona seems to have these events:
"applicationStart" occurs when the application is launched and all code
in main.lua is executed.
"applicationExit" occurs when the user quits the application.
"applicationSuspend" occurs when the device needs to suspend the application such as during a phone call or if the phone goes to sleep
from inactivity. In the simulator, this corresponds to the simulator
running in the background. During suspension, no events (not even
enterFrame events) are sent to the application while suspended, so if
you have code that depends on time, you should account for the time
lost to an application being suspended.
"applicationResume" occurs when the application resumes after a suspend. On the phone, this occurs if the application was suspended
because of a phone call. On the simulator, this occurs when the simulator was in the background and now is the foreground application.
So my guess is that you have to implement it outside of the corona API.
According to the corona documents you can implement them in the delegate:
You can intercept UIApplicationDelegate events via your implementation
of the CoronaDelegate protocol.
This protocol conforms to the UIApplicationDelegate protocol. Corona's
internal delegate will call your protocol's method if it is
implemented.
Please keep in mind the following:
Methods that Apple has deprecated will be ignored.
In most cases, your class' version will be invoked after Corona's corresponding version of the UIApplicationDelegate method. There is one situation in which your version will be called before.
In situations where the app is about to suspend or go to the background, your method will be called before Corona's version, e.g.
applicationWillResignActive: and applicationDidEnterBackground:.
http://docs.coronalabs.com/native/enterprise/ios/CoronaDelegate.html
But this is just a guess. Hope it helps!
Edit:
I was thinking, something really simple you could do is catch it outside and present a "pause" screen, then just hide it when the application enters foreground.
So if you can't do that (for now), one other option is to save application state when the application is about to terminate, and then set UIApplicationExitsOnSuspend = true in your plist file. This will cause the application to exit instead of suspending, which will avoid any screenshots, effectively "hiding" the board, etc. The downfall is, the app will have to read the session state when it launches again... this is only useful if your application can be designed to actually exit without losing your state, and is quite honestly, a little extreme. That said, it may be the only way to effectively do what you're trying to do.
Other ideas would be to see if you can add a large black layer to the screen, even though the application is suspending; perhaps this will somehow trigger an internal screen update by natively setting setNeedsDisplay. Also, instead of modifying the alpha, you might consider temporarily removing all of your layers and see if that has a similar effect.

Is there a method if application was closed in multitasking?

Is there a method like: wasTerminated or something like that? I want to display the user an alertsheet, if he has completely closed the app from multitasking. At the moment I have implemented my code in the DidEnterBackround, but is there another way to fix this? That would be very useful for me.
Sorry I'm a newbie and I didn't find a solution on the net.
Thanks.
Background applications can be terminated at any time, and there's no way for an app to tell whether it was terminated by the user (through the multitasking switcher) or by the system.
Your only notifications are –applicationDidEnterBackground:, –applicationWillEnterForeground:, and –application:didFinishLaunchingWithOptions:. With these notifications you can tell if some background task completed or not, but you can't tell how your app was terminated.
Do you want to show the message to the user, next time the user starts your app, or when the app is killed. If the app is killed by double clicking on the home button and killing it, and if you want to find out then, it is not possible.
But if the app is killed and the user starts the app again, then you will know whether the app is started fresh or did it become active.
The method
-(void)applicationWillEnterForeground:(UIApplication *)application{
NSLog(#"Entering foreground");
}
will get called if it becomes active from background.
Other wise,
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
will get called where you can put your alert view.
You can easily experiment with these situations and figure out a way to do what you want.

iPhone download / parse xml file on app launch?

I'm working on a storyboard app in which one of it's tabbed views is a mapView that downloads points from an xml file on a server. Everytime the app is launched and that tab in the tab bar controller is selected, it takes a second to download the file and parse it. Worse still, if there is no access to internet, the app crashes :/
I would like to try to use my getDataService (which downloads and parses) during the splash screen of the app instead of on ViewDidLoad of the viewcontroller (is this in appdelegate under didFinishLaunchingWithOptions?) and let it do its thing then, or in the background, and keep working in the background if the app is closed.
Then I'd like the array to be retained for future use (does this have to do with dictionaries?) and only re-download and parse the xml when the app is fully restarted.
How can I do these things? If anyone has examples or links to tutorials and examples that do these things, I'd be very grateful. I've been searching for a while, but I don't know what to search for.
Actually DO NOT do this during didFinishLaunchingWithOptions:
The reason is that iOS will kill any application that takes too long to load. I don't have the relevant documentation to hand, but iOS expects your app to finish launching within a specific period of time (I believe it's around 3 seconds or so) and if this method is not finished within that time frame you app is deemed to have hung and iOS will kill it.
The recommended technique is that if you have long running code is to start a background thread with the code on it.
The whole idea is to get the user to a usable interface as quickly as possible. Note that the debugger disables iOS's kill function, it's only active when your code is on a device and no you cannot disable it programmatically. So your code will appear to be fine when developing but fail when you run it for real.
If you need to display something whilst loading, I'd recommend putting the long running code on a background thread and continuing on to a temporary view which is basically a copy of the splash screen. then when you data is available, load up your interface.
If you do this from the AppDelegate applicationDidFinishLoading function, and assign it to a property that you define for you AppDelegate, your loading screen will still be visible while your data is being downloaded and parsed.
- (BOOL)application:(UIApplicatioN *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSLog(#"loading!");
sleep(5); //delay to show you that the log happens before the loading screen goes away
return YES;
}
Make the first screen that shows when the app launches (after the Default.png splash screen) be the same or a very similar image, but give the user feedback that something is happening -- e.g. a UIActivityIndicator.
If your app doesn't fail gracefully when launched with no internet connection, Apple will reject it. Show a relevant message in this situation which advises the user something like either of these:
1) No internet connection, so functionality of this app may be limited
2) No internet connection, and this app will not function with it

iOS home button warning, is it possible?

I really don't think this can be done, but still my boss wants me to provide a link where it says so. What he wants is to add an 'are you sure you want to exit?' warning when the user presses the home button, and if the user says 'no' the app won't go inactive.
It can't be done, can it?
No, you cannot do this - the application has no say in this. Ask your boss whether he has ever seen a single example of an iOS application that would do this. There isn't ... not one I would bet.
The application can continue to execute some functionality in the background - streaming music, getting location information for example, but no application can block the home button. If you could do this, you could block an application from ever closing.
A) You couldn't technically do this and
B) Apple wouldn't allow it to be released on the App Store if that was the distribution route you were taking
If you look at the methods stubs created by XCode when you create an application delegate
-(void)applicationWillResignActive:(UIApplication *)application
-(void)applicationWillTerminate:(UIApplication *)application
That are filled will comments about how you can use this method to pause tasks, disable timers, throttle down frame rates, save data - there is nothing about being able to delay, query the user with an "Are you sure" message.
This whole idea is rather counter to the user-experience of the iPhone/Pad/Pod-Touch.
From the App Store guidelines (slightly abbreviated):
Apps that alter the behavior of switches on the device will be
rejected
This is a proposed change the behavior of the home button - so would be rejected.
This is possible on a jail broken device, using un-aproved API's. The concept is in multiple violations of apple's usage policy however so you would never, ever, ever get an app attempting to implement this in any way on the official app store. Here's just a few reasons:
You can't alter the functionality of any buttons (including the volume buttons, some camera apps used to use them to take pictures, but they got booted from the store as a result).
You can't interfere with standard user interactions with the device. The home button takes people home, you can't prevent that, or ask for confirmation as that would be interfering with the interaction.
There is no public API to detect actual usage of the home button. As such you would need a private API, and you can not use private API's without explicit permission from Apple, which they would never give due to #1 and #2 above.
I'm sure there's plenty of more reasons, but regardless it would be in direct violation of app store policies as well as iOS human interface guidelines.
You can detect when the app is about to lose focus, has lost focus, or could loose focus (such as a phone call is coming in) but you can not alter the flow (i.e. not allow the app to lose focus).
You can continue to execute code in the background within the backgrounding guidelines and limitations. The backgrounded code could submit a notification to the user that would allow them to switch back into the app... that's about as close as you could get, and expect apple to reject you if it happens every time the app closes...
Already answered by numerous others, but no, you can't do this. When the user presses the home button, your application delegate's applicationWillResignActive is called which disables touch events to the application. Then applicationDidEnterBackground is called, which, per the Apple docs:
Your delegate’s applicationDidEnterBackground: method has
approximately 5 seconds to finish any tasks and return. In practice,
this method should return as quickly as possible. If the method does
not return before time runs out, your application is killed and purged
from memory
You need proof to show your boss that obviously isn't an iOS developer.
Apple Human Interface Guide
That should be all the proof you need. But to be clear, Apple will not allow an app to override the home button in any way. You can surely put action sheets or pop ups to warn before logging out, but once the home button is pressed, you are on notice to give up your memory, you are being shut down.
You might want to look into the Store Demo Mode of IOS. This way you can disbale the Home button and lock the device in the first app you start after booting.
I know I'm too late to answer this question.
But I recently came with the issue which Samssonart had.
The answer given by #iandotkelly is deprecated with iOS5. Now none of delegate method will be used to distinguish between locking the device or sending app to background using Home button.
you can now use applicationState variable to define what action is triggered.
applicationState is an inbuilt id provided by appDelegate.
**
if it returns 2 then, it will identify the Home button is pressed
if it returns 1 then, it will identify the lock hardware button is pressed
**
So, in your case you can check out this condition in **applicationDidEnterBackground** method
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(#"decision >> %d",[[UIApplication sharedApplication] applicationState]);
}
Enjoy Programming!
The best reference I can find is this one. It's not quite explicit, but Apple's Human Interface Guidelines have a couple of headings 'Always Be Prepared to Stop', followed by 'Don't Quite Programmatically', which spell out what the home button does and that you shouldn't be implementing your own quitting strategies.
I know this is an old topic, but I just want to update this answer. In iOS 7 this is not working.
So I use screenbrightness when the app will go to the background to identify difference between the Home and Lock button.
-(void)applicationDidEnterBackground:(UIApplication *)application {
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateInactive) {
NSLog(#"Sleep button pressed");
} else if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground) {
if ([[UIScreen mainScreen] brightness] > 0.0)
NSLog(#"Home button pressed");
else
NSLog(#"Sleep button pressed");
}
}
I hope this is gonna be of any help for in future for anyone

Crash on resuming app within 11 seconds after exit(0)

I have an app that imports data on start using Core Data. In this part of the app, I have disabled resuming (multitasking) by calling exit(0) in applicationDidEnterBackground when a flag is set. E.g.:
-(void)applicationDidEnterBackground:(UIApplication *)application {
if (allowResuming==NO){
NSLog(#"Terminating...");
exit(0);
}
}
If I then attempt to 'resume' the app (by pressing its icon) within 11 seconds of having pressed the Home button (and, therefore, exit(0) having been called), the app crashes. This doesn't happen when running through the debugger, but the crash logs suggest that it looks like the app is trying to resume the data import where it left off, which, of course, is not what I want.
Attempting to 'resume' the app again straight after this crash (i.e. within a second) is successful.
If I attempt to 'resume' the app after 11 seconds, it's fine.
I would be really grateful if anyone has any ideas and/or can point me in the right direction here.
I don't think you should be doing exit(0). To disable Multitasking, set the key UIApplicationExitsOnSuspend key in Info.plist to YES. For details, see the section Opting Out of Background Execution at
http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/CoreApplication/CoreApplication.html#//apple_ref/doc/uid/TP40007072-CH3-SW1.
To discard the partial work done when the app leaves foreground, add a listener for UIApplicationWillResignActiveNotification or UIApplicationDidEnterBackgroundNotification. In the handler method, you could do something like-
[self discardPartialWorkDone];
HTH,
Akshay
You should not use exit(0) like Akshay said. In addition to that Apple will probably reject your App, because Apps which consist of code which interrupt the App like this wont be approved.