forked from mirrors/linphone-iphone
[CNContact] contact loading time optimised
This commit is contained in:
parent
bf0ae9a61e
commit
dfc5af3c7f
7 changed files with 135 additions and 96 deletions
|
|
@ -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<CNPhoneNumber *> *phoneNumber in _person.phoneNumbers) {
|
||||
[_phones addObject:phoneNumber.value.stringValue];
|
||||
}
|
||||
if ([_person respondsToSelector:NSSelectorFromString(
|
||||
CNInstantMessageAddressUsernameKey)] ||
|
||||
[_person respondsToSelector:NSSelectorFromString(
|
||||
CNContactInstantMessageAddressesKey)]) {
|
||||
if (_person.instantMessageAddresses != NULL) {
|
||||
for (CNLabeledValue<CNInstantMessageAddress *> *sipAddr in _person
|
||||
.instantMessageAddresses) {
|
||||
[_sipAddresses addObject:sipAddr.value.username];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (CNLabeledValue<NSString *> *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<CNPhoneNumber *> *phoneNumber in _person.phoneNumbers) {
|
||||
[_phones addObject:phoneNumber.value.stringValue];
|
||||
}
|
||||
if ([_person respondsToSelector:NSSelectorFromString( CNInstantMessageAddressUsernameKey)] || [_person respondsToSelector:NSSelectorFromString(CNContactInstantMessageAddressesKey)]) {
|
||||
if (_person.instantMessageAddresses != NULL) {
|
||||
for (CNLabeledValue<CNInstantMessageAddress *> *sipAddr in _person.instantMessageAddresses) {
|
||||
[_sipAddresses addObject:sipAddr.value.username];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (CNLabeledValue<NSString *> *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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue