From a286d457dbc2e38696bb84191de03ae326250f79 Mon Sep 17 00:00:00 2001 From: Paul Cartier Date: Mon, 20 Apr 2020 16:53:09 +0200 Subject: [PATCH] Display display name instead of address in notif --- Classes/Utils/FastAddressBook.h | 3 + Classes/Utils/FastAddressBook.m | 85 +++++++++++++++++++ .../NotificationService.swift | 40 ++++++++- 3 files changed, 124 insertions(+), 4 deletions(-) diff --git a/Classes/Utils/FastAddressBook.h b/Classes/Utils/FastAddressBook.h index 40683a803..60ecb78e9 100644 --- a/Classes/Utils/FastAddressBook.h +++ b/Classes/Utils/FastAddressBook.h @@ -35,6 +35,9 @@ - (BOOL)saveContact:(Contact *)contact; - (BOOL)saveCNContact:(CNContact *)CNContact contact:(Contact *)Contact; +- (void)dumpContactsDisplayNamesToUserDefaults; +- (void)removeContactFromUserDefaults:(Contact *)contact; + + (BOOL)isAuthorized; // TOOLS diff --git a/Classes/Utils/FastAddressBook.m b/Classes/Utils/FastAddressBook.m index b2674a9ff..cb54275ca 100644 --- a/Classes/Utils/FastAddressBook.m +++ b/Classes/Utils/FastAddressBook.m @@ -152,6 +152,11 @@ if ((self = [super init]) != nil) { store = [[CNContactStore alloc] init]; _addressBookMap = [NSMutableDictionary dictionary]; + + [NSNotificationCenter.defaultCenter addObserver:self + selector:@selector(onPresenceChanged:) + name:kLinphoneNotifyPresenceReceivedForUriOrTel + object:nil]; } self.needToUpdate = FALSE; if (floor(NSFoundationVersionNumber) >= NSFoundationVersionNumber_iOS_9_x_Max) { @@ -217,6 +222,8 @@ linphone_friend_list_update_subscriptions(fl); lists = lists->next; } + [self dumpContactsDisplayNamesToUserDefaults]; + [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneAddressBookUpdate object:self]; @@ -349,6 +356,8 @@ } - (BOOL)deleteContact:(Contact *)contact { + [self removeContactFromUserDefaults:contact]; + CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init]; NSArray *keysToFetch = @[ CNContactEmailAddressesKey, CNContactPhoneNumbersKey, @@ -488,4 +497,80 @@ lists = lists->next; } } + +- (void)dumpContactsDisplayNamesToUserDefaults { + LOGD(@"dumpContactsDisplayNamesToUserDefaults"); + NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:kLinphoneMsgNotificationAppGroupId]; + __block NSDictionary *oldDisplayNames = [defaults dictionaryForKey:@"addressBook"]; + LinphoneProxyConfig *cfg = linphone_core_get_default_proxy_config(LC); + + __block NSMutableDictionary *displayNames = [[NSMutableDictionary dictionary] init]; + [_addressBookMap enumerateKeysAndObjectsUsingBlock:^(NSString *name, Contact *contact, BOOL *stop) { + NSString *key = name; + LinphoneAddress *addr = linphone_address_new(name.UTF8String); + + if (linphone_proxy_config_is_phone_number(cfg, linphone_address_get_username(addr))) { + if (oldDisplayNames[name] != nil && oldDisplayNames[name] != [contact displayName]) { + NSString *addrForTel = [NSString stringWithString:oldDisplayNames[name]]; + /* we keep the link between tel number and sip addr to have the information quickly. + If we don't do that, between the startup and presence callback we don't have the dispay name for this address */ + LOGD(@"add %s -> %s link to userdefaults", name.UTF8String, addrForTel.UTF8String); + [displayNames setObject:addrForTel forKey:name]; + key = addrForTel; + } + } + LOGD(@"add %s to userdefaults", key.UTF8String); + [displayNames setObject:[contact displayName] forKey:key]; + linphone_address_unref(addr); + }]; + + [defaults setObject:displayNames forKey:@"addressBook"]; +} + +- (void)removeContactFromUserDefaults:(Contact *)contact { + LOGD(@"removeContactFromUserDefaults contact: [%p]", contact); + NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:kLinphoneMsgNotificationAppGroupId]; + NSMutableDictionary *displayNames = [[NSMutableDictionary alloc] initWithDictionary:[defaults dictionaryForKey:@"addressBook"]]; + if (displayNames == nil) return; + + NSMutableArray *addresses = contact.sipAddresses; + for (id addr in addresses) { + [displayNames removeObjectForKey:addr]; + LOGD(@"removed %s from userdefaults addressBook", ((NSString *)addr).UTF8String); + } + + [defaults setObject:displayNames forKey:@"addressBook"]; +} + +- (void)onPresenceChanged:(NSNotification *)k { + LinphoneFriend *f = [[k.userInfo valueForKey:@"friend"] pointerValue]; + NSString *uri = [NSString stringWithUTF8String:[[k.userInfo valueForKey:@"uri"] pointerValue]]; + if (![FastAddressBook isSipURI:uri]) { + LOGD(@"presence changed for tel [%s]", uri.UTF8String); + NSString *telAddr = [FastAddressBook normalizeSipURI:uri]; + + NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:kLinphoneMsgNotificationAppGroupId]; + NSMutableDictionary *displayNames = [[NSMutableDictionary alloc] initWithDictionary:[defaults dictionaryForKey:@"addressBook"]]; + if (displayNames == nil) return; + + id displayName = [displayNames objectForKey:telAddr]; + if (displayName == nil) return; + + const LinphonePresenceModel *m = [[k.userInfo valueForKey:@"presence_model"] pointerValue]; + NSString *contact = [NSString stringWithUTF8String:linphone_presence_model_get_contact(m)]; + NSString *sipAddr = [FastAddressBook normalizeSipURI:contact]; + + if (sipAddr != nil && [displayNames objectForKey:sipAddr] == nil) { + [displayNames setObject:displayName forKey:sipAddr]; + [displayNames removeObjectForKey:telAddr]; + [displayNames setObject:sipAddr forKey:telAddr]; + LOGD(@"add %s -> %s link to userdefaults", telAddr.UTF8String, sipAddr.UTF8String); + /* we keep the link between tel number and sip addr to have the information on the next startup. + If we don't do that, between the startup and this callback we don't have the dispay name for this address */ + LOGD(@"Replaced %s by %s in userdefaults addressBook", telAddr.UTF8String, sipAddr.UTF8String); + [defaults setObject:displayNames forKey:@"addressBook"]; + } + } +} + @end diff --git a/msgNotificationService/NotificationService.swift b/msgNotificationService/NotificationService.swift index 6099e67cd..207e24793 100644 --- a/msgNotificationService/NotificationService.swift +++ b/msgNotificationService/NotificationService.swift @@ -144,24 +144,31 @@ class NotificationService: UNNotificationServiceExtension { func parseMessage(message: PushNotificationMessage) -> MsgData? { let content = message.isText ? message.textContent : "🗻" - let from = message.fromAddr?.username + let fromAddr = message.fromAddr?.username let callId = message.callId let localUri = message.localAddr?.asStringUriOnly() let peerUri = message.peerAddr?.asStringUriOnly() + let from: String + if let fromDisplayName = getDisplayNameFromSipAddress(sipAddr: message.fromAddr?.asStringUriOnly()) { + from = fromDisplayName + } else { + from = fromAddr! + } - var msgData = MsgData(from: from, body: "", subtitle: "", callId:callId, localAddr: localUri, peerAddr:peerUri) + + var msgData = MsgData(from: fromAddr, body: "", subtitle: "", callId:callId, localAddr: localUri, peerAddr:peerUri) if let showMsg = lc!.config?.getBool(section: "app", key: "show_msg_in_notif", defaultValue: true), showMsg == true { if let subject = message.subject as String?, subject != "" { msgData.subtitle = subject - msgData.body = from! + " : " + content + msgData.body = from + " : " + content } else { msgData.subtitle = from msgData.body = content } } else { if let subject = message.subject as String?, subject != "" { - msgData.body = subject + " : " + from! + msgData.body = subject + " : " + from } else { msgData.body = from } @@ -198,4 +205,29 @@ class NotificationService: UNNotificationServiceExtension { return count } + + func getDisplayNameFromSipAddress(sipAddr: String?) -> String? { + if let sipAddr = sipAddr { + NotificationService.log.message(msg: "looking for display name for \(sipAddr)") + + if (sipAddr == "") { return nil } + + let defaults = UserDefaults.init(suiteName: APP_GROUP_ID) + let addressBook = defaults?.dictionary(forKey: "addressBook") + + if (addressBook == nil) { + NotificationService.log.message(msg: "address book not found in user defaults") + return nil + } + + if let displayName = addressBook?[sipAddr] as? String { + NotificationService.log.message(msg: "display name for \(sipAddr): \(displayName)") + return displayName + } else { + NotificationService.log.message(msg: "address book not found in user defaults") + return nil + } + } + return nil + } }