diff --git a/Classes/Contact.m b/Classes/Contact.m index 8fde471f9..b377b2d54 100644 --- a/Classes/Contact.m +++ b/Classes/Contact.m @@ -29,74 +29,60 @@ _sipAddresses = [[NSMutableArray alloc] init]; _emails = [[NSMutableArray alloc] init]; if (_person) { - _identifier = _person.identifier; - _firstName = _person.givenName; - _lastName = _person.familyName; - _displayName = [NSString stringWithFormat:@"%@ %@", _firstName, _lastName]; - for (CNLabeledValue *phoneNumber in _person.phoneNumbers) { - [_phones addObject:phoneNumber.value.stringValue]; - } - if ([_person respondsToSelector:NSSelectorFromString( - CNInstantMessageAddressUsernameKey)] || - [_person respondsToSelector:NSSelectorFromString( - CNContactInstantMessageAddressesKey)]) { - if (_person.instantMessageAddresses != NULL) { - for (CNLabeledValue *sipAddr in _person - .instantMessageAddresses) { - [_sipAddresses addObject:sipAddr.value.username]; - } - } - } - for (CNLabeledValue *email in _person.emailAddresses) { - [_emails addObject:email.value]; - } - const char *key = - [NSString stringWithFormat:@"ab%@", acncontact.identifier].UTF8String; - // try to find friend associated with that person - _friend = linphone_friend_list_find_friend_by_ref_key( - linphone_core_get_default_friend_list(LC), key); - if (!_friend) { - _friend = linphone_friend_ref(linphone_core_create_friend(LC)); - linphone_friend_set_ref_key(_friend, key); - linphone_friend_set_name( - _friend, - [NSString - stringWithFormat:@"%@%@", _firstName ? _firstName : @"", - _lastName - ? [_firstName ? @" " : @"" - stringByAppendingString:_lastName] - : @""] - .UTF8String); - for (NSString *sipAddr in _sipAddresses) { - LinphoneAddress *addr = - linphone_core_interpret_url(LC, sipAddr.UTF8String); - if (addr) { - linphone_address_set_display_name(addr, - [self displayName].UTF8String); - linphone_friend_add_address(_friend, addr); - linphone_address_destroy(addr); - } - } - for (NSString *phone in _phones) { - linphone_friend_add_phone_number(_friend, phone.UTF8String); - } - if (_friend) { - linphone_friend_enable_subscribes(_friend, FALSE); - linphone_friend_set_inc_subscribe_policy(_friend, LinphoneSPDeny); - linphone_core_add_friend(LC, _friend); - } - } - linphone_friend_ref(_friend); + _identifier = _person.identifier; + _firstName = _person.givenName; + _lastName = _person.familyName; + _displayName = [NSString stringWithFormat:@"%@ %@", _firstName, _lastName]; + for (CNLabeledValue *phoneNumber in _person.phoneNumbers) { + [_phones addObject:phoneNumber.value.stringValue]; + } + if ([_person respondsToSelector:NSSelectorFromString( CNInstantMessageAddressUsernameKey)] || [_person respondsToSelector:NSSelectorFromString(CNContactInstantMessageAddressesKey)]) { + if (_person.instantMessageAddresses != NULL) { + for (CNLabeledValue *sipAddr in _person.instantMessageAddresses) { + [_sipAddresses addObject:sipAddr.value.username]; + } + } + } + for (CNLabeledValue *email in _person.emailAddresses) { + [_emails addObject:email.value]; + } + const char *key = [NSString stringWithFormat:@"ab%@", acncontact.identifier].UTF8String; + // try to find friend associated with that person + _friend = linphone_friend_list_find_friend_by_ref_key(linphone_core_get_default_friend_list(LC), key); + if (!_friend) { + _friend = linphone_friend_ref(linphone_core_create_friend(LC)); + linphone_friend_set_ref_key(_friend, key); + linphone_friend_set_name(_friend, [NSString stringWithFormat:@"%@%@", _firstName ? _firstName : @"", _lastName ? [_firstName ? @" " : @"" stringByAppendingString:_lastName] : @""] .UTF8String); + for (NSString *sipAddr in _sipAddresses) { + LinphoneAddress *addr = linphone_core_interpret_url(LC, sipAddr.UTF8String); + if (addr) { + linphone_address_set_display_name(addr, [self displayName].UTF8String); + linphone_friend_add_address(_friend, addr); + linphone_address_destroy(addr); + } + } + for (NSString *phone in _phones) { + linphone_friend_add_phone_number(_friend, phone.UTF8String); + } + if (_friend) { + linphone_friend_enable_subscribes(_friend, FALSE); + linphone_friend_set_inc_subscribe_policy(_friend, LinphoneSPDeny); + linphone_core_add_friend(LC, _friend); + } + } + linphone_friend_ref(_friend); + } else if (_friend) { - [self loadFriend]; + [self loadFriend]; } else { - LOGE(@"Contact cannot be initialized"); - return nil; + LOGE(@"Contact cannot be initialized"); + return nil; } - LOGI(@"Contact %@ %@ initialized with %d phones, %d sip, %d emails", + /* LOGI(@"Contact %@ %@ initialized with %d phones, %d sip, %d emails", self.firstName ?: @"", self.lastName ?: @"", self.phones.count, self.sipAddresses.count, self.emails.count); + */ return self; } diff --git a/Classes/ContactsListTableView.m b/Classes/ContactsListTableView.m index 29a713e50..3eb1d684e 100644 --- a/Classes/ContactsListTableView.m +++ b/Classes/ContactsListTableView.m @@ -110,7 +110,7 @@ static int ms_strcmpfuz(const char *fuzzy_word, const char *sentence) { } - (NSString *)displayNameForContact:(Contact *)person { - NSString *name = [FastAddressBook displayNameForContact:person]; + NSString *name = person.displayName; if (name != nil && [name length] > 0 && ![name isEqualToString:NSLocalizedString(@"Unknown", nil)]) { // Add the contact only if it fuzzy match filter too (if any) if ([ContactSelection getNameOrEmailFilter] == nil || @@ -119,18 +119,22 @@ static int ms_strcmpfuz(const char *fuzzy_word, const char *sentence) { // Sort contacts by first letter. We need to translate the name to ASCII first, because of UTF-8 // issues. For instance expected order would be: Alberta(A tilde) before ASylvano. - NSData *name2ASCIIdata = [name dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; + /* NSData *name2ASCIIdata = [name dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; NSString *name2ASCII = [[NSString alloc] initWithData:name2ASCIIdata encoding:NSASCIIStringEncoding]; - return name2ASCII; + */ return name; } } return nil; } -// TODO - check this - (void)loadData { _ongoing = TRUE; LOGI(@"Load contact list"); + NSString* previous = [PhoneMainView.instance getPreviousViewName]; + addressBookMap = [LinphoneManager.instance getLinphoneManagerAddressBookMap]; + BOOL updated = [LinphoneManager.instance getContactsUpdated]; + if(([previous isEqualToString:@"ContactsDetailsView"] && updated)|| [addressBookMap count] == 0){ + [LinphoneManager.instance setContactsUpdated:FALSE]; @synchronized(addressBookMap) { //Set all contacts from ContactCell to nil for (NSInteger j = 0; j < [self.tableView numberOfSections]; ++j) @@ -224,6 +228,8 @@ static int ms_strcmpfuz(const char *fuzzy_word, const char *sentence) { } }); } + [LinphoneManager.instance setLinphoneManagerAddressBookMap:addressBookMap]; + } _ongoing = FALSE; } @@ -433,7 +439,10 @@ static int ms_strcmpfuz(const char *fuzzy_word, const char *sentence) { selector:@selector(onAddressBookUpdate:) name:kLinphoneAddressBookUpdate object:nil]; - [self loadData]; + dispatch_async(dispatch_get_main_queue(), + ^{ + [self loadData]; + }); } } diff --git a/Classes/LinphoneManager.h b/Classes/LinphoneManager.h index adba17596..1ee25a20c 100644 --- a/Classes/LinphoneManager.h +++ b/Classes/LinphoneManager.h @@ -33,7 +33,7 @@ #include "linphone/linphonecore.h" #include "bctoolbox/list.h" - +#import "OrderedDictionary.h" #import "ProviderDelegate.h" extern NSString *const LINPHONERC_APPLICATION_KEY; @@ -197,6 +197,13 @@ typedef struct _LinphoneManagerSounds { - (void)shouldPresentLinkPopup; - (void)setProviderDelegate:(ProviderDelegate *)del; + +- (void) setLinphoneManagerAddressBookMap:(OrderedDictionary*) addressBook; +- (OrderedDictionary*) getLinphoneManagerAddressBookMap; + +- (void) setContactsUpdated:(BOOL) updated; +- (BOOL) getContactsUpdated; + @property ProviderDelegate *providerDelegate; @property (readonly) BOOL isTesting; @@ -225,5 +232,7 @@ typedef struct _LinphoneManagerSounds { @property BOOL nextCallIsTransfer; @property BOOL conf; @property NSDictionary *pushDict; +@property(strong, nonatomic) OrderedDictionary *linphoneManagerAddressBookMap; +@property (nonatomic, assign) BOOL contactsUpdated; @end diff --git a/Classes/LinphoneManager.m b/Classes/LinphoneManager.m index 5aa090def..a1fb3e75e 100644 --- a/Classes/LinphoneManager.m +++ b/Classes/LinphoneManager.m @@ -257,7 +257,7 @@ struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_pre _bluetoothEnabled = FALSE; _conf = FALSE; _fileTransferDelegates = [[NSMutableArray alloc] init]; - + _linphoneManagerAddressBookMap = [[OrderedDictionary alloc] init]; pushCallIDs = [[NSMutableArray alloc] init]; _photoLibrary = [[ALAssetsLibrary alloc] init]; _isTesting = [LinphoneManager isRunningTests]; @@ -292,6 +292,23 @@ struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_pre [NSNotificationCenter.defaultCenter removeObserver:self]; } +#pragma mark - AddressBookMap + +- (void) setLinphoneManagerAddressBookMap:(OrderedDictionary*) addressBook{ + _linphoneManagerAddressBookMap = addressBook; +} + +- (OrderedDictionary*) getLinphoneManagerAddressBookMap{ + return _linphoneManagerAddressBookMap; +} + +- (void) setContactsUpdated:(BOOL) updated{ + _contactsUpdated = updated; +} +- (BOOL) getContactsUpdated{ + return _contactsUpdated; +} + #pragma deploymate push "ignored-api-availability" - (void)silentPushFailed:(NSTimer *)timer { if (_silentPushCompletion) { diff --git a/Classes/PhoneMainView.h b/Classes/PhoneMainView.h index 0ccf21b9b..3ac43c52a 100644 --- a/Classes/PhoneMainView.h +++ b/Classes/PhoneMainView.h @@ -79,6 +79,7 @@ @property(nonatomic, strong) IBOutlet UICompositeView *mainViewController; @property(nonatomic, strong) NSString *currentName; +@property(nonatomic, strong) NSString *previousView; @property(nonatomic, strong) NSString *name; @property(weak, readonly) UICompositeViewDescription *currentView; @property LinphoneChatRoom* currentRoom; @@ -87,6 +88,9 @@ - (void)changeCurrentView:(UICompositeViewDescription *)view; - (UIViewController*)popCurrentView; - (UIViewController *)popToView:(UICompositeViewDescription *)currentView; +- (void) setPreviousViewName:(NSString*)previous; +- (NSString*) getPreviousViewName; ++ (NSString*) getPreviousViewName; - (UICompositeViewDescription *)firstView; - (void)hideStatusBar:(BOOL)hide; - (void)hideTabBar:(BOOL)hide; diff --git a/Classes/PhoneMainView.m b/Classes/PhoneMainView.m index 8f2f694f2..7a54ed38a 100644 --- a/Classes/PhoneMainView.m +++ b/Classes/PhoneMainView.m @@ -128,6 +128,7 @@ static RootViewManager *rootViewManagerInstance = nil; currentView = nil; _currentRoom = NULL; _currentName = NULL; + _previousView = nil; inhibitedEvents = [[NSMutableArray alloc] init]; } @@ -657,6 +658,7 @@ static RootViewManager *rootViewManagerInstance = nil; PhoneMainView *vc = [[RootViewManager instance] setViewControllerForDescription:view]; if (![view equal:vc.currentView] || vc != self) { LOGI(@"Change current view to %@", view.name); + [self setPreviousViewName:vc.currentView.name]; NSMutableArray *viewStack = [RootViewManager instance].viewDescriptionStack; [viewStack addObject:view]; if (animated && transition == nil) @@ -683,6 +685,19 @@ static RootViewManager *rootViewManagerInstance = nil; return [self _changeCurrentView:view transition:[PhoneMainView getBackwardTransition] animated:ANIMATED]; } +- (void) setPreviousViewName:(NSString*)previous{ + _previousView = previous; +} + +- (NSString*) getPreviousViewName { + return _previousView; +} + ++ (NSString*) getPreviousViewName { + return [self getPreviousViewName]; +} + + - (UICompositeViewDescription *)firstView { UICompositeViewDescription *view = nil; NSArray *viewStack = [RootViewManager instance].viewDescriptionStack; diff --git a/Classes/Utils/FastAddressBook.m b/Classes/Utils/FastAddressBook.m index e17c4b69d..291663573 100644 --- a/Classes/Utils/FastAddressBook.m +++ b/Classes/Utils/FastAddressBook.m @@ -91,8 +91,7 @@ + (NSString *)normalizeSipURI:(NSString *)address { // replace all whitespaces (non-breakable, utf8 nbsp etc.) by the "classical" whitespace - NSString *normalizedSipAddress = [[address - componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] componentsJoinedByString:@" "]; + NSString *normalizedSipAddress = nil; LinphoneAddress *addr = linphone_core_interpret_url(LC, [address UTF8String]); if (addr != NULL) { linphone_address_clean(addr); @@ -100,8 +99,11 @@ normalizedSipAddress = [NSString stringWithUTF8String:tmp]; ms_free(tmp); linphone_address_destroy(addr); + return normalizedSipAddress; + }else { + normalizedSipAddress = [[address componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] componentsJoinedByString:@" "]; + return normalizedSipAddress; } - return normalizedSipAddress; } + (BOOL)isAuthorized { @@ -112,8 +114,10 @@ if ((self = [super init]) != nil) { store = [[CNContactStore alloc] init]; _addressBookMap = [NSMutableDictionary dictionary]; - [self reloadAllContacts]; - } + dispatch_async(dispatch_get_main_queue(), ^{ + [self reloadAllContacts]; + }); + } self.needToUpdate = FALSE; if (floor(NSFoundationVersionNumber) >= NSFoundationVersionNumber_iOS_9_x_Max) { @@ -167,13 +171,14 @@ error:&contactError]; NSArray *keysToFetch = @[ CNContactEmailAddressesKey, CNContactPhoneNumbersKey, - CNContactFamilyNameKey, CNContactGivenNameKey, + CNContactFamilyNameKey, CNContactGivenNameKey, CNContactNicknameKey, CNContactPostalAddressesKey, CNContactIdentifierKey, CNInstantMessageAddressUsernameKey, CNContactInstantMessageAddressesKey, CNInstantMessageAddressUsernameKey, CNContactImageDataKey ]; CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keysToFetch]; + success = [store enumerateContactsWithFetchRequest:request error:&contactError @@ -183,10 +188,10 @@ NSLog(@"error fetching contacts %@", contactError); } else { - Contact *newContact = [[Contact alloc] + Contact *newContact = [[Contact alloc] initWithCNContact:contact]; [self registerAddrsFor:newContact]; - } + } }]; // load Linphone friends const MSList *lists = linphone_core_get_friends_lists(LC); @@ -214,25 +219,18 @@ } - (void)registerAddrsFor:(Contact *)contact { - for (NSString *phone in contact.phones) { - char *normalizedPhone = linphone_proxy_config_normalize_phone_number( - linphone_core_get_default_proxy_config(LC), phone.UTF8String); - NSString *name = [FastAddressBook - normalizeSipURI:normalizedPhone - ? [NSString stringWithUTF8String:normalizedPhone] - : phone]; - if (phone != NULL) { - [_addressBookMap - setObject:contact - forKey:(name ?: [FastAddressBook localizedLabel:phone])]; - } - if (normalizedPhone) - ms_free(normalizedPhone); - } - for (NSString *sip in contact.sipAddresses) { - [_addressBookMap setObject:contact - forKey:([FastAddressBook normalizeSipURI:sip] ?: sip)]; - } + for (NSString *phone in contact.phones) { + char *normalizedPhone = linphone_proxy_config_normalize_phone_number(linphone_core_get_default_proxy_config(LC), phone.UTF8String); + NSString *name = [FastAddressBook normalizeSipURI:normalizedPhone ? [NSString stringWithUTF8String:normalizedPhone] : phone]; + if (phone != NULL) { + [_addressBookMap setObject:contact forKey:(name ?: [FastAddressBook localizedLabel:phone])]; + } + if (normalizedPhone) + ms_free(normalizedPhone); + } + for (NSString *sip in contact.sipAddresses) { + [_addressBookMap setObject:contact forKey:([FastAddressBook normalizeSipURI:sip] ?: sip)]; + } } #pragma mark - Tools @@ -407,6 +405,7 @@ NSLog(@"Success %d", [store executeSaveRequest:saveRequest error:&saveError]); [self updateFriend:contact]; + [LinphoneManager.instance setContactsUpdated:TRUE]; } @catch (NSException *exception) { NSLog(@"=====>>>>> CNContact SaveRequest failed : description = %@", [exception description]);