From 375b6e3d394a99d79cce4be037ced31d200806a0 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Sat, 20 Sep 2014 15:45:36 +0200 Subject: [PATCH] Use new notification system for iOS8: answer/decline calls and reply/mark read messages from within the notifications --- Classes/LinphoneAppDelegate.m | 104 +++++++++++++++++++++++++++++++++- Classes/LinphoneManager.m | 4 +- 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index c2db65be7..45da851d0 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -118,10 +118,77 @@ } } +- (UIUserNotificationCategory*)newMessageNotificationCategory { + + UIMutableUserNotificationAction* reply = [[UIMutableUserNotificationAction alloc] init]; + reply.identifier = @"reply"; + reply.title = NSLocalizedString(@"Reply", nil); + reply.activationMode = UIUserNotificationActivationModeForeground; + reply.destructive = NO; + reply.authenticationRequired = YES; + + UIMutableUserNotificationAction* mark_read = [[UIMutableUserNotificationAction alloc] init]; + mark_read.identifier = @"mark_read"; + mark_read.title = NSLocalizedString(@"Mark Read", nil); + mark_read.activationMode = UIUserNotificationActivationModeBackground; + mark_read.destructive = NO; + mark_read.authenticationRequired = NO; + + + NSArray* localRingActions = @[mark_read, reply]; + + UIMutableUserNotificationCategory* localRingNotifAction = [[UIMutableUserNotificationCategory alloc] init]; + localRingNotifAction.identifier = @"incoming_msg"; + [localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextDefault]; + [localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextMinimal]; + + return localRingNotifAction; +} + +- (UIUserNotificationCategory*)newCallNotificationCategory { + UIMutableUserNotificationAction* Answer = [[UIMutableUserNotificationAction alloc] init]; + Answer.identifier = @"answer"; + Answer.title = NSLocalizedString(@"Answer", nil); + Answer.activationMode = UIUserNotificationActivationModeForeground; + Answer.destructive = NO; + Answer.authenticationRequired = YES; + + UIMutableUserNotificationAction* Decline = [[UIMutableUserNotificationAction alloc] init]; + Decline.identifier = @"decline"; + Decline.title = NSLocalizedString(@"Decline", nil); + Decline.activationMode = UIUserNotificationActivationModeBackground; + Decline.destructive = YES; + Decline.authenticationRequired = NO; + + + NSArray* localRingActions = @[Decline, Answer]; + + UIMutableUserNotificationCategory* localRingNotifAction = [[UIMutableUserNotificationCategory alloc] init]; + localRingNotifAction.identifier = @"incoming_call"; + [localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextDefault]; + [localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextMinimal]; + + return localRingNotifAction; +} + - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeNewsstandContentAvailability]; + + UIApplication* app= [UIApplication sharedApplication]; + + if( [app respondsToSelector:@selector(registerUserNotificationSettings:)] ){ + /* iOS8 notifications can be actioned! Awesome: */ + UIUserNotificationType notifTypes = UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert; + + NSSet* categories = [NSSet setWithObjects:[self newCallNotificationCategory], [self newMessageNotificationCategory], nil]; + UIUserNotificationSettings* userSettings = [UIUserNotificationSettings settingsForTypes:notifTypes categories:categories]; + [app registerUserNotificationSettings:userSettings]; + [app registerForRemoteNotifications]; + } else { + NSUInteger notifTypes = UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeNewsstandContentAvailability; + [app registerForRemoteNotificationTypes:notifTypes]; + } LinphoneManager* instance = [LinphoneManager instance]; @@ -353,6 +420,41 @@ [[LinphoneManager instance] setPushNotificationToken:nil]; } +#pragma mark - User notifications + +- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { + [LinphoneLogger log:LinphoneLoggerLog format:@"%@", NSStringFromSelector(_cmd)]; +} + +- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler { + [LinphoneLogger log:LinphoneLoggerLog format:@"%@", NSStringFromSelector(_cmd)]; + if( [notification.category isEqualToString:@"incoming_call"]) { + if( [identifier isEqualToString:@"answer"] ){ + // use the standard handler + [self application:application didReceiveLocalNotification:notification]; + } else if( [identifier isEqualToString:@"decline"] ){ + LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); + if( call ) linphone_core_decline_call([LinphoneManager getLc], call, LinphoneReasonDeclined); + } + } else if( [notification.category isEqualToString:@"incoming_msg"] ){ + if( [identifier isEqualToString:@"reply"] ){ + // use the standard handler + [self application:application didReceiveLocalNotification:notification]; + } else if( [identifier isEqualToString:@"mark_read"] ){ + LinphoneChatRoom* room = [[notification.userInfo objectForKey:@"room"] pointerValue]; + if( room ){ + linphone_chat_room_mark_as_read(room); + } + + } + } + completionHandler(); +} + +- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler { + completionHandler(); +} + #pragma mark - Remote configuration Functions (URL Handler) diff --git a/Classes/LinphoneManager.m b/Classes/LinphoneManager.m index 6e759060d..26b20632c 100644 --- a/Classes/LinphoneManager.m +++ b/Classes/LinphoneManager.m @@ -669,6 +669,7 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char data->timer = [NSTimer scheduledTimerWithTimeInterval:4.0 target:self selector:@selector(localNotifContinue:) userInfo:data->notification repeats:TRUE]; data->notification.repeatInterval = 0; + data->notification.category = @"incoming_call"; data->notification.alertBody =[NSString stringWithFormat:NSLocalizedString(@"IC_MSG",nil), address]; data->notification.alertAction = NSLocalizedString(@"Answer", nil); data->notification.soundName = @"shortring.caf"; @@ -893,10 +894,11 @@ static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyCo UILocalNotification* notif = [[[UILocalNotification alloc] init] autorelease]; if (notif) { notif.repeatInterval = 0; + notif.category = @"@incoming_msg"; notif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"IM_MSG",nil), address]; notif.alertAction = NSLocalizedString(@"Show", nil); notif.soundName = @"msg.caf"; - notif.userInfo = @{@"from":from_address }; + notif.userInfo = @{@"from":from_address, @"room":[NSValue valueWithPointer:room] }; [[UIApplication sharedApplication] presentLocalNotificationNow:notif];