diff --git a/CHANGELOG.md b/CHANGELOG.md
index 11e55ecb0..da549f8e3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,21 @@ Group changes to describe their impact on the project, as follows:
Fixed for any bug fixes.
Security to invite users to upgrade in case of vulnerabilities.
+## [3.16.5] - 2017-11-28
+
+### Added
+- Support of IOS 11
+
+### Changed
+- Contact, CNContact implmentation.
+- Contacts loading optimization.
+- Sound management updated
+
+### Fixed
+- Chat file resend fixed
+- Minor bugs fixes
+- Audio fixed on conference call
+
## [3.16.3] - 2017-05-03
### Added
diff --git a/Classes/ContactsListTableView.m b/Classes/ContactsListTableView.m
index 294443400..a9c8b55b4 100644
--- a/Classes/ContactsListTableView.m
+++ b/Classes/ContactsListTableView.m
@@ -134,103 +134,81 @@ static int ms_strcmpfuz(const char *fuzzy_word, const char *sentence) {
addressBookMap = [LinphoneManager.instance getLinphoneManagerAddressBookMap];
BOOL updated = [LinphoneManager.instance getContactsUpdated];
if(([previous isEqualToString:@"ContactsDetailsView"] && updated) || 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)
- {
- for (NSInteger i = 0; i < [self.tableView numberOfRowsInSection:j]; ++i)
+ [LinphoneManager.instance setContactsUpdated:FALSE];
+ @synchronized(addressBookMap) {
+ //Set all contacts from ContactCell to nil
+ for (NSInteger j = 0; j < [self.tableView numberOfSections]; ++j)
{
- [[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:j]] setContact:nil];
+ for (NSInteger i = 0; i < [self.tableView numberOfRowsInSection:j]; ++i)
+ {
+ [[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:j]] setContact:nil];
+ }
}
+
+ // Reset Address book
+ [addressBookMap removeAllObjects];
+ for (NSString *addr in LinphoneManager.instance.fastAddressBook.addressBookMap) {
+ Contact *contact = nil;
+ @synchronized(LinphoneManager.instance.fastAddressBook.addressBookMap) {
+ contact = [LinphoneManager.instance.fastAddressBook.addressBookMap objectForKey:addr];
+ }
+ BOOL add = true;
+ // Do not add the contact directly if we set some filter
+ if ([ContactSelection getSipFilter] ||
+ [ContactSelection emailFilterEnabled]) {
+ add = false;
+ }else if ([FastAddressBook contactHasValidSipDomain:contact]) {
+ add = true;
+ }else if (contact.friend &&
+ linphone_presence_model_get_basic_status(
+ linphone_friend_get_presence_model(
+ contact.friend)) ==
+ LinphonePresenceBasicStatusOpen) {
+ add = true;
+ }
+
+ if (!add && [ContactSelection emailFilterEnabled]) {
+ // Add this contact if it has an email
+ add = (contact.emails.count > 0);
+ }
+
+ NSMutableString *name = [self displayNameForContact:contact] ? [[NSMutableString alloc] initWithString: [self displayNameForContact:contact]] : nil;
+ if (add && name != nil) {
+ NSString *firstChar = [[name substringToIndex:1] uppercaseString];
+ // Put in correct subAr
+ if ([firstChar characterAtIndex:0] < 'A' || [firstChar characterAtIndex:0] > 'Z') {
+ firstChar = @"#";
+ }
+ NSMutableArray *subAr = [addressBookMap objectForKey:firstChar];
+ if (subAr == nil) {
+ subAr = [[NSMutableArray alloc] init];
+ [addressBookMap insertObject:subAr forKey:firstChar selector:@selector(caseInsensitiveCompare:)];
+ }
+ NSUInteger idx = [subAr indexOfObject:contact inSortedRange:(NSRange){0, subAr.count} options:NSBinarySearchingInsertionIndex usingComparator:^NSComparisonResult( Contact *_Nonnull obj1, Contact *_Nonnull obj2) {
+ return [[self displayNameForContact:obj1] compare:[self displayNameForContact:obj2] options:NSCaseInsensitiveSearch];
+ }];
+ if (![subAr containsObject:contact]) {
+ [subAr insertObject:contact atIndex:idx];
+ }
+ }
+ //}
+ }
+ [super loadData];
+
+ // since we refresh the tableview, we must perform this on main
+ // thread
+ dispatch_async(dispatch_get_main_queue(), ^(void) {
+ if (IPAD) {
+ if (!([self totalNumberOfItems] > 0)) {
+ ContactDetailsView *view = VIEW(ContactDetailsView);
+ [view setContact:nil];
+ }
+ }
+ });
}
-
- // Reset Address book
- [addressBookMap removeAllObjects];
- for (NSString *addr in LinphoneManager.instance.fastAddressBook.addressBookMap) {
- @synchronized(
- LinphoneManager.instance.fastAddressBook.addressBookMap) {
- Contact *contact =
- [LinphoneManager.instance.fastAddressBook.addressBookMap
- objectForKey:addr];
- BOOL add = true;
- // Do not add the contact directly if we set some filter
- if ([ContactSelection getSipFilter] ||
- [ContactSelection emailFilterEnabled]) {
- add = false;
- }
- if ([FastAddressBook contactHasValidSipDomain:contact]) {
- add = true;
- }
- if (contact.friend &&
- linphone_presence_model_get_basic_status(
- linphone_friend_get_presence_model(
- contact.friend)) ==
- LinphonePresenceBasicStatusOpen) {
- add = true;
- }
-
- if (!add && [ContactSelection emailFilterEnabled]) {
- // Add this contact if it has an email
- add = (contact.emails.count > 0);
- }
-
- NSMutableString *name =
- [self displayNameForContact:contact]
- ? [[NSMutableString alloc]
- initWithString:
- [self displayNameForContact:contact]]
- : nil;
- if (add && name != nil) {
- NSString *firstChar =
- [[name substringToIndex:1] uppercaseString];
-
- // Put in correct subAr
- if ([firstChar characterAtIndex:0] < 'A' ||
- [firstChar characterAtIndex:0] > 'Z') {
- firstChar = @"#";
- }
- NSMutableArray *subAr =
- [addressBookMap objectForKey:firstChar];
- if (subAr == nil) {
- subAr = [[NSMutableArray alloc] init];
- [addressBookMap
- insertObject:subAr
- forKey:firstChar
- selector:@selector(caseInsensitiveCompare:)];
- }
- NSUInteger idx = [subAr
- indexOfObject:contact
- inSortedRange:(NSRange){0, subAr.count}
- options:NSBinarySearchingInsertionIndex
- usingComparator:^NSComparisonResult(
- Contact *_Nonnull obj1, Contact *_Nonnull obj2) {
- return [[self displayNameForContact:obj1]
- compare:[self displayNameForContact:obj2]
- options:NSCaseInsensitiveSearch];
- }];
- if (![subAr containsObject:contact]) {
- [subAr insertObject:contact atIndex:idx];
- }
- }
- }
- }
- [super loadData];
-
- // since we refresh the tableview, we must perform this on main
- // thread
- dispatch_async(dispatch_get_main_queue(), ^(void) {
- if (IPAD) {
- if (!([self totalNumberOfItems] > 0)) {
- ContactDetailsView *view = VIEW(ContactDetailsView);
- [view setContact:nil];
- }
- }
- });
- }
[LinphoneManager.instance setLinphoneManagerAddressBookMap:addressBookMap];
}
- _ongoing = FALSE;
+ _ongoing = FALSE;
}
- (void)loadSearchedData {
diff --git a/Classes/ContactsListView.m b/Classes/ContactsListView.m
index 3a988b632..ea3c5b52b 100644
--- a/Classes/ContactsListView.m
+++ b/Classes/ContactsListView.m
@@ -158,6 +158,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)changeView:(ContactsCategory)view {
CGRect frame = _selectedButtonImage.frame;
if (view == ContactsAll && !allButton.selected) {
+ [LinphoneManager.instance setContactsUpdated:TRUE];
frame.origin.x = allButton.frame.origin.x;
[ContactSelection setSipFilter:nil];
[ContactSelection enableEmailFilter:FALSE];
diff --git a/linphone-Info.plist b/linphone-Info.plist
index fec3a6130..53b0d6bde 100644
--- a/linphone-Info.plist
+++ b/linphone-Info.plist
@@ -53,7 +53,7 @@
CFBundleVersion
- 8
+ 9
ITSAppUsesNonExemptEncryption
ITSEncryptionExportComplianceCode