I have an application an I managed to make a custom remote controller with help of this question on stack overflow.
it works fine but in I want to bring app to foreground by asking the user to unlock the phone, something like apple Musics share button action. Is it possible to ask user to unlock the phone and bring app to foreground to complete an action?
I managed to make it work using local notification, but I think there need to be an alert view or a user interaction with button. Is it possible to make it work without any pop-up?
Here is the code I used to change lock screen controllers button
//App delegate
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)]){
[application registerUserNotificationSettings:[UIUserNotificationSettings
settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|
UIUserNotificationTypeSound categories:nil]];
}
}
// inside viewDidLoad
MPRemoteCommandCenter *rcc = [MPRemoteCommandCenter sharedCommandCenter];
MPFeedbackCommand *likeCommand = [rcc likeCommand];
[likeCommand setEnabled:YES];
[likeCommand setLocalizedTitle:#"I love it"]; // can leave this out for default
[likeCommand addTarget:self action:#selector(likeEvent:)];
MPFeedbackCommand *dislikeCommand = [rcc dislikeCommand];
[dislikeCommand setEnabled:YES];
[dislikeCommand setActive:YES];
[dislikeCommand setLocalizedTitle:#"I hate it"]; // can leave this out for default
[dislikeCommand addTarget:self action:#selector(dislikeEvent:)];
BOOL userPreviouslyIndicatedThatTheyDislikedThisItemAndIStoredThat = YES;
if (userPreviouslyIndicatedThatTheyDislikedThisItemAndIStoredThat) {
[dislikeCommand setActive:YES];
}
//Selectors:
-(void)dislikeEvent: (MPFeedbackCommandEvent *)feedbackEvent
{
//I need to ask user to unlock the phone and bring app to foreground
NSLog(#"Mark the item disliked");
}
-(void)likeEvent: (MPFeedbackCommandEvent *)feedbackEvent
{
//I need to ask user to unlock the phone and bring app to foreground
NSLog(#"Mark the item liked");
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:0];
notification.alertBody = #"This is local notification!";
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
I suppose these delegate methods in the appdelegate.h would be helpful.
I think you could use the last one, "application did become active."
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
OR
By using notification center you can perform any actions in particular classes, i have used will enter foreground. There are different options available as per users requirements.
- (void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(appReturnToForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
}
- (void)appReturnToForeground {
// Your code...What you want to perform.
}
Related
I have a app to which i can send push notifications using pushbots. The user is able to receive the notification and on clicking it he/she can open the app. However the badge notification still shows that there is a notification. How would i set my notification badge to 0.
This is my appdelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Register for Remote Notifications
[Pushbots sharedInstanceWithAppId:#"5503e09a1d0ab1481f8b45a1"];
NSDictionary * userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if(userInfo) {
// Notification Message
NSString* notificationMsg = [userInfo valueForKey:#"alert"];
// Custom Field
NSString* title = [userInfo valueForKey:#"title"];
NSLog(#"Notification Msg is %# and Custom field title = %#", notificationMsg , title);
}
return YES;
}
-(void)onReceivePushNotification:(NSDictionary *) pushDict andPayload:(NSDictionary *)payload {
NSString* message = [pushDict valueForKey:#"alert"];
UIAlertView *alertMessage = [[UIAlertView alloc] initWithTitle:#"New Event !" message:message delegate:self cancelButtonTitle:#"Open" otherButtonTitles: #"I will check later",nil];
[alertMessage show];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
Pushbots * pushbots = [Pushbots sharedInstance];
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"Open"]) {
[pushbots OpenedNotification];
}
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
#end
You can call this in your application :
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
Obviously this needs a little more work. If you're dealing with messages for example, you'd need to decrement the badge number by the number of messages read and make sure to not go below zero.
You can also use the "badge" key to modify the current badge through the notification payload itself.
for example use
{..., "badge" : "increment", ...}
or
{...,"badge" : 3, ...}
The first one would be the most frequent version i'm guessing.
But if your app is fairly simple, then just call this and your badge will be set to zero.
I'd advise you to update your pushbots lib to 1.1 and use the following method which will clear the badge locally and on the server:
[[Pushbots sharedInstance] clearBadgeCount];
For Swift 3
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
UIApplication.sharedApplication().applicationIconBadgeNumber = 0
Pushbots.sharedInstance().clearBadgeCount()
}
func applicationWillEnterForeground(application: UIApplication)
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
UIApplication.sharedApplication().applicationIconBadgeNumber = 0
Pushbots.sharedInstance().clearBadgeCount()
}
Objective C
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
[[Pushbots sharedInstance] clearBadgeCount];
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
[[Pushbots sharedInstance] clearBadgeCount];
}
My App receives APNS Push Notifications, and when a user receive more than one NSNotification, he should be able to open the app in a specific view according the NSNotification tapped.
So in the method
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:
(void (^)(UIBackgroundFetchResult))completionHandler
I added this code to save all the notifications
if (self.notifications == nil) {
self.notifications = [[NSMutableArray alloc] init];
}
[notifications addObject:userInfo];
And every time the app becomes active again it does this
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started)
// while the application was inactive.
// If the application was previously in the background,
// optionally refresh the user interface.
[notifications removeAllObjects];
application.applicationIconBadgeNumber = 0;
}
Before removing all the objects and setting the badge to zero, I would like to handle which NSNotification made my app open from the background. And once I have which push NSNotification it was, I would like to pass all the data to a specific view.
Based on your comment about UILocalNotification usage
UILocalNotification has a userInfo property. When you create your local notification from the push notification, set the appropriate information into this property and then when the app delegate receives application:didReceiveLocalNotification: you can use that into to update your UI.
If you not use new iOS7 background fetch notifications.
In - (void)applicationDidBecomeActive:(UIApplication *)application before removing all object from notification array, check for notification
NSDictionary * myNotification = [notifications lastObject];
if (myNotification)
{
// is last notification
}
Is will work because app receive only notification that user tap on it
Send with your push notification, data, and use it when your app receives it.
In this example, i'm using the image file and alert, and sending it to all the views that are registered for this Notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
//Posting the notificaiton to the use, if its valid:
NSDictionary *returnDic = [userInfo objectForKey:#"aps"];
if (![returnDic objectForKey:#"alert"]) {
return;
}
NSString *alert = [NSString stringWithFormat:#"%#",[returnDic objectForKey:#"alert"]];
if (![returnDic objectForKey:#"MagnetID"]) {
return;
}
NSString *magnetImage = [returnDic objectForKey:#"MagnetImage"];
NSDictionary *dictionaryToSend = [NSDictionary dictionaryWithObjectsAndKeys:magnetImage,MAGNET_IMAGE,alert,MAGNET_ERROR_MESSEGE, nil];
//Posting to the rest of the views, the messege:
[[NSNotificationCenter defaultCenter] postNotificationName:USER_MESSEGE_RECEAVED object:nil userInfo:dictionaryToSend];
NSLog(#"Notifications - userInfo=%#",userInfo);
}
What you may do, is save the data that you need, by UserDefults or whatever you prefer, and at the "applicationDidBecomeActive" method, use that data to show the right view.
Hope this helps
I am trying to add some RevMob code into my app, the app currently has IAP in it and I am looking to add some advertising (fullscreen).
Now I currently have my code placed in the following method
- (void)applicationDidBecomeActive:(UIApplication *)application {
RevMobFullscreen *fullscreen;
fullscreen = [[RevMobAds session] fullscreen];
fullscreen.delegate = self;
[fullscreen loadAd];
[fullscreen showAd];
}
The problem is that this causes the advert to appear far too often. Ideally I only want to call the advert when the app first loads and then when the user closes the app and then reopens it (standby mode).
The above code is calling the advert code when the user also interacts with the IAP because the alert box is opened asking whether the user wants to buy.
Any Suggestions?
"Ideally I only want to call the advert when the app first loads and then when the user closes the app and then reopens it (standby mode)."
Implement the following methods of the UIApplicationDelegate:
application:didFinishLaunchingWithOptions:
As I'm sure you are well aware, this method fires once when the app is first launched. We have to implement this method because the following method is not called on first launch.
applicationWillEnterForeground:
From the documentation:
This method is called as part of the transition from the background to the active state.
This method is only called when the application moves from a background state. Unlike the applicationDidBecomeActive: method you were experiencing problems with applicationWillEnterForeground: is not called after brief interruptions such as dismissing an incoming SMS or phone call or interacting with In-App Purchases.
Code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
[self showAd];
return YES;
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[self showAd];
}
- (void)showAd
{
RevMobFullscreen *fullscreen;
fullscreen = [[RevMobAds session] fullscreen];
fullscreen.delegate = self;
[fullscreen loadAd];
[fullscreen showAd];
}
Use
application:didFinishLaunchingWithOptions:
for the initial launch of the app.
For the coming from backward feature record the date time like so
- (void)applicationDidEnterBackground:(UIApplication *)application
{
self.timeEnteredBackground = [NSDate date];
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
NSDate* now = [NSDate date];
double diff = [now timeIntervalSinceDate:timeEnteredBackground];
if (diff > SOME_SECONDS)
This way the ad will only appear after a background time greater than some threshold.
I would like to know, if it is possible to somehow "wake up" a task that is in the background, to quickly check something on the network.. I think that this could be done with UILocalNotification, however, no matter what I tried, I could not get the didReceiveLocalNotification to do ANYTHING when the app is in the background.. After starting up, I immediately close the app by pressing the Home button (there is a 10 second delay for local notification to fire). This code works PERFECTLY when the app is in the foreground, and just kind of sitting there...
In app delegate header file:
UILocalNotification *localNotif;
For testing, I set up local notification to fire quickly in the appDelegate startup.
localNotif = [[UILocalNotification alloc] init];
localNotif.fireDate = [NSDate dateWithTimeIntervalSinceNow:10]; // the date you want the notification to fire.
localNotif.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
NSLog(#"setup the timer for 10 seconds");
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
UIApplicationState state = [application applicationState];
NSLog(#"getting kicked");
if (state == UIApplicationStateInactive) {
// Application was in the background when notification was delivered.
NSLog(#"INACTIVE..");
} else {
NSLog(#"ACTIVE..");
}
}
The user has a couple of choices: #1) Do they want to see a notification for your app. #2) If notifications are enabled for your app, do they want to click on your notification to launch your app. If they do accept notifications and open your notification while your app is in the background, application:didReceiveLocalNotification is called. To be clear, the user has to accept the notification (such as sliding the slider underneath the notification)... otherwise NOTHING is called.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
NSLog(#"%#", notification);
}
If your app has been terminated application:didFinishLaunchingWithOptions: is called -
- (BOOL)application:(UIApplication *)
application didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions {
UILocalNotification *theNotification =
[launchOptions
objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
NSLog(#"%#", theNotification);
return YES;
}
I am trying to do two things for a simple test app.
I am stuck at trying to learn how to use beginBackgroundTaskWithExpirationHandler
I want to execute a backgroundTask when the user presses the home button (nothing fancy). In 9 minutes, I'd like to alert the user that the time is about to expire (if possible) and allow the user to switch back into the app to renew the 10 minutes.
I don't need backward compatibility with iOS 3, or 4.
If you want your code to continue in the background, then you'll need to wrap it in a background task. It's also very important that you call endBackgroundTask when you're finished - otherwise the app will be killed after it's allotted time has expired
- (IBAction) buttonPressed: (id) sender
[self beingBackgroundUpdateTask];
// Do your long running background thing here
[self endBackgroundUpdateTask];
});
}
- (void) beingBackgroundUpdateTask
{
self.backgroundUpdateTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[self endBackgroundUpdateTask];
}];
}
- (void) endBackgroundUpdateTask
{
[[UIApplication sharedApplication] endBackgroundTask: self.backgroundUpdateTask];
self.backgroundUpdateTask = UIBackgroundTaskInvalid;
}
Put the code in the applicationDidEnterBackground function in your UIApplicationDelegate. You will need to set up a UILocalNotification and schedule it. You should also probably disable it in applicationWillEnterForeground so it doesn't fire off the user goes back to the app before it expires.
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UILocalNotification *timerNotification = [[UILocalNotification alloc] init];
//set up notification with proper time and attributes
[[UIApplication sharedApplication] scheduleLocalNotification:timerNotification];
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
The cancelling code I gave there will actually cancel all notifications. If you have multiple notifications and only want to cancel a specific one, you should give the userInfo property of your notification a key/value when you set it up. Then, when the application enters the foreground, get the list of all active notifications by doing
NSArray *notifications = [[UIApplication sharedApplication] scheduledLocalNotifications];
and loop through them, checking userInfo until you get to the one you want and then just cancelling that one with
[[UIApplication sharedApplication] cancelLocalNotification:whateverNotification];