iOS Tutorial Identifying LocalNotification using 'Tag'

You may have come across a scenario where your app can register more than one local notification at a time. One such example can be an alarm app, where each alarm will have its own tag.

The out of the box functionality provided by B4i LocalNotification is slick like everything else. But it does not (in my knowledge) have a way to identify what the triggered local notification is about? Going back to the alarm example, how do you know which alarm in your app is the one that has just got triggered so when the user taps the notification, you can perform a specific action based on a key provided by the notification.

iOS in all its wisdom does not provide a 'tag' mechanism when it comes to local notifications, hence, B4i doesn't have it IMO. To achieve the same effect, iOS folks have provided a 'userInfo' NSDictionary object to store data with your local notifications.

I've written a bit of in-line objective c code to allow you to set a tag against a local notification.

You need to copy the following in your page's code/class module:

B4X:
#If OBJC
-(void) setNotificationTag: (UILocalNotification*) localNotification: (NSString*) notificationTag  {
    NSArray *keys = @[@"key"];
    NSArray *values = [NSArray arrayWithObject:notificationTag];
    NSDictionary *uinfo = [NSDictionary dictionaryWithObjects:values forKeys:keys];
    localNotification.userInfo = uinfo;
}

-(void) printLocalNotification: (UILocalNotification*) localNotification  {
    NSDictionary *uinfo = localNotification.userInfo;
    NSLog(@"value = %@",[uinfo valueForKey:@"key"]);
}
-(NSString*) getNotificationTag: (UILocalNotification*) localNotification  {
    NSDictionary *uinfo = localNotification.userInfo;
    NSString *str = [uinfo valueForKey:@"key"];
    return str;
}
-(void) removeScheduledNotification: (NSString*) notificationTag {
    UIApplication *app = [UIApplication sharedApplication];
    NSArray *eventArray = [app scheduledLocalNotifications];
    for (int i=0; i<[eventArray count]; i++) {
        UILocalNotification* oneEvent = [eventArray objectAtIndex:i];
        NSDictionary *userInfoCurrent = oneEvent.userInfo;
        NSString *tag=[NSString stringWithFormat:@"%@",[userInfoCurrent valueForKey:@"key"]];
        if ([tag isEqualToString:notificationTag]) {
            //Cancelling local notification
            NSLog(@"removing notification with tag = %@",tag);
            [app cancelLocalNotification:oneEvent];
            break;
        }
    }
}
#End If

Then in your app when you need to register a local notification, you can do something like this:
B4X:
    Dim ln As Notification
    ln.Initialize(DateTime.Now)
    ln.AlertBody = 'Alert body'
    Dim no As NativeObject = Me
    no.RunMethod("setNotificationTag::", Array(ln,MyTagValue)) 'MyTagValue is a string
    ln.Register

Then when you receive a notification:
B4X:
Private Sub Application_ReceiveLocalNotification (LN As Notification)
    Dim no As NativeObject = Me
    no.RunMethod("printLocalNotification:", Array (LN)) 'for debug print the tag 
    Dim tag As Object = no.RunMethod("getNotificationTag:",Array(LN)) 'this returns your tag
    'do something with the tag like looking up the value from a map
    Dim stuffObject as Stuff = StuffMap.Get(tag)
    ' do something with the retrived stuffObject
End Sub

Have fun!
 
Top