Brittany
Brittany

Reputation: 1449

iOS/Obj-C - Fire local notification without timer?

I want to setup some local notifications in my iOS app, however every tutorial I seem to find on implementing these seems to only allow me to fire a notification based on a timer (see sample code below)? Is it possible to fire a local notification for example when new data is loaded to a UITableView? Sorry for the general question, but I can't seem to find a whole lot of documentation on this. I'm also not sure how I could do this if data is only grabbed when my user hits a screen? E.g. data is grabbed/updated in viewDidLoad of ViewController?

-(void)viewDidLoad {

        UILocalNotification *localNotification = [[UILocalNotification alloc] init];
        localNotification.fireDate = dateTime;
        localNotification.alertBody = [NSString stringWithFormat:@"Alert Fired at %@", dateTime];
        localNotification.soundName = UILocalNotificationDefaultSoundName;
        localNotification.applicationIconBadgeNumber = 1;
        [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];

    }

Upvotes: 6

Views: 2041

Answers (5)

Kirill  Dubovitskiy
Kirill Dubovitskiy

Reputation: 306

First of all you should consider the fact that UILocalNotification class that you are using is deprecated starting from iOS 10. Since iOS 10 there is no distinction between local and remote notifications.

In UserNotifications framework (iOS 10.0+, Swift | Objective-C) one does not create instances of UNNotification like in some of the previous implementations of similar frameworks / API's by Apple. Instead, an instance of UNNotificationCenter is responsible for creating notification objects and calls delegate methods when new notifications are received and before the default UI will be displayed. See Apple's documentation for more details on the requirements for conforming UNUserNotificationCenterDelegate protocol. I often end up using AppDelegate as a class conforming to that protocol

Now back to the question. To initiate a creation of the notification from within the app first you should create a trigger (in your case you might want to use UNTime​Interval​Notification​Trigger), then create a notification request and finally add the request to the notification center singleton that can be accessed by calling UNUserNotificationCenter.current().

let content = UNMutableNotificationContent()
content.title = "Alert Fired"

Create a trigger that will determine the moment when UNUserNotificationCenter will invoke the notification

let trigger = UNTime​Interval​Notification​Trigger(timeInterval: 0, repeats: false)

Create a notification request. You only create those to invoke local notifications, since iOS is responsible for creating request objects for incoming push notifications.

let request = UNNotificationRequest(identifier: "FiveSecond", content: content, trigger: trigger)

Now we will have to add our request to the current notification center associated with our app.

let center = UNUserNotificationCenter.current()
center.add(request, withCompletionHandler: nil)

In our case the notification will be triggered immediately by the UNUserNotificationCenter.

Upvotes: 4

Jagveer Singh
Jagveer Singh

Reputation: 2328

first thing in mind for what ios you need local local notification

// Handle launching from a notification

if(IOS_VERSION<10)
{
    UILocalNotification *locationNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
    if (locationNotification)
 {
    // Set icon badge number to zero
    application.applicationIconBadgeNumber = 0;
}

if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)])
{

    [application registerUserNotificationSettings:[UIUserNotificationSettings
                                                   settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|
                                                   UIUserNotificationTypeSound categories:nil]];
}

}else{

[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound)
                                                                    completionHandler:^(BOOL granted, NSError * _Nullable error) {
                                                                        // Enable or disable features based on authorization.
                                                                    }];

}

and final thing

    if(IOS_VERSION<10){

        [[UIApplication sharedApplication] cancelAllLocalNotifications];

        NSLog(@"LocalNotifications]count %d",(int) [[[UIApplication sharedApplication] scheduledLocalNotifications]count]);

        NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar] ;
        NSDate *now = [NSDate date];
        NSDateComponents *components = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth |  NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute) fromDate:now];
        [components setHour:15];
        [components setMinute:35];

        UILocalNotification *notification = [[UILocalNotification alloc]init];
        notification.fireDate = [calendar dateFromComponents:components];
        notification.repeatInterval = NSCalendarUnitDay;
        notification.alertBody =@"message";
        notification.applicationIconBadgeNumber = 0;
        notification.soundName = UILocalNotificationDefaultSoundName;
        [[UIApplication sharedApplication] scheduleLocalNotification:notification];


    }else{

        [[UNUserNotificationCenter currentNotificationCenter] removeAllPendingNotificationRequests];
        NSLog(@"LocalNotifications]count %d",(int) [[[UIApplication sharedApplication] scheduledLocalNotifications]count]);

        NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar] ;
        NSDate *now = [NSDate date];
        NSDateComponents *components = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth |  NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute) fromDate:now];
        [components setHour:15];
        [components setMinute:35];




        UNMutableNotificationContent *objNotificationContent = [[UNMutableNotificationContent alloc] init];
//        objNotificationContent.title = [NSString localizedUserNotificationStringForKey:NotificationHeading arguments:nil];
        objNotificationContent.body = [NSString localizedUserNotificationStringForKey:@"message"
                                                                            arguments:nil];
        objNotificationContent.sound = [UNNotificationSound defaultSound];

        /// 4. update application icon badge number
        objNotificationContent.badge = @([[UIApplication sharedApplication] applicationIconBadgeNumber]);

//        UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger
//                                                      triggerWithTimeInterval:60 repeats:YES];

        UNCalendarNotificationTrigger *trigger2 = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:YES];

        UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"FiveSecond"
                                                                              content:objNotificationContent trigger:trigger2];

        /// 3. schedule localNotification
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];


        [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
            if (!error) {
                NSLog(@"Local Notification succeeded");
            }
            else {
                NSLog(@"Local Notification failed");
            }
        }];


    }

Upvotes: 0

Raza.najam
Raza.najam

Reputation: 769

You can simply give The time as [NSDate date] whenever you want to fire local notification. It will fire a notification at current time.

Upvotes: 1

HarmVanRisk
HarmVanRisk

Reputation: 303

You can use the method postNotificationName like this:

MyCustomObject *customObject = [MyCustomObject new];
[[NSNotificationCenter defaultCenter] postNotificationName:@"Your notification name" object:customObject];

Processing the object coming through from the posted notification would look something like this. Obviously, I am only logging here but you can process it whatever way you like.

- (void)methodToProcessNotificationData:(NSNotification *)notification {
   NSLog(@"%@",notification.object);
}

When you want a class to listen for the notification you can do something like the below chunk of code. This adds the observer to the class, gives it the method that is to be called (in this instance methodToProcessNotificationData) and the notification name that you wish to listen out for.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(methodToProcessNotificationData:) name:@"Your notification name" object:nil];

Upvotes: 3

jokeman
jokeman

Reputation: 1297

You can use below method[1] instead:

- (void)postNotificationName:(NSNotificationName)aName 
                      object:(id)anObject 
                    userInfo:(NSDictionary *)aUserInfo;

[1]https://developer.apple.com/reference/foundation/nsnotificationcenter/1410608-postnotificationname?language=objc

Upvotes: 1

Related Questions