I'm developing a music application which also works on background. I want to catch when there is a phone call on the phone so I can pause the music.
I don't want to use CTCallCenter properties as it requires me to call them time to time. Also I used the following appDelegate method:
-(void)applicationWillResignActive:(UIApplication *)application {
NSLog(#"Phone Call!");
}
It works but it is called just once and it is not only for phone calls and when I click home button and the application is on background it happens and if there is a phone call after that it keeps playing!
Related
I am adding some notifications for when the user sends the application to the background or when they completely quit the app. However when they quit the app, both the methods applicationDidEnterBackground and applicationWillTerminate are called. Why is this so and how can I just have applicationWillTerminate get called when the user quits the app?
This is objective-c for if anyone is wondering.
applicationWillTerminate method will be called only when application is not in suspended state while being terminated.
Following links may help you -
Which function is called when iPhone app is terminated?
applicationWillTerminate when is it called and when not
Seeing that applicationWillTerminate is called after applicationDidEnterBackground I have decided to set a notification.fireDate of 1sec from the point at which applicationDidEnterBackground is called. When applicationWillTerminate is called it first cancels the notification that was scheduled within applicationDidEnterBackground.
Pseudocode:
-applicationDidEnterBackground()
{
[self scheduleLocalNotificationAtTimeIntervalFromNow:1.0f identifier: #"someIdentifier"];
}
-applicationWillTerminate
{
[self cancelLocalNotificationWithIdentifier: #"someIdentifier"];
[self scheduleLocalNotificationAtTimeIntervalFromNow:0.0f identifier: #"irrelevantIdentifier"];
}
I'm using the ServiceManagement framework to add a login item that will launch a Helper App, which will launch the main app whenever the user logs back in. The addLoginItem and disableLoginItem methods are called if the user selects or deselects "Launch at Login" with an NSButton of a switch-type:
//Add the Helper app as a login item
- (void)addLoginItem
{
NSLog(#"Enable login item");
if (!SMLoginItemSetEnabled((__bridge CFStringRef)kLoginHelperBundleIdentifier, true)) {
}
}
//Disable the Helper app as a login item
- (void)disableLoginItem
{
NSLog(#"Disable login item");
if (!SMLoginItemSetEnabled((__bridge CFStringRef)kLoginHelperBundleIdentifier, false)) {
}
}
The code for the helper app is rather simple...
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
[[NSWorkspace sharedWorkspace] launchApplication: #"My App"];
[[NSApplication sharedApplication] terminate:self];
}
The problem is that when the Main App is running, if a user repeatedly selects and deflects the 'Launch At Login' button, a second instance of the Main App will be launched. Whereas, what I want to happen is that the Main App will only be launched upon the user logging back in.
Upon looking at SMLoginItem.h, I saw that the documentation stated the following:
* #param enabled
* The Boolean enabled state of the helper application. This value is effective
* only for the currently logged in user. If true, the helper application will
* be started immediately (and upon subsequent logins) and kept running. If
* false, the helper application will no longer be kept running.
So, it seems as if the Helper App is being launched every time addLoginItem is called. Knowing that, I modified my Helper App to check if my main app is already running. If it is, then we will terminate the Helper App. Otherwise, we'll launch an instance of the Main App, and then terminate the Helper App.
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
if ([NSRunningApplication runningApplicationsWithBundleIdentifier:#"com.myCompany.MyApp"]){
[[NSApplication sharedApplication] terminate:self];
}
else {
[[NSWorkspace sharedWorkspace] launchApplication: #"My App"];
[[NSApplication sharedApplication] terminate:self];
}
}
However, if the user selects and deselects the "Launch At Login" button repeatedly, then a second instance of the Main App will be created. Does anyone have any idea on how to make sure a second instance of the Main App is not created by the Helper App if the user toggles "Launch At Login" multiple times?
EDIT The app is not being distributed through the Mac App Store, which is why I do not have code-signing or sandboxing enabled per the instruction in this tutorial.
The problem being that I had a few different copies of the application on my system (specifically, one on the desktop and on in the applications folder). Removing one of these application instances resolved my issue.
In app delegate, I have written some code in the didRecieveLocalNotification Method which firstly determines which local notification was triggered, and then generates a UIAlert once the app re opens after clicking the notification banner.
If my app is closed, the local notification is still received, and clicking on it does re open the app from its terminated state, however the code inside of the didRecieveLocalNotification method is not triggering at all. I can't even get a NSLog to work.
Anything I can do to fix this?
Have a look at https://developer.apple.com/library/ios/documentation/iphone/Reference/UILocalNotification_Class/Reference/Reference.html
You can get this information in application:didFinishLaunchingWithOptions, but only if user taps the local notification.
When the system delivers a local notification, several things can happen, depending on the application state and the type of notification. If the application is not frontmost and visible, the system displays the alert message, badges the application, and plays a sound—whatever is specified in the notification. If the notification is an alert and the user taps the action button (or, if the device is locked, drags open the action slider), the application is launched. In the application:didFinishLaunchingWithOptions: method the application delegate can obtain the UILocalNotification object from the passed-in options dictionary by using the UIApplicationLaunchOptionsLocalNotificationKey key. The delegate can inspect the properties of the notification and, if the notification includes custom data in its userInfo dictionary, it can access that data and process it accordingly. On the other hand, if the local notification only badges the application icon, and the user in response launches the application, the application:didFinishLaunchingWithOptions: method is invoked, but no UILocalNotification object is included in the options dictionary.
If the application is foremost and visible when the system delivers the notification, no alert is shown, no icon is badged, and no sound is played. However, the application:didReceiveLocalNotification: is called if the application delegate implements it. The UILocalNotification instance is passed into this method, and the delegate can check its properties or access any custom data from the userInfo dictionary.
When you app is neither running nor in the background, your notification is received in application:didFinishLaunchingWithOptions: method in your app delegate.
You can use the below code to access the notification object.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif) {
// Show Alert Here
}
}
i have a button in my app a button that submit score to gamecenter and works.
this is the code:
-(void)subScore{
GKScore *scoreRepoter = [[[GKScore alloc] initWithCategory:#"123456"] autorelease];
scoreRepoter.value=100;
[scoreRepoter reportScoreWithCompletionHandler:^(NSError *error) {
if (error!=nil) {
NSLog(#"errr submitting");
}else
NSLog(#"ok!");
}];
now i'd like to submit score before app is closed with home button.
i thought to customize an action of home button (if it is possible)
or perhaps i make the same line of code in viewDidUload...or something like that...
will i be sure that that action will be performed before unloading the app?
i should make that code in dealloc method?
thanks
You can't customize behaviour of Home button directly, but iOS provides some methods in your application's delegate, by which you can control lifecycle of the application.
Method called right before the application goes to background is applicationWillResignActive: in your application's delegate (usually this method is located in AppDelegate.m file).
I think you can get needed effect by calling your method like that:
- (void)applicationWillResignActive:(UIApplication *)application {
[mygame subScore];
}
Also please note that iOS has time limit of execution for this method: you must do all saving-the-game work in less that five seconds or your application will be killed.
I would like to know if we can actually redirect the alert box to a specific view. Meaning that when they clicked on "View" which is on the notification alert, it will redirect them to a particular view, just like the text message notification pop up. Is there any idea on how this works?
From your question, you could mean two types of alert dialogs:
The generic "alert box" you mention, or UIAlertView
A UILocalNotification alert dialog, shown when the application is in the background ("just like the text message notification pop up")
I will address them in order.
First, how to handle a UIAlertView "View" button click.
Implement the alertView:didDismissWithButtonIndex: method of the UIAlertViewDelegate protocol in your controller class, and when you init the UIAlertView set its delegate to self. Then when the user clicks a button marked e.g. "View", do this:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if([[alertView buttonTitleAtIndex:buttonIndex] isEqualToString:#"View"])
{
// take the user to a specific view
} else { // handle other cases if you have any
}
}
Secondly, how to handle a UILocalNotification which triggers an application launch.
Apple docs on UILocalNotification state:
If the notification is an alert and the user taps the action button (or, if the device is locked, drags open the action slider), the application is launched. In the application:didFinishLaunchingWithOptions: method the application delegate can obtain the UILocalNotification object from the passed-in options dictionary by using the UIApplicationLaunchOptionsLocalNotificationKey key. The delegate can inspect the properties of the notification and, if the notification includes custom data in its userInfo dictionary, it can access that data and process it accordingly.
On the other hand, if the local notification only badges the application icon, and the user in response launches the application, the application:didFinishLaunchingWithOptions: method is invoked, but no UILocalNotification object is included in the options dictionary.
You need to write code for handling this launch case in your app delegate class, in the application:didFinishLaunchingWithOptions: method.
IF you happen to get a UILocalNotification while the app is running, Apple docs state:
If the application is foremost and visible when the system delivers the notification, no alert is shown, no icon is badged, and no sound is played. However, the application:didReceiveLocalNotification: is called if the application delegate implements it. The UILocalNotification instance is passed into this method, and the delegate can check its properties or access any custom data from the userInfo dictionary.
EDIT: To take the user to a specific view straight away, you can manually push something onto a UINavigationController stack (if your app usually operates with navigation controllers, it makes sense to do this), or present a modal view controller. I've linked there to guides for both.