Adding iOS8 Location Notification Permission Support to Titanium
Before you start, you must make the below changes to Ti SDK 3.4.0 or greater
This gist discusses the approach used to provide a PR for https://jira.appcelerator.org/browse/TC-4671 PR submitted here tidev/titanium-sdk#6025
In this gist we will provide step by step instructions and reasons for adding features to Titanium to allow developers to check iOS 8 the current UIUserNotificationSettings for the app. These are needed so the developer can determine if the proper UIUserNotificationType has been granted to their app.
To accomplish this, we first add an event listener to Ti.App.iOS called usernotificationsetting. This will fire when the app's [UIApplication sharedApplication] currentUserNotificationSettings is updated.
Second we create a method named getCurrentUserNotificationSettings which returnes a dictionary with an array of UIUserNotificationType which are current granted to the app.
Both of these features are needed in order to properly check if your Titanium application currently has registered the proper rights to be able to create local notifications.
Add the usernotificationsetting listener to Ti.App.iOS
To add the usernotificationsetting to Ti.App.iOS we have to update the UIApplicationDelegate located in TiApp.m.
Open TiApp.m and go to the iOS local notification section and add the below.
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
[[NSNotificationCenter defaultCenter] postNotificationName:kTiUserNotificationSettingsNotification object:notificationSettings userInfo:nil];
}
By adding the didRegisterUserNotificationSettings method, your app will now call this delegate method whenever an UIUserNotificationSettings registeration event happens. This is typically after the user answers the iOS security prompt allowing you to register local notifications or disallowing you app to do so.
The didRegisterUserNotificationSettings method simply creates a notification which will be handled in the TiAppiOSProxy.
Next you need to add the const used by the notification. Open TiBase.h and add the below to the const section.
extern NSString * const kTiUserNotificationSettingsNotification;
Then open TiBase.m and add the following to the const section.
NSString * const kTiUserNotificationSettingsNotification = @"TiUserNotificationSettingsNotification";
Now you have the delegate method ready to start sending notifications.
Next open TiAppiOSProxy and update the _listenerAdded method. At the end of the method add the below code:
if ([TiUtils isIOS8OrGreater]){
if ((count == 1) && [type isEqual:@"usernotificationsetting"]) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector
(didRegisterUserNotificationSettingsNotification:) name:kTiUserNotificationSettingsNotification object:nil];
}
}
This will add our listener and fire the didRegisterUserNotificationSettingsNotification method when the UIUserNotificationSettings registeration event is fired on the app delegate.
Next open update the _listenerRemoved method. At the end of this method, add the below code:
if ([TiUtils isIOS8OrGreater]){
if ((count == 1) && [type isEqual:@"usernotificationsetting"]) {
[[NSNotificationCenter defaultCenter] removeObserver:self name:kTiUserNotificationSettingsNotification object:nil];
}
}
This will allow the developer to remove the Titanium event.
Next scroll to the end of the TiAppiOSProxy file and add the below code. This is the code that is triggered by the UIUserNotificationSettings notification.
-(void)didRegisterUserNotificationSettingsNotification:(NSNotification*)notificationSettings
{
[self fireEvent:@"usernotificationsetting"
withObject:[self formatUserNotificationSettings:(UIUserNotificationSettings*)[notificationSettings object]]];
}
Next we will add our formatter. The formatter is used in a few places to format the UIUserNotificationSettings object into a nicer object for JavaScript. Above your didRegisterUserNotificationSettingsNotification method, add the below code:
-(NSDictionary*)formatUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings
{
NSMutableArray *notifSettings = [[NSMutableArray alloc] init];
if(notificationSettings == nil)
{
return [NSDictionary dictionaryWithObjectsAndKeys: notifSettings,@"types",nil];
}
if((notificationSettings.types & UIUserNotificationTypeNone) != 0){
[notifSettings addObject:NUMINT(UIUserNotificationTypeNone)];
}
if((notificationSettings.types & UIUserNotificationTypeBadge) != 0){
[notifSettings addObject:NUMINT(UIUserNotificationTypeBadge)];
}
if((notificationSettings.types & UIUserNotificationTypeSound) != 0){
[notifSettings addObject:NUMINT(UIUserNotificationTypeSound)];
}
if((notificationSettings.types & UIUserNotificationTypeAlert) != 0){
[notifSettings addObject:NUMINT(UIUserNotificationTypeAlert)];
}
return [NSDictionary dictionaryWithObjectsAndKeys: notifSettings,@"types",nil];
}
Add the getCurrentUserNotificationSettings method to Ti.App.iOS
Next we will create the getCurrentUserNotificationSettings method. This method returns a dictionary with all of the UIUserNotificationSettings which your application has registered and allowed by the user.
At the end of your TiAppiOSProxy.m file add the below code:
-(NSDictionary*)getCurrentUserNotificationSettings:(id)unused
{
if (![TiUtils isIOS8OrGreater]){
return nil;
}
return [self formatUserNotificationSettings:[[UIApplication sharedApplication] currentUserNotificationSettings]];
}
You can now use this to query the [UIApplication sharedApplication] currentUserNotificationSettings for registered and allowed notification types.