Custom UIButton with local notification - ios

I'm trying to create a custom button that then schedules a local notification. The code I've found on here seems to be outdated. I've looked at the outlines from Apple https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/IPhoneOSClientImp.html
But I'm still pretty confused. Can anyone post a clean and concise example including which files I put which code? (Including registering) Even just an example of creating any local notification would be helpful, thanks!

In AppDelegate.m, register the types of user interactions the app supports (from iOS 8.0 and later)
UIUserNotificationType types = (UIUserNotificationType) (UIUserNotificationTypeBadge |
UIUserNotificationTypeSound | UIUserNotificationTypeAlert);
UIUserNotificationSettings *mySettings =
[UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
Inside the button tapped method you do this:
NSDate * fireDate; // The schedule date time.
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = fireDate;
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.alertBody = #"alertText";
localNotification.alertAction = #"buttonTitle";
localNotification.soundName = UILocalNotificationDefaultSoundName;
// Schedule it with the app
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
In AppDelegate.m add this method to handle when a local notification arrives (if necessary):
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)localNotification{
// This method gets called when a local notification arrives
}

Related

How to generate faster local notification in iOS?

I am generating Local notification when Push notification(Actionable) are received but app is closed or in background. I have used following code to generate local notification in objective-c.
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler {
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
// localNotification.fireDate = [NSDate date];
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.alertBody = #"Security settings enabled, tap to start the application";
localNotification.category = #"LOCAL_NOTIFICATION"; // Same as category identifier
// [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}
1.When i drag notification trey down(Notification Center) not from alert it generate local notification fine in 1 sec.
2.But while press action from alert(while at home) it
it takes 3-4 seconds for local notification to appear.
Why there is time difference between action from alert(press action from home) and Notification center(swipe down notification trey)
generating local notification?
How to make it faster? Thanks in advance.
Try to use the presentLocalNotificationNow method instead of scheduleLocalNotification to make your notification fire instantly:
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];

Why does UIAlert generated by UILocalNotification display "Options" instead of action title?

I am trying to set up an Apple Watch app (presenting flashcards) which fires a notification when a new question is due. If the iPhone is open but the app is in the background it fires a UIAlert, and clicking the action button ("View") opens the app. If the iPhone is locked the notification fires on the Apple Watch with a short glance-long glance with a button "View Question" which opens the Apple Watch app.
It works, but the UIAlert on the iPhone has an annoying "Options" button which requires you to click "Options" to open another UIAlert with two action buttons ("View" and "View Question"), either of which will open the iPhone app. Here is the relevant code which first cancels all previous notifications (as the app allows you to answer a new question before the timer is finished, at which point the timer is reset). It then sets up a notification to be displayed on the iPhone; and finally sets up a notification for the Apple Watch.
// Cancel previous notifications
[[UIApplication sharedApplication] cancelAllLocalNotifications];
// Set up iPhone notification
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:(int)dateLatency];
localNotification.timeZone = [NSTimeZone defaultTimeZone];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSInteger intVal = [prefs integerForKey:#"timeLag"];
localNotification.alertBody = [NSString stringWithFormat:#"%ld-%d", (long)intVal, (int)dateLatency];
localNotification.alertAction = [NSString stringWithFormat:#"View"];
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.alertLaunchImage = nil;
localNotification.category = #"qDue";
localNotification.userInfo = [self createAPNS:#"999"]; // function that constructs userInfo json structure
// Set up apple watch notification
NSMutableSet *categories = [[NSMutableSet alloc] init];
UIMutableUserNotificationAction *viewQuestion = [[UIMutableUserNotificationAction alloc] init];
viewQuestion.title = #"View Question";
viewQuestion.identifier = #"viewQuestion";
viewQuestion.activationMode = UIUserNotificationActivationModeForeground;
viewQuestion.authenticationRequired = false;
UIMutableUserNotificationCategory *questionCategory = [[UIMutableUserNotificationCategory alloc] init];
questionCategory.identifier = #"qDue";
[questionCategory setActions:#[viewQuestion] forContext:UIUserNotificationActionContextDefault];
[categories addObject:questionCategory];
UIUserNotificationType notificationType = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:notificationType categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
// Schedule it with the app
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
I can get rid of the "Options" button and the extra UIAlert by deleting the apple watch notification, but then there is no notification on the apple watch.
Can anybody tell me why the "Options" button appears, and how to get rid of it?

ask user for permission to show alert when firing local notification

I want to show an alert when the local notification is fired, but for that I have to ask for permission, as it says to me when I run the app on my iPhone:
Attempting to schedule a local notification {fire date = Friday 13 June 2014 12 h 10 min 27 s Central European Summer Time, time zone = (null), repeat interval = 0, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = Friday 13 June 2014 12 h 10 min 27 s Central European Summer Time, user info = (null)} with an alert but haven't received permission from the user to display alerts
How can I do that?
Here´s the code as it is now:
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.fireDate = [[NSDate date] dateByAddingTimeInterval:timeUntilNotification];
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.alertBody = #"ZEIT!";
localNotif.alertAction = #"Show me the Timer!";
localNotif.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] +1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
add this code, it will show a alert view to ask user for permission.
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)]) {
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeSound|UIUserNotificationTypeBadge
categories:nil]];
}
you can add this code in application:didFinishLaunchingWithOptions; method, so that the app will ask your user when they launch the app, or you can add this code when you set Local Notification, it's up to you.
蘇健豪's answer is good.
In Swift it looks like this:
let registerUserNotificationSettings = UIApplication.instancesRespondToSelector("registerUserNotificationSettings:")
if registerUserNotificationSettings {
var types: UIUserNotificationType = UIUserNotificationType.Alert | UIUserNotificationType.Sound
UIApplication.sharedApplication().registerUserNotificationSettings(UIUserNotific‌​ationSettings(forTypes: types, categories: nil))
}
Also see here: Ask for User Permission to Receive UILocalNotifications in iOS 8
//register notifications
if([application respondsToSelector:#selector(registerUserNotificationSettings:)]) //ios 8+
{
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
[application registerForRemoteNotifications];
}
else // ios 7 or less
{
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge];
}
In the swift language....
var type = UIUserNotificationType.Badge | UIUserNotificationType.Alert | UIUserNotificationType.Sound;
var setting = UIUserNotificationSettings(forTypes: type, categories: nil);
UIApplication.sharedApplication().registerUserNotificationSettings(setting);
UIApplication.sharedApplication().registerForRemoteNotifications();
Try this for Objective-C
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
NSLog(#"didFinishLaunchingWithOptions");
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)]) {
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeSound categories:nil]];
}
return YES;
}

How to check if Local Notification is enabled/disabled?

I understand we can check if a user has enabled/disabled Remote Notification with this code:
[[UIApplication sharedApplication] enabledRemoteNotificationTypes]
But what about checking for Local Notification?
I don't find a corresponding property for local notification types, and I have verified that enabledRemoteNotificationTypes is only for remote notifications.
And we all know, users can edit their Notification settings, which will affect both remote and local.
I'm not sure, but I don't think you can access this information.
One way you can check if the user has notifications enabled for your app is to send yourself a local notification with a 1 second delay :
UILocalNotification *testNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:1];
localNotification.alertBody = #"Test notification";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
And check if you catch it in :
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification) {
// If you get here, notifications are enabled
}
All there is left is add info (e.g in localNotification.userInfo) so you can know in didReceiveLocalNotification: if you are handling your test notification, or if it's a "real" notification.
- (BOOL) isLocalNotificationsEnable {
if ([[UIApplication sharedApplication] respondsToSelector:#selector(currentUserNotificationSettings)]) {
UIUserNotificationSettings *grantedSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];
return (grantedSettings.types == UIUserNotificationTypeNone) ? NO : YES;
}
return NO;
}
Note: the if block is only require if you're targeting < iOS 8.0.

Difference between presentLocalNotificationNow and scheduleLocalNotification

What is the difference between presentLocalNotificationNow and scheduleLocalNotification.
For the both following function is showing notification after 1 second
-(void)showLocalNotification:(NSNotification *)notification {
NSString *msg = #"test message";
[[UIApplication sharedApplication] cancelAllLocalNotifications];
UILocalNotification *_localNotification = [[UILocalNotification alloc]init];
_localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:1];
_localNotification.timeZone = [NSTimeZone defaultTimeZone];
_localNotification.alertBody = msg;
_localNotification.soundName = UILocalNotificationDefaultSoundName;
_localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber]+1;
[[UIApplication sharedApplication] scheduleLocalNotification:_localNotification];
// or
//[[UIApplication sharedApplication] presentLocalNotificationNow:_localNotification];
}
If the application is running in the background, the local notification will not get an alert or sound, as it is directly received by the application. In that case, you need to present the notification using presentLocalNotificationNow.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
UIApplicationState applicationState = application.applicationState;
if (applicationState == UIApplicationStateBackground) {
[application presentLocalNotificationNow:notification];
}
}
From Apple Documentation:
Once you have created an instance of UILocalNotification, you schedule
it using one of two methods of the UIApplication class:
scheduleLocalNotification: or presentLocalNotificationNow:. The former
method use the fire date to schedule delivery; the latter method
presents the notification immediately, regardless of the value of
fireDate. You can cancel specific or all local notifications by
calling cancelLocalNotification: or cancelAllLocalNotifications,
respectively.
There's no difference right here, but using scheduleLocalNotification you can schedule it at whatever time you want, not only in one second.
And, of corse, nobody promises you that presentLocalNotificationNow will show one in exactly one second, not in 0.5 or 2.0 in iOS 8, for example.

Resources