Merge branch 'master' into dev_group_chat

This commit is contained in:
Benjamin Reis 2017-12-15 10:53:13 +01:00
commit 054df9ac24
39 changed files with 1375 additions and 1278 deletions

View file

@ -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

View file

@ -199,7 +199,7 @@ void assistant_activate_phone_number_link(LinphoneAccountCreator *creator, Linph
}
[PhoneMainView.instance popToView:DialerView.compositeViewDescription];
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneAddressBookUpdate object:NULL];
[LinphoneManager.instance.fastAddressBook reload];
[LinphoneManager.instance.fastAddressBook fetchContactsInBackGroundThread];
} else {
[thiz showErrorPopup:resp];
}

View file

@ -412,10 +412,10 @@ static UICompositeViewDescription *compositeDescription = nil;
linphone_core_set_default_proxy_config(LC, new_config);
// reload address book to prepend proxy config domain to contacts' phone number
// todo: STOP doing that!
[[LinphoneManager.instance fastAddressBook] reload];
} else {
[self displayAssistantConfigurationError];
}
[[LinphoneManager.instance fastAddressBook] fetchContactsInBackGroundThread];
} else {
[self displayAssistantConfigurationError];
}
}
- (void)displayAssistantConfigurationError {
@ -1324,8 +1324,10 @@ void assistant_is_account_linked(LinphoneAccountCreator *creator, LinphoneAccoun
NSString *pwd = [self findTextField:ViewElement_Password].text;
LinphoneProxyConfig *config = linphone_core_create_proxy_config(LC);
LinphoneAddress *addr = linphone_address_new(NULL);
LinphoneAddress *tmpAddr = linphone_address_new([NSString stringWithFormat:@"sip:%@",domain].UTF8String);
linphone_address_set_username(addr, username.UTF8String);
linphone_address_set_domain(addr, domain.UTF8String);
linphone_address_set_port(addr, linphone_address_get_port(tmpAddr));
linphone_address_set_domain(addr, linphone_address_get_domain(tmpAddr));
if (displayName && ![displayName isEqualToString:@""]) {
linphone_address_set_display_name(addr, displayName.UTF8String);
}
@ -1359,6 +1361,7 @@ void assistant_is_account_linked(LinphoneAccountCreator *creator, LinphoneAccoun
);
linphone_core_add_auth_info(LC, info);
linphone_address_unref(addr);
linphone_address_unref(tmpAddr);
if (config) {
[[LinphoneManager instance] configurePushTokenForProxyConfig:config];
@ -1366,13 +1369,13 @@ void assistant_is_account_linked(LinphoneAccountCreator *creator, LinphoneAccoun
linphone_core_set_default_proxy_config(LC, config);
// reload address book to prepend proxy config domain to contacts' phone number
// todo: STOP doing that!
[[LinphoneManager.instance fastAddressBook] reload];
[PhoneMainView.instance changeCurrentView:DialerView.compositeViewDescription];
[[LinphoneManager.instance fastAddressBook] fetchContactsInBackGroundThread];
[PhoneMainView.instance changeCurrentView:DialerView.compositeViewDescription];
} else {
[self displayAssistantConfigurationError];
[self displayAssistantConfigurationError];
}
} else {
[self displayAssistantConfigurationError];
[self displayAssistantConfigurationError];
}
});
}

View file

@ -150,7 +150,9 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)bluetoothAvailabilityUpdateEvent:(NSNotification *)notif {
bool available = [[notif.userInfo objectForKey:@"available"] intValue];
[self hideSpeaker:available];
dispatch_async(dispatch_get_main_queue(), ^{
[self hideSpeaker:available];
});
}
@end

View file

@ -6,28 +6,31 @@
//
//
#import <Foundation/Foundation.h>
#import <AddressBook/AddressBook.h>
#import <Contacts/Contacts.h>
#import <Foundation/Foundation.h>
#include <linphone/linphonecore.h>
@interface Contact : NSObject
@property(nonatomic, readonly) ABRecordRef person;
//@property(nonatomic, readonly) ABRecordRef person;
@property(nonatomic, readonly) CNContact *person;
@property(nonatomic, readonly) LinphoneFriend *friend;
@property(nonatomic, retain) NSString *identifier;
@property(nonatomic, retain) NSString *firstName;
@property(nonatomic, retain) NSString *lastName;
@property(nonatomic, retain) NSString *displayName;
@property(nonatomic, strong) NSMutableArray *sipAddresses;
@property(nonatomic, strong) NSMutableArray *emails;
@property(nonatomic, strong) NSMutableArray *phoneNumbers;
@property(nonatomic, strong) NSMutableArray *phones;
@property BOOL added;
- (void)setAvatar:(UIImage *)avatar;
- (UIImage *)avatar;
- (NSString *)displayName;
- (instancetype)initWithPerson:(ABRecordRef)person;
- (instancetype)initWithCNContact:(CNContact *)contact;
- (instancetype)initWithFriend:(LinphoneFriend *) friend;
- (BOOL)setSipAddress:(NSString *)sip atIndex:(NSInteger)index;

File diff suppressed because it is too large Load diff

View file

@ -29,15 +29,17 @@
- (NSMutableArray *)getSectionData:(NSInteger)section {
if (section == ContactSections_Number) {
return _contact.phoneNumbers;
} else if (section == ContactSections_Sip) {
return _contact.sipAddresses;
} else if (section == ContactSections_Email) {
if ([LinphoneManager.instance lpConfigBoolForKey:@"show_contacts_emails_preference"] == true) {
return _contact.emails;
}
}
return nil;
return _contact.phones;
} else if (section == ContactSections_Sip) {
return _contact.sipAddresses;
} else if (section == ContactSections_Email) {
if ([LinphoneManager.instance
lpConfigBoolForKey:@"show_contacts_emails_preference"] ==
true) {
return _contact.emails;
}
}
return nil;
}
- (void)removeEmptyEntry:(UITableView *)tableview section:(NSInteger)section animated:(BOOL)animated {
@ -73,27 +75,36 @@
- (void)addEntry:(UITableView *)tableview section:(NSInteger)section animated:(BOOL)animated value:(NSString *)value {
bool added = FALSE;
if (section == ContactSections_Number) {
if ([_contact.phones count] ==
[_contact.person.phoneNumbers count])
added = [_contact addPhoneNumber:value];
} else if (section == ContactSections_Sip) {
added = [_contact addSipAddress:value];
} else if (section == ContactSections_Email) {
added = [_contact addEmail:value];
}
if (added) {
NSUInteger count = [self getSectionData:section].count;
[tableview insertRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:count - 1 inSection:section] ]
withRowAnimation:animated ? UITableViewRowAnimationFade : UITableViewRowAnimationNone];
} else {
LOGW(@"Cannot add entry '%@' in section %d, skipping", value, section);
}
if ([_contact.sipAddresses count] ==
[_contact.person.instantMessageAddresses count])
added = [_contact addSipAddress:value];
} else if (section == ContactSections_Email) {
if ([_contact.emails count] ==
[_contact.person.emailAddresses count])
added = [_contact addEmail:value];
}
if (added) {
NSUInteger count = [self getSectionData:section].count;
[tableview
insertRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:count - 1
inSection:section] ]
withRowAnimation:animated ? UITableViewRowAnimationFade
: UITableViewRowAnimationNone];
} else {
LOGW(@"Cannot add entry '%@' in section %d, skipping", value,
section);
}
}
- (void)setContact:(Contact *)acontact {
if (acontact == _contact)
return;
_contact = acontact;
[self loadData];
// if (acontact == _contact)
// return;
_contact = acontact;
[self loadData];
}
- (void)addPhoneField:(NSString *)number {
@ -119,8 +130,9 @@
- (BOOL)isValid {
BOOL hasName = (_contact.firstName.length + _contact.lastName.length > 0);
BOOL hasAddr = (_contact.phoneNumbers.count + _contact.sipAddresses.count) > 0;
return hasName && hasAddr;
BOOL hasAddr =
(_contact.phones.count + _contact.sipAddresses.count) > 0;
return hasName && hasAddr;
}
#pragma mark - UITableViewDataSource Functions
@ -140,12 +152,13 @@
} else if (section == ContactSections_Sip) {
return _contact.sipAddresses.count;
} else if (section == ContactSections_Number) {
return _contact.phoneNumbers.count;
} else if (section == ContactSections_Email) {
BOOL showEmails = [LinphoneManager.instance lpConfigBoolForKey:@"show_contacts_emails_preference"];
return showEmails ? _contact.emails.count : 0;
}
return 0;
return _contact.phones.count;
} else if (section == ContactSections_Email) {
BOOL showEmails = [LinphoneManager.instance
lpConfigBoolForKey:@"show_contacts_emails_preference"];
return showEmails ? _contact.emails.count : 0;
}
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
@ -170,26 +183,29 @@
value = _contact.lastName;
[cell hideDeleteButton:YES];
} else if ([indexPath section] == ContactSections_Number) {
value = _contact.phoneNumbers[indexPath.row];
[cell.editTextfield setKeyboardType:UIKeyboardTypePhonePad];
} else if ([indexPath section] == ContactSections_Sip) {
value = _contact.sipAddresses[indexPath.row];
LinphoneAddress *addr = NULL;
if ([LinphoneManager.instance lpConfigBoolForKey:@"contact_display_username_only"] &&
(addr = linphone_core_interpret_url(LC, [value UTF8String]))) {
value = [NSString stringWithCString:linphone_address_get_username(addr)
encoding:[NSString defaultCStringEncoding]];
linphone_address_destroy(addr);
}
[cell.editTextfield setKeyboardType:UIKeyboardTypeASCIICapable];
} else if ([indexPath section] == ContactSections_Email) {
value = _contact.emails[indexPath.row];
[cell.editTextfield setKeyboardType:UIKeyboardTypeEmailAddress];
}
value = _contact.phones[indexPath.row];
[cell.editTextfield setKeyboardType:UIKeyboardTypePhonePad];
} else if ([indexPath section] == ContactSections_Sip) {
value = _contact.sipAddresses[indexPath.row];
LinphoneAddress *addr = NULL;
if ([LinphoneManager.instance
lpConfigBoolForKey:@"contact_display_username_only"] &&
(addr = linphone_core_interpret_url(LC, [value UTF8String]))) {
value =
[NSString stringWithCString:linphone_address_get_username(addr)
encoding:[NSString defaultCStringEncoding]];
linphone_address_destroy(addr);
}
[cell.editTextfield setKeyboardType:UIKeyboardTypeASCIICapable];
} else if ([indexPath section] == ContactSections_Email) {
value = _contact.emails[indexPath.row];
[cell.editTextfield setKeyboardType:UIKeyboardTypeEmailAddress];
}
if ([value hasPrefix:@" "])
value = [value substringFromIndex:1];
[cell setAddress:value];
[cell setAddress:value];
return cell;
return cell;
}
- (void)tableView:(UITableView *)tableView
@ -198,13 +214,16 @@
[LinphoneUtils findAndResignFirstResponder:[self tableView]];
if (editingStyle == UITableViewCellEditingStyleInsert) {
[tableView beginUpdates];
[self addEntry:tableView section:[indexPath section] animated:TRUE value:@""];
[tableView endUpdates];
} else if (editingStyle == UITableViewCellEditingStyleDelete) {
[tableView beginUpdates];
[self removeEntry:tableView indexPath:indexPath animated:TRUE];
[tableView endUpdates];
}
[self addEntry:tableView
section:[indexPath section]
animated:TRUE
value:@" "];
[tableView endUpdates];
} else if (editingStyle == UITableViewCellEditingStyleDelete) {
[tableView beginUpdates];
[self removeEntry:tableView indexPath:indexPath animated:TRUE];
[tableView endUpdates];
}
}
#pragma mark - UITableViewDelegate Functions
@ -372,19 +391,22 @@
break;
case ContactSections_Number:
[_contact setPhoneNumber:value atIndex:path.row];
value = _contact.phoneNumbers[path.row]; // in case of reformatting
break;
case ContactSections_MAX:
case ContactSections_None:
break;
}
cell.editTextfield.text = value;
_editButton.enabled = [self isValid];
}
value =
_contact.phones[path.row]; // in case of
// reformatting
break;
case ContactSections_MAX:
case ContactSections_None:
break;
}
cell.editTextfield.text = value;
_editButton.enabled = [self isValid];
}
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
[self textFieldUpdated:textField];
// TODO reload current contact
}
- (BOOL)textField:(UITextField *)textField

View file

@ -29,12 +29,18 @@
self = [super initWithNibName:NSStringFromClass(self.class) bundle:[NSBundle mainBundle]];
if (self != nil) {
inhibUpdate = FALSE;
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(onAddressBookUpdate:)
name:kLinphoneAddressBookUpdate
object:nil];
}
return self;
[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(onAddressBookUpdate:)
name:kLinphoneAddressBookUpdate
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(onAddressBookUpdate:)
name:CNContactStoreDidChangeNotification
object:nil];
}
return self;
}
- (void)dealloc {
@ -44,11 +50,12 @@
#pragma mark -
- (void)onAddressBookUpdate:(NSNotification *)k {
if (!inhibUpdate && ![_tableController isEditing] &&
(PhoneMainView.instance.currentView == self.compositeViewDescription) &&
(_nameLabel.text == PhoneMainView.instance.currentName)) {
[self resetData];
}
if (!inhibUpdate && ![_tableController isEditing] &&
(PhoneMainView.instance.currentView == self.compositeViewDescription) &&
(_nameLabel.text == PhoneMainView.instance.currentName)) {
[self resetData];
}
}
- (void)resetData {
@ -67,9 +74,9 @@
- (void)removeContact {
inhibUpdate = TRUE;
[[LinphoneManager.instance fastAddressBook] removeContact:_contact];
inhibUpdate = FALSE;
[PhoneMainView.instance popCurrentView];
[[LinphoneManager.instance fastAddressBook] deleteContact:_contact];
inhibUpdate = FALSE;
[PhoneMainView.instance popCurrentView];
}
- (void)saveData {
@ -77,9 +84,9 @@
[PhoneMainView.instance popCurrentView];
return;
}
// Add contact to book
[LinphoneManager.instance.fastAddressBook saveContact:_contact];
PhoneMainView.instance.currentName = _contact.displayName;
_nameLabel.text = PhoneMainView.instance.currentName;
[LinphoneManager.instance.fastAddressBook saveContact:_contact];
}
- (void)selectContact:(Contact *)acontact andReload:(BOOL)reload {
@ -109,12 +116,11 @@
if (!acontact) {
return;
}
_tmpContact = [[Contact alloc] initWithPerson:ABPersonCreate()];
_tmpContact.firstName = acontact.firstName.copy;
_tmpContact.lastName = acontact.lastName.copy;
_tmpContact.sipAddresses = acontact.sipAddresses.copy;
_tmpContact.emails = acontact.emails.copy;
_tmpContact.phoneNumbers = acontact.phoneNumbers.copy;
@synchronized(LinphoneManager.instance.fastAddressBook) {
_tmpContact = [[Contact alloc]
initWithCNContact:[LinphoneManager.instance.fastAddressBook
getCNContactFromContact:acontact]];
}
}
- (void)addCurrentContactContactField:(NSString *)address {
@ -140,14 +146,19 @@
- (void)newContact {
_isAdding = TRUE;
[self selectContact:[[Contact alloc] initWithPerson:ABPersonCreate()] andReload:YES];
CNContact *contact = [[CNContact alloc] init];
[self selectContact:[[Contact alloc] initWithCNContact:contact]
andReload:YES];
}
- (void)newContact:(NSString *)address {
[self selectContact:[[Contact alloc] initWithPerson:ABPersonCreate()] andReload:NO];
[self addCurrentContactContactField:address];
// force to restart server subscription to add new contact into the list
[LinphoneManager.instance becomeActive];
CNContact *contact = [[CNContact alloc] init];
Contact *mContact = [[Contact alloc] initWithCNContact:contact];
[mContact setSipAddress:address atIndex:0];
[self selectContact:mContact andReload:NO];
[self addCurrentContactContactField:address];
// force to restart server subscription to add new contact into the list
[LinphoneManager.instance becomeActive];
}
- (void)editContact:(Contact *)acontact {
@ -258,47 +269,45 @@
[_contact addSipAddress:_tmpContact.sipAddresses[nbSipAd]];
nbSipAd++;
}
while (_contact.phoneNumbers.count > 0) {
[_contact removePhoneNumberAtIndex:0];
}
NSInteger nbPhone = 0;
while (_tmpContact.phoneNumbers.count> nbPhone) {
[_contact addPhoneNumber:_tmpContact.phoneNumbers[nbPhone]];
nbPhone++;
}
while (_contact.emails.count > 0) {
[_contact removeEmailAtIndex:0];
}
NSInteger nbEmail = 0;
while (_tmpContact.emails.count> nbEmail) {
[_contact addEmail:_tmpContact.emails[nbEmail]];
nbEmail++;
}
self.tmpContact = NULL;
[self saveData];
}
BOOL rm = TRUE;
for (NSString *sip in _contact.sipAddresses) {
if (![sip isEqualToString:@""]) {
rm = FALSE;
break;
}
}
if (rm) {
for (NSString *phone in _contact.phoneNumbers) {
if (![phone isEqualToString:@""]) {
rm = FALSE;
break;
}
}
}
if (rm) {
[LinphoneManager.instance.fastAddressBook removeContact:_contact];
}
while (_contact.phones.count > 0) {
[_contact removePhoneNumberAtIndex:0];
}
NSInteger nbPhone = 0;
while (_tmpContact.phones.count > nbPhone) {
[_contact addPhoneNumber:_tmpContact.phones[nbPhone]];
nbPhone++;
}
while (_contact.emails.count > 0) {
[_contact removeEmailAtIndex:0];
}
NSInteger nbEmail = 0;
while (_tmpContact.emails.count > nbEmail) {
[_contact addEmail:_tmpContact.emails[nbEmail]];
nbEmail++;
}
self.tmpContact = NULL;
[self saveData];
}
BOOL rm = TRUE;
for (NSString *sip in _contact.sipAddresses) {
if (![sip isEqualToString:@""]) {
rm = FALSE;
break;
}
}
if (rm) {
for (NSString *phone in _contact.phones) {
if (![phone isEqualToString:@""]) {
rm = FALSE;
break;
}
}
}
if (rm) {
[LinphoneManager.instance.fastAddressBook deleteContact:_contact];
}
}
#pragma mark - UICompositeViewDelegate Functions
@ -399,55 +408,60 @@ static UICompositeViewDescription *compositeDescription = nil;
[_contact removeSipAddressAtIndex:0];
}
NSInteger nbSipAd = 0;
while (_tmpContact.sipAddresses.count > nbSipAd) {
[_contact addSipAddress:_tmpContact.sipAddresses[nbSipAd]];
nbSipAd++;
}
while (_contact.phoneNumbers.count > 0) {
[_contact removePhoneNumberAtIndex:0];
}
NSInteger nbPhone = 0;
while (_tmpContact.phoneNumbers.count> nbPhone) {
[_contact addPhoneNumber:_tmpContact.phoneNumbers[nbPhone]];
nbPhone++;
}
while (_contact.emails.count > 0) {
[_contact removeEmailAtIndex:0];
}
NSInteger nbEmail = 0;
while (_tmpContact.emails.count> nbEmail) {
[_contact addEmail:_tmpContact.emails[nbEmail]];
nbEmail++;
}
[self saveData];
[self.tableController.tableView reloadData];
} else {
[LinphoneManager.instance.fastAddressBook removeContact:_contact];
}
[self setEditing:FALSE];
if (IPAD) {
_emptyLabel.hidden = !_isAdding;
_avatarImage.hidden = !_emptyLabel.hidden;
_deleteButton.hidden = !_emptyLabel.hidden;
_editButton.hidden = !_emptyLabel.hidden;
} else {
if (_isAdding) {
[PhoneMainView.instance popCurrentView];
} else {
_avatarImage.hidden = FALSE;
_deleteButton.hidden = FALSE;
_editButton.hidden = FALSE;
}
}
self.tmpContact = NULL;
if (_isAdding) {
[PhoneMainView.instance popToView:ContactsListView.compositeViewDescription];
_isAdding = FALSE;
}
if (_tmpContact.sipAddresses) {
while (_tmpContact.sipAddresses.count > nbSipAd) {
[_contact addSipAddress:_tmpContact.sipAddresses[nbSipAd]];
nbSipAd++;
}
}
while (_contact.phones.count > 0 &&
_contact.phones[0] != NULL) {
[_contact removePhoneNumberAtIndex:0];
}
NSInteger nbPhone = 0;
if (_tmpContact.phones != NULL) {
while (_tmpContact.phones.count > nbPhone) {
[_contact addPhoneNumber:_tmpContact.phones[nbPhone]];
nbPhone++;
}
}
while (_contact.emails.count > 0) {
[_contact removeEmailAtIndex:0];
}
NSInteger nbEmail = 0;
if (_tmpContact.emails != NULL) {
while (_tmpContact.emails.count > nbEmail) {
[_contact addEmail:_tmpContact.emails[nbEmail]];
nbEmail++;
}
}
// [self saveData];
} else {
[LinphoneManager.instance.fastAddressBook deleteContact:_contact];
}
[self setEditing:FALSE];
if (IPAD) {
_emptyLabel.hidden = !_isAdding;
_avatarImage.hidden = !_emptyLabel.hidden;
_deleteButton.hidden = !_emptyLabel.hidden;
_editButton.hidden = !_emptyLabel.hidden;
} else {
if (_isAdding) {
[PhoneMainView.instance popCurrentView];
} else {
_avatarImage.hidden = FALSE;
_deleteButton.hidden = FALSE;
_editButton.hidden = FALSE;
}
}
self.tmpContact = NULL;
if (_isAdding) {
[PhoneMainView.instance
popToView:ContactsListView.compositeViewDescription];
_isAdding = FALSE;
}
}
- (IBAction)onBackClick:(id)event {

View file

@ -29,10 +29,16 @@
- (void)initContactsTableViewController {
addressBookMap = [[OrderedDictionary alloc] init];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(onAddressBookUpdate:)
name:kLinphoneAddressBookUpdate
object:nil];
[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(onAddressBookUpdate:)
name:kLinphoneAddressBookUpdate
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(onAddressBookUpdate:)
name:CNContactStoreDidChangeNotification
object:nil];
}
- (void)onAddressBookUpdate:(NSNotification *)k {
@ -104,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 ||
@ -124,77 +130,83 @@ static int ms_strcmpfuz(const char *fuzzy_word, const char *sentence) {
- (void)loadData {
_ongoing = TRUE;
LOGI(@"Load contact list");
@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)
NSString* previous = [PhoneMainView.instance getPreviousViewName];
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)
{
[[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 = [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;
for (NSInteger i = 0; i < [self.tableView numberOfRowsInSection:j]; ++i)
{
[[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:j]] setContact:nil];
}
}
if (!add && [ContactSelection emailFilterEnabled]) {
// Add this contact if it has an email
add = (contact.emails.count > 0);
}
// 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;
}
NSMutableString *name = [self displayNameForContact:contact]
? [[NSMutableString alloc] initWithString:[self displayNameForContact:contact]]
: nil;
if (add && name != nil) {
NSString *firstChar = [[name substringToIndex:1] uppercaseString];
if (!add && [ContactSelection emailFilterEnabled]) {
// Add this contact if it has an email
add = (contact.emails.count > 0);
}
// 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];
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];
}
}
});
}
[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;
}
@ -218,66 +230,94 @@ static int ms_strcmpfuz(const char *fuzzy_word, const char *sentence) {
NSMutableArray *subArContain = [NSMutableArray new];
[addressBookMap insertObject:subAr forKey:@"" selector:@selector(caseInsensitiveCompare:)];
for (NSString *addr in 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;
}
NSString* filter = [ContactSelection getNameOrEmailFilter];
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);
}
NSInteger idx_begin = -1;
NSInteger idx_sort = - 1;
NSMutableString *name = [self displayNameForContact:contact]
? [[NSMutableString alloc] initWithString:[self displayNameForContact:contact]]
: nil;
if (add && name != nil) {
if ([[contact displayName] rangeOfString:filter options:NSCaseInsensitiveSearch].location == 0) {
if(![subArBegin containsObject:contact]) {
idx_begin = idx_begin + 1;
[subArBegin insertObject:contact atIndex:idx_begin];
}
} else if([[contact displayName] rangeOfString:filter options:NSCaseInsensitiveSearch].location != NSNotFound) {
if(![subArContain containsObject:contact]) {
idx_sort = idx_sort + 1;
[subArContain insertObject:contact atIndex:idx_sort];
}
}
}
}
[subArBegin sortUsingComparator:^NSComparisonResult(Contact* _Nonnull obj1, Contact* _Nonnull obj2) {
return [[self displayNameForContact:obj1] compare:[self displayNameForContact:obj2]options:NSCaseInsensitiveSearch];
}];
[subArContain sortUsingComparator:^NSComparisonResult(Contact* _Nonnull obj1, Contact* _Nonnull obj2) {
return [[self displayNameForContact:obj1] compare:[self displayNameForContact:obj2]options:NSCaseInsensitiveSearch];
}];
@synchronized(
LinphoneManager.instance.fastAddressBook.addressBookMap) {
Contact *contact =
[LinphoneManager.instance.fastAddressBook.addressBookMap
objectForKey:addr];
[subAr addObjectsFromArray:subArBegin];
[subAr addObjectsFromArray:subArContain];
[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];
}
}
});
}
BOOL add = true;
// Do not add the contact directly if we set some filter
if ([ContactSelection getSipFilter] ||
[ContactSelection emailFilterEnabled]) {
add = false;
}
NSString *filter = [ContactSelection getNameOrEmailFilter];
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);
}
NSInteger idx_begin = -1;
NSInteger idx_sort = -1;
NSMutableString *name =
[self displayNameForContact:contact]
? [[NSMutableString alloc]
initWithString:
[self displayNameForContact:contact]]
: nil;
if (add && name != nil) {
if ([[contact displayName]
rangeOfString:filter
options:NSCaseInsensitiveSearch]
.location == 0) {
if (![subArBegin containsObject:contact]) {
idx_begin = idx_begin + 1;
[subArBegin insertObject:contact atIndex:idx_begin];
}
} else if ([[contact displayName]
rangeOfString:filter
options:NSCaseInsensitiveSearch]
.location != NSNotFound) {
if (![subArContain containsObject:contact]) {
idx_sort = idx_sort + 1;
[subArContain insertObject:contact atIndex:idx_sort];
}
}
}
}
}
[subArBegin
sortUsingComparator:^NSComparisonResult(
Contact *_Nonnull obj1, Contact *_Nonnull obj2) {
return [[self displayNameForContact:obj1]
compare:[self displayNameForContact:obj2]
options:NSCaseInsensitiveSearch];
}];
[subArContain
sortUsingComparator:^NSComparisonResult(
Contact *_Nonnull obj1, Contact *_Nonnull obj2) {
return [[self displayNameForContact:obj1]
compare:[self displayNameForContact:obj2]
options:NSCaseInsensitiveSearch];
}];
[subAr addObjectsFromArray:subArBegin];
[subAr addObjectsFromArray:subArContain];
[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];
}
}
});
}
}
@ -365,17 +405,23 @@ static int ms_strcmpfuz(const char *fuzzy_word, const char *sentence) {
}
UIContactCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];
[cell setContact:NULL];
[[LinphoneManager.instance fastAddressBook] removeContact:contact];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
[[LinphoneManager.instance fastAddressBook]
deleteContact:contact];
[tableView
deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(onAddressBookUpdate:)
name:kLinphoneAddressBookUpdate
object:nil];
[self loadData];
}
[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(onAddressBookUpdate:)
name:kLinphoneAddressBookUpdate
object:nil];
dispatch_async(dispatch_get_main_queue(),
^{
[self loadData];
});
}
}
- (void)removeSelectionUsing:(void (^)(NSIndexPath *))remover {
@ -391,12 +437,13 @@ static int ms_strcmpfuz(const char *fuzzy_word, const char *sentence) {
}
UIContactCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];
[cell setContact:NULL];
[[LinphoneManager.instance fastAddressBook] removeContact:contact];
[[LinphoneManager.instance fastAddressBook] deleteContact:contact];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(onAddressBookUpdate:)
name:kLinphoneAddressBookUpdate
object:nil];
[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(onAddressBookUpdate:)
name:kLinphoneAddressBookUpdate
object:nil];
}];
}

View file

@ -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];
@ -165,6 +166,7 @@ static UICompositeViewDescription *compositeDescription = nil;
linphoneButton.selected = FALSE;
[tableController loadData];
} else if (view == ContactsLinphone && !linphoneButton.selected) {
[LinphoneManager.instance setContactsUpdated:TRUE];
frame.origin.x = linphoneButton.frame.origin.x;
[ContactSelection setSipFilter:LinphoneManager.instance.contactFilter];
[ContactSelection enableEmailFilter:FALSE];

View file

@ -91,47 +91,56 @@
if (PhoneMainView.instance.currentView == ContactsListView.compositeViewDescription || PhoneMainView.instance.currentView == ContactDetailsView.compositeViewDescription) {
[PhoneMainView.instance changeCurrentView:DialerView.compositeViewDescription];
}
[instance.fastAddressBook reload];
instance.fastAddressBook.needToUpdate = FALSE;
const MSList *lists = linphone_core_get_friends_lists(LC);
while (lists) {
linphone_friend_list_update_subscriptions(lists->data);
lists = lists->next;
}
}
[instance.fastAddressBook fetchContactsInBackGroundThread];
instance.fastAddressBook.needToUpdate = FALSE;
const MSList *lists = linphone_core_get_friends_lists(LC);
while (lists) {
linphone_friend_list_update_subscriptions(lists->data);
lists = lists->next;
}
}
LinphoneCall *call = linphone_core_get_current_call(LC);
LinphoneCall *call = linphone_core_get_current_call(LC);
if (call) {
if (call == instance->currentCallContextBeforeGoingBackground.call) {
const LinphoneCallParams *params = linphone_call_get_current_params(call);
if (linphone_call_params_video_enabled(params)) {
linphone_call_enable_camera(call, instance->currentCallContextBeforeGoingBackground.cameraIsEnabled);
}
instance->currentCallContextBeforeGoingBackground.call = 0;
} else if (linphone_call_get_state(call) == LinphoneCallIncomingReceived) {
LinphoneCallAppData *data = (__bridge LinphoneCallAppData *)linphone_call_get_user_data(call);
if (data && data->timer) {
[data->timer invalidate];
data->timer = nil;
}
if ((floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max)) {
if ([LinphoneManager.instance lpConfigBoolForKey:@"autoanswer_notif_preference"]) {
linphone_call_accept(call);
[PhoneMainView.instance changeCurrentView:CallView.compositeViewDescription];
} else {
[PhoneMainView.instance displayIncomingCall:call];
}
} else if (linphone_core_get_calls_nb(LC) > 1) {
[PhoneMainView.instance displayIncomingCall:call];
}
if (call) {
if (call == instance->currentCallContextBeforeGoingBackground.call) {
const LinphoneCallParams *params =
linphone_call_get_current_params(call);
if (linphone_call_params_video_enabled(params)) {
linphone_call_enable_camera(
call, instance->currentCallContextBeforeGoingBackground
.cameraIsEnabled);
}
instance->currentCallContextBeforeGoingBackground.call = 0;
} else if (linphone_call_get_state(call) ==
LinphoneCallIncomingReceived) {
LinphoneCallAppData *data =
(__bridge LinphoneCallAppData *)linphone_call_get_user_data(
call);
if (data && data->timer) {
[data->timer invalidate];
data->timer = nil;
}
if ((floor(NSFoundationVersionNumber) <=
NSFoundationVersionNumber_iOS_9_x_Max)) {
if ([LinphoneManager.instance
lpConfigBoolForKey:@"autoanswer_notif_preference"]) {
linphone_call_accept(call);
[PhoneMainView.instance
changeCurrentView:CallView.compositeViewDescription];
} else {
[PhoneMainView.instance displayIncomingCall:call];
}
} else if (linphone_core_get_calls_nb(LC) > 1) {
[PhoneMainView.instance displayIncomingCall:call];
}
// in this case, the ringing sound comes from the notification.
// To stop it we have to do the iOS7 ring fix...
[self fixRing];
}
}
[LinphoneManager.instance.iapManager check];
// in this case, the ringing sound comes from the notification.
// To stop it we have to do the iOS7 ring fix...
[self fixRing];
}
}
[LinphoneManager.instance.iapManager check];
}
#pragma deploymate push "ignored-api-availability"
@ -978,7 +987,7 @@ didInvalidatePushTokenForType:(NSString *)type {
linphone_core_set_provisioning_uri(LC, [configURL UTF8String]);
[LinphoneManager.instance destroyLinphoneCore];
[LinphoneManager.instance startLinphoneCore];
[LinphoneManager.instance.fastAddressBook reload];
[LinphoneManager.instance.fastAddressBook fetchContactsInBackGroundThread];
}
#pragma mark - Prevent ImagePickerView from rotating

View file

@ -636,7 +636,7 @@
}
}
// reload address book to prepend proxy config domain to contacts' phone number
[[LinphoneManager.instance fastAddressBook] reload];
[[LinphoneManager.instance fastAddressBook] fetchContactsInBackGroundThread];
}
- (void)synchronizeCodecs:(const MSList *)codecs {
@ -722,34 +722,27 @@
NSString *videoPreset = [self stringForKey:@"video_preset_preference"];
linphone_core_set_video_preset(LC, [videoPreset UTF8String]);
int bw;
MSVideoSize vsize;
switch ([self integerForKey:@"video_preferred_size_preference"]) {
case 0:
MS_VIDEO_SIZE_ASSIGN(vsize, 720P);
// 128 = margin for audio, the BW includes both video and audio
bw = 1024 + 128;
break;
case 1:
MS_VIDEO_SIZE_ASSIGN(vsize, VGA);
// no margin for VGA or QVGA, because video encoders can encode the
// target resulution in less than the asked bandwidth
bw = 660;
break;
case 2:
default:
MS_VIDEO_SIZE_ASSIGN(vsize, QVGA);
bw = 380;
break;
}
linphone_core_set_preferred_video_size(LC, vsize);
if (![videoPreset isEqualToString:@"custom"]) {
[self setInteger:0 forKey:@"video_preferred_fps_preference"];
[self setInteger:bw forKey:@"download_bandwidth_preference"];
[self setInteger:0 forKey:@"download_bandwidth_preference"];
}
linphone_core_set_preferred_framerate(LC, [self integerForKey:@"video_preferred_fps_preference"]);
linphone_core_set_download_bandwidth(LC, [self integerForKey:@"download_bandwidth_preference"]);
linphone_core_set_upload_bandwidth(LC, [self integerForKey:@"download_bandwidth_preference"]);
linphone_core_set_download_bandwidth(LC, [self integerForKey:@"download_bandwidth_preference"]);
linphone_core_set_upload_bandwidth(LC, [self integerForKey:@"download_bandwidth_preference"]);
}
// call section

View file

@ -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

View file

@ -83,6 +83,7 @@ extern void libmsx264_init(MSFactory *factory);
extern void libmsopenh264_init(MSFactory *factory);
extern void libmssilk_init(MSFactory *factory);
extern void libmswebrtc_init(MSFactory *factory);
extern void libmscodec2_init(MSFactory *factory);
#define FRONT_CAM_NAME \
"AV Capture: com.apple.avfoundation.avcapturedevice.built-in_video:1" /*"AV Capture: Front Camera"*/
@ -141,6 +142,7 @@ struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_pre
{"mpeg4-generic", 48000, "aaceld_48k_preference"},
{"opus", 48000, "opus_preference"},
{"BV16", 8000, "bv16_preference"},
{"CODEC2", 8000, "codec2_preference"},
{NULL, 0, Nil}};
+ (NSString *)getPreferenceForCodec:(const char *)name withRate:(int)rate {
@ -257,7 +259,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 +294,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) {
@ -580,7 +599,7 @@ static void linphone_iphone_display_status(struct _LinphoneCore *lc, const char
video = ([UIApplication sharedApplication].applicationState == UIApplicationStateActive &&
linphone_core_get_video_policy(LC)->automatically_accept &&
linphone_call_params_video_enabled(linphone_call_get_remote_params(call)));
[LinphoneManager.instance.providerDelegate reportIncomingCallwithUUID:uuid handle:address video:video];
[LinphoneManager.instance.providerDelegate reportIncomingCall:call withUUID:uuid handle:address video:video];
#else
[PhoneMainView.instance displayIncomingCall:call];
#endif
@ -697,8 +716,6 @@ static void linphone_iphone_display_status(struct _LinphoneCore *lc, const char
// furthermore it introduces a bug when calling multiple times since route may not be
// reconfigured between cause leading to bluetooth being disabled while it should not
_bluetoothEnabled = FALSE;
/*IOS specific*/
linphone_core_start_dtmf_stream(theLinphoneCore);
}
if (incallBgTask) {
@ -1983,6 +2000,8 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
libmsx264_init(f);
libmsopenh264_init(f);
libmswebrtc_init(f);
libmscodec2_init(f);
linphone_core_reload_ms_plugins(theLinphoneCore, NULL);
[self migrationAllPost];
@ -2052,10 +2071,10 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
[self destroyLinphoneCore];
[self createLinphoneCore];
// reload friends
[self.fastAddressBook reload];
[self.fastAddressBook fetchContactsInBackGroundThread];
// reset network state to trigger a new network connectivity assessment
linphone_core_set_network_reachable(theLinphoneCore, FALSE);
// reset network state to trigger a new network connectivity assessment
linphone_core_set_network_reachable(theLinphoneCore, FALSE);
}
static int comp_call_id(const LinphoneCall *call, const char *callid) {

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="15G1217" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13527"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -26,7 +26,6 @@
<outlet property="imdmLabel" destination="44j-me-Iqi" id="m5R-Dm-V8g"/>
<outlet property="messageImageView" destination="yMW-cT-bpU" id="MNr-F2-abQ"/>
<outlet property="resendRecognizer" destination="5ZI-Ip-lGl" id="G2r-On-6mV"/>
<outlet property="statusErrorImage" destination="ASM-vr-ei3" id="MK9-hl-6UF"/>
<outlet property="statusInProgressSpinner" destination="Eab-ND-ix3" id="UuC-eY-MSf"/>
<outlet property="totalView" destination="8I3-n2-0kS" id="aa8-j9-saW"/>
</connections>
@ -113,11 +112,6 @@
<rect key="frame" x="0.0" y="150" width="322" height="1"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="chat_message_not_delivered.png" id="ASM-vr-ei3" userLabel="statusErrorImage">
<rect key="frame" x="302" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Delivery failed"/>
</imageView>
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="gray" id="Eab-ND-ix3" userLabel="statusInprogressSpinner">
<rect key="frame" x="302" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
@ -163,7 +157,6 @@
</objects>
<resources>
<image name="avatar.png" width="259" height="259"/>
<image name="chat_message_not_delivered.png" width="11" height="10"/>
<image name="chat_unsecure.png" width="18" height="27"/>
<image name="color_A.png" width="2" height="2"/>
<image name="color_G.png" width="2" height="2"/>
@ -172,9 +165,4 @@
<image name="linphone_logo.png" width="26" height="22"/>
<image name="valid_default.png" width="28" height="19"/>
</resources>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4_7.fullscreen"/>
</simulatedMetricsContainer>
</document>

View file

@ -20,17 +20,10 @@
<outlet property="imdmIcon" destination="WlS-fU-Aut" id="bYC-jb-Amo"/>
<outlet property="imdmLabel" destination="yKD-pC-Nhu" id="ge9-Yl-qsr"/>
<outlet property="messageText" destination="CYa-If-oB4" id="7xm-UF-1qB"/>
<outlet property="resendRecognizer" destination="OA2-9R-81Z" id="zVJ-IY-3yO"/>
<outlet property="statusErrorImage" destination="nLy-JO-TyL" id="ZkB-dR-cx2"/>
<outlet property="statusInProgressSpinner" destination="4Z8-PE-uPe" id="T9k-9x-DeB"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tapGestureRecognizer id="OA2-9R-81Z" userLabel="resendClick">
<connections>
<action selector="onResendClick:" destination="-1" id="l6k-1D-O4U"/>
</connections>
</tapGestureRecognizer>
<view contentMode="scaleToFill" misplaced="YES" id="ucH-2r-rar">
<rect key="frame" x="0.0" y="0.0" width="334" height="74"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
@ -59,11 +52,6 @@
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="chat_message_not_delivered.png" id="nLy-JO-TyL" userLabel="statusErrorImage">
<rect key="frame" x="302" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Delivery failed"/>
</imageView>
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="gray" id="4Z8-PE-uPe" userLabel="statusInprogressSpinner">
<rect key="frame" x="302" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
@ -94,12 +82,11 @@
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="chat_read.png" id="WlS-fU-Aut" userLabel="imdmIcon">
<rect key="frame" x="306" y="41" width="13" height="13"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Delivery failed"/>
<accessibility key="accessibilityConfiguration" label="Delivery failed">
<accessibilityTraits key="traits" button="YES" image="YES"/>
</accessibility>
</imageView>
</subviews>
<connections>
<outletCollection property="gestureRecognizers" destination="OA2-9R-81Z" appends="YES" id="Phx-YZ-cwz"/>
</connections>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -110,7 +97,6 @@
</objects>
<resources>
<image name="avatar.png" width="259" height="259"/>
<image name="chat_message_not_delivered.png" width="11" height="10"/>
<image name="chat_read.png" width="24" height="24"/>
<image name="chat_unsecure.png" width="18" height="27"/>
<image name="color_A.png" width="2" height="2"/>

View file

@ -179,7 +179,7 @@
} else if (_cancelButton.hidden == NO) {
[self onCancelClick:event];
} else {
[super onResendClick:event];
[super onResend];
}
}

View file

@ -30,7 +30,6 @@
@property(nonatomic, weak) IBOutlet UIImageView *backgroundColorImage;
@property(nonatomic, weak) IBOutlet UIRoundedImageView *avatarImage;
@property(nonatomic, weak) IBOutlet UILabel *contactDateLabel;
@property(nonatomic, weak) IBOutlet UIImageView *statusErrorImage;
@property(weak, nonatomic) IBOutlet UIActivityIndicatorView *statusInProgressSpinner;
@property(nonatomic, weak) IBOutlet UITextViewNoDefine *messageText;
@property(weak, nonatomic) IBOutlet UIImageView *bottomBarColor;
@ -46,8 +45,9 @@
- (void)setEvent:(LinphoneEventLog *)event;
- (void)setChatMessage:(LinphoneChatMessage *)message;
- (IBAction)onDeleteClick:(id)event;
- (IBAction)onResendClick:(id)event;
- (void)onDelete;
- (void)onResend;
- (void)onLime;
- (void)update;
- (void)displayImdmStatus:(LinphoneChatMessageState)state;

View file

@ -40,6 +40,23 @@
[self addSubview:sub];
}
}
UITapGestureRecognizer *limeRecognizer =
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onLime)];
limeRecognizer.numberOfTapsRequired = 1;
[_LIMEKO addGestureRecognizer:limeRecognizer];
_LIMEKO.userInteractionEnabled = YES;
UITapGestureRecognizer *resendRecognizer =
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onResend)];
resendRecognizer.numberOfTapsRequired = 1;
[_imdmIcon addGestureRecognizer:resendRecognizer];
_imdmIcon.userInteractionEnabled = YES;
UITapGestureRecognizer *resendRecognizer2 =
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onResend)];
resendRecognizer2.numberOfTapsRequired = 1;
[_imdmLabel addGestureRecognizer:resendRecognizer2];
_imdmLabel.userInteractionEnabled = YES;
return self;
}
@ -150,13 +167,10 @@
_contactDateLabel.textColor = [UIColor colorWithPatternImage:_backgroundColorImage.image];
if (outgoing && state == LinphoneChatMessageStateInProgress) {
_statusErrorImage.hidden = YES;
[_statusInProgressSpinner startAnimating];
} else if (!outgoing && state == LinphoneChatMessageStateFileTransferError) {
_statusErrorImage.hidden = NO;
[_statusInProgressSpinner stopAnimating];
} else {
_statusErrorImage.hidden = YES;
[_statusInProgressSpinner stopAnimating];
}
@ -210,7 +224,7 @@
#pragma mark - Action Functions
- (IBAction)onDeleteClick:(id)event {
- (void)onDelete {
if (_message != NULL) {
UITableView *tableView = VIEW(ChatConversationView).tableController.tableView;
NSIndexPath *indexPath = [tableView indexPathForCell:self];
@ -220,45 +234,42 @@
}
}
- (IBAction)onResendClick:(id)event {
if (!_LIMEKO.hidden) {
- (void)onLime {
if (!_LIMEKO.hidden)
[self displayLIMEWarning];
return;
}
}
- (void)onResend {
if (_message == nil || !linphone_chat_message_is_outgoing(_message))
return;
LinphoneChatMessageState state = linphone_chat_message_get_state(_message);
if (state == LinphoneChatMessageStateNotDelivered || state == LinphoneChatMessageStateFileTransferError) {
if (linphone_chat_message_get_file_transfer_information(_message) != NULL) {
NSString *localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:_message];
NSNumber *uploadQuality =[LinphoneManager getMessageAppDataForKey:@"uploadQuality" inMessage:_message];
NSURL *imageUrl = [NSURL URLWithString:localImage];
if (state != LinphoneChatMessageStateNotDelivered && state != LinphoneChatMessageStateFileTransferError)
return;
[self onDeleteClick:nil];
[LinphoneManager.instance.photoLibrary assetForURL:imageUrl
resultBlock:^(ALAsset *asset) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL),
^(void) {
UIImage *image = [[UIImage alloc] initWithCGImage:[[asset defaultRepresentation] fullResolutionImage]];
[_chatRoomDelegate startImageUpload:image url:imageUrl withQuality:(uploadQuality ? [uploadQuality floatValue] : 0.9)];
});
}
failureBlock:^(NSError *error) {
LOGE(@"Can't read image");
}];
} else {
[self onDeleteClick:nil];
double delayInSeconds = 0.4;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
[_chatRoomDelegate resendChat:self.textMessage withExternalUrl:nil];
});
}
if (linphone_chat_message_get_file_transfer_information(_message) != NULL) {
NSString *localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:_message];
NSNumber *uploadQuality =[LinphoneManager getMessageAppDataForKey:@"uploadQuality" inMessage:_message];
NSURL *imageUrl = [NSURL URLWithString:localImage];
[self onDelete];
[LinphoneManager.instance.photoLibrary assetForURL:imageUrl
resultBlock:^(ALAsset *asset) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL),
^(void) {
UIImage *image = [[UIImage alloc] initWithCGImage:[[asset defaultRepresentation] fullResolutionImage]];
[_chatRoomDelegate startImageUpload:image url:imageUrl withQuality:(uploadQuality ? [uploadQuality floatValue] : 0.9)];
});
}
failureBlock:^(NSError *error) {
LOGE(@"Can't read image");
}];
} else {
[self onDelete];
double delayInSeconds = 0.4;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
[_chatRoomDelegate resendChat:self.textMessage withExternalUrl:nil];
});
}
}
#pragma mark - State changed handling

View file

@ -42,7 +42,8 @@ INIT_WITH_COMMON_CF {
#pragma mark - UIToggleButtonDelegate Functions
- (void)audioRouteChangeListenerCallback:(NSNotification *)notif {
[self update];
dispatch_async(dispatch_get_main_queue(), ^{
[self update];});
}
- (void)onOn {

View file

@ -82,6 +82,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;
@ -91,6 +92,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;

View file

@ -128,6 +128,7 @@ static RootViewManager *rootViewManagerInstance = nil;
currentView = nil;
_currentRoom = NULL;
_currentName = NULL;
_previousView = nil;
inhibitedEvents = [[NSMutableArray alloc] init];
}
@ -656,6 +657,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)
@ -682,6 +684,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;

View file

@ -23,7 +23,7 @@
@property BOOL pendingCallVideo;
@property int callKitCalls;
- (void)reportIncomingCallwithUUID:(NSUUID *)uuid handle:(NSString *)handle video:(BOOL)video;
- (void)reportIncomingCall:(LinphoneCall *) call withUUID:(NSUUID *)uuid handle:(NSString *)handle video:(BOOL)video;
- (void)config;
- (void)configAudioSession:(AVAudioSession *)audioSession;
@end

View file

@ -71,7 +71,7 @@
}
}
- (void)reportIncomingCallwithUUID:(NSUUID *)uuid handle:(NSString *)handle video:(BOOL)video {
- (void)reportIncomingCall:(LinphoneCall *) call withUUID:(NSUUID *)uuid handle:(NSString *)handle video:(BOOL)video; {
// Create update to describe the incoming call and caller
CXCallUpdate *update = [[CXCallUpdate alloc] init];
update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:handle];
@ -80,13 +80,24 @@
update.supportsGrouping = TRUE;
update.supportsUngrouping = TRUE;
update.hasVideo = video;
linphone_call_ref(call);
// Report incoming call to system
LOGD(@"CallKit: report new incoming call");
[self.provider reportNewIncomingCallWithUUID:uuid
update:update
completion:^(NSError *error) {
}];
if (error) {
LOGE(@"CallKit: cannot complete incoming call from [%@] caused by [%@]",handle,[error localizedDescription]);
if ( [error code] == CXErrorCodeIncomingCallErrorFilteredByDoNotDisturb
|| [error code] == CXErrorCodeIncomingCallErrorFilteredByBlockList) {
linphone_call_decline(call,LinphoneReasonBusy); /*to give a chance for other devices to answer*/
} else {
linphone_call_decline(call,LinphoneReasonUnknown);
}
}
linphone_call_unref(call);
}];
}
- (void)setPendingCall:(LinphoneCall *)pendingCall {
@ -198,11 +209,12 @@
LinphoneManager.instance.speakerBeforePause = LinphoneManager.instance.speakerEnabled;
linphone_call_pause((LinphoneCall *)call);
} else {
[self configAudioSession:[AVAudioSession sharedInstance]];
if (linphone_core_get_conference(LC)) {
linphone_core_enter_conference(LC);
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCallUpdate object:self];
} else {
[self configAudioSession:[AVAudioSession sharedInstance]];
self.pendingCall = call;
}
}

View file

@ -6,6 +6,8 @@
//
//
#import "linphone/core_utils.h"
#import "SideMenuTableView.h"
#import "Utils.h"
@ -37,7 +39,7 @@
}
- (void)viewWillAppear:(BOOL)animated {
linphone_core_stop_dtmf(LC);
linphone_core_stop_dtmf_stream(LC);
[super viewWillAppear:animated];
_sideMenuEntries = [[NSMutableArray alloc] init];

View file

@ -28,16 +28,19 @@
@property(readonly, nonatomic) NSMutableDictionary *addressBookMap;
@property BOOL needToUpdate;
- (void)reload;
- (void)saveAddressBook;
- (int)removeContact:(Contact *)contact;
- (void) fetchContactsInBackGroundThread;
- (BOOL)deleteContact:(Contact *)contact;
- (BOOL)deleteCNContact:(CNContact *)CNContact;
- (BOOL)deleteAllContacts;
- (BOOL)saveContact:(Contact *)contact;
- (BOOL)saveCNContact:(CNContact *)CNContact contact:(Contact *)Contact;
+ (BOOL)isAuthorized;
// TOOLS
+ (Contact *)getContactWithAddress:(const LinphoneAddress *)address;
- (CNContact *)getCNContactFromContact:(Contact *)acontact;
+ (UIImage *)imageForContact:(Contact *)contact;
+ (UIImage *)imageForAddress:(const LinphoneAddress *)addr;
@ -52,5 +55,6 @@
+ (NSString *)normalizeSipURI:(NSString *)address; // should be removed
+ (NSString *)localizedLabel:(NSString *)label;
- (void)registerAddrsFor:(Contact *)contact;
@end

View file

@ -25,12 +25,9 @@
#import "Utils.h"
@implementation FastAddressBook {
ABAddressBookRef addressBook;
CNContactStore* store;
}
static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info, void *context);
+ (UIImage *)imageForContact:(Contact *)contact {
@synchronized(LinphoneManager.instance.fastAddressBook.addressBookMap) {
UIImage *retImage = [contact avatar];
@ -57,7 +54,7 @@ static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info
return [LinphoneManager.instance.fastAddressBook.addressBookMap objectForKey:address];
}
}
return nil;
return nil;
}
+ (Contact *)getContactWithAddress:(const LinphoneAddress *)address {
@ -94,8 +91,7 @@ static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info
+ (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);
@ -103,72 +99,92 @@ static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info
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 {
return ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized;
return [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
}
- (FastAddressBook *)init {
if ((self = [super init]) != nil) {
store = [[CNContactStore alloc] init];
_addressBookMap = [NSMutableDictionary dictionary];
addressBook = nil;
[self reload];
}
self.needToUpdate = FALSE;
if ([CNContactStore class]) {
//ios9 or later
CNEntityType entityType = CNEntityTypeContacts;
if([CNContactStore authorizationStatusForEntityType:entityType] == CNAuthorizationStatusNotDetermined) {
CNContactStore * contactStore = [[CNContactStore alloc] init];
LOGD(@"CNContactStore requesting authorization");
[contactStore requestAccessForEntityType:entityType completionHandler:^(BOOL granted, NSError * _Nullable error) {
LOGD(@"CNContactStore authorization granted");
}];
} else if([CNContactStore authorizationStatusForEntityType:entityType]== CNAuthorizationStatusAuthorized) {
LOGD(@"CNContactStore authorization granted");
if (floor(NSFoundationVersionNumber) >= NSFoundationVersionNumber_iOS_9_x_Max) {
if ([CNContactStore class]) {
// ios9 or later
if (store == NULL)
store = [[CNContactStore alloc] init];
[self fetchContactsInBackGroundThread];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateAddressBook:) name:CNContactStoreDidChangeNotification object:nil];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateAddressBook:) name:CNContactStoreDidChangeNotification object:nil];
}
return self;
}
- (void)saveAddressBook {
if (addressBook != nil) {
if (!ABAddressBookSave(addressBook, nil)) {
LOGW(@"Couldn't save Address Book");
- (void) fetchContactsInBackGroundThread{
CNEntityType entityType = CNEntityTypeContacts;
[store requestAccessForEntityType:entityType completionHandler:^(BOOL granted, NSError *_Nullable error) {
BOOL success = FALSE;
if(granted){
LOGD(@"CNContactStore authorization granted");
NSError *contactError;
CNContactStore* store = [[CNContactStore alloc] init];
[store containersMatchingPredicate:[CNContainer predicateForContainersWithIdentifiers:@[ store.defaultContainerIdentifier]] error:&contactError];
NSArray *keysToFetch = @[
CNContactEmailAddressesKey, CNContactPhoneNumbersKey,
CNContactFamilyNameKey, CNContactGivenNameKey, CNContactNicknameKey,
CNContactPostalAddressesKey, CNContactIdentifierKey,
CNInstantMessageAddressUsernameKey, CNContactInstantMessageAddressesKey,
CNInstantMessageAddressUsernameKey, CNContactImageDataKey
];
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keysToFetch];
success = [store enumerateContactsWithFetchRequest:request error:&contactError usingBlock:^(CNContact *__nonnull contact, BOOL *__nonnull stop) {
if (contactError) {
NSLog(@"error fetching contacts %@",
contactError);
} else {
dispatch_async(dispatch_get_main_queue(), ^{
Contact *newContact = [[Contact alloc] initWithCNContact:contact];
[self registerAddrsFor:newContact];
});
}
}];
}
}
}
- (void)reload {
CFErrorRef error;
// create if it doesn't exist
if (addressBook == nil) {
addressBook = ABAddressBookCreateWithOptions(NULL, &error);
}
if (addressBook != nil) {
__weak FastAddressBook *weakSelf = self;
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (!granted) {
LOGE(@"Permission for address book acces was denied: %@", [(__bridge NSError *)error description]);
return;
}];
// load Linphone friends
const MSList *lists = linphone_core_get_friends_lists(LC);
while (lists) {
LinphoneFriendList *fl = lists->data;
const MSList *friends = linphone_friend_list_get_friends(fl);
while (friends) {
LinphoneFriend *f = friends->data;
// only append friends that are not native contacts (already added
// above)
if (linphone_friend_get_ref_key(f) == NULL) {
Contact *contact = [[Contact alloc] initWithFriend:f];
[self registerAddrsFor:contact];
}
ABAddressBookRegisterExternalChangeCallback(addressBook, sync_address_book, (__bridge void *)(weakSelf));
dispatch_async(dispatch_get_main_queue(), ^(void) {
[weakSelf loadData];
});
});
} else {
LOGE(@"Create AddressBook failed, reason: %@", [(__bridge NSError *)error localizedDescription]);
friends = friends->next;
}
linphone_friend_list_update_subscriptions(fl);
lists = lists->next;
}
[NSNotificationCenter.defaultCenter
postNotificationName:kLinphoneAddressBookUpdate
object:self];
}
-(void) updateAddressBook:(NSNotification*) notif {
@ -177,81 +193,41 @@ static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info
}
- (void)registerAddrsFor:(Contact *)contact {
for (NSString *phone in contact.phoneNumbers) {
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)];
}
}
- (void)loadData {
@synchronized(_addressBookMap) {
ABAddressBookRevert(addressBook);
[_addressBookMap removeAllObjects];
// load native contacts
CFArrayRef lContacts = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex count = CFArrayGetCount(lContacts);
for (CFIndex idx = 0; idx < count; idx++) {
ABRecordRef lPerson = CFArrayGetValueAtIndex(lContacts, idx);
Contact *contact = [[Contact alloc] initWithPerson:lPerson];
[self registerAddrsFor:contact];
}
CFRelease(lContacts);
// load Linphone friends
const MSList *lists = linphone_core_get_friends_lists(LC);
while (lists) {
LinphoneFriendList *fl = lists->data;
const MSList *friends = linphone_friend_list_get_friends(fl);
while (friends) {
LinphoneFriend *f = friends->data;
// only append friends that are not native contacts (already added above)
if (linphone_friend_get_ref_key(f) == NULL) {
Contact *contact = [[Contact alloc] initWithFriend:f];
[self registerAddrsFor:contact];
Contact* mContact = contact;
for (NSString *phone in mContact.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) {
if(_addressBookMap){
if(mContact){
[_addressBookMap setObject:mContact forKey:(name ?: [FastAddressBook localizedLabel:phone])];
}else{
// Dosomte
}
}
friends = friends->next;
}
linphone_friend_list_update_subscriptions(fl);
lists = lists->next;
if (normalizedPhone)
ms_free(normalizedPhone);
}
for (NSString *sip in mContact.sipAddresses) {
[_addressBookMap setObject:mContact forKey:([FastAddressBook normalizeSipURI:sip] ?: sip)];
}
}
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneAddressBookUpdate object:self];
}
void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info, void *context) {
FastAddressBook *fastAddressBook = (__bridge FastAddressBook *)context;
[fastAddressBook loadData];
}
- (void)dealloc {
ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, (__bridge void *)(self));
CFRelease(addressBook);
}
#pragma mark - Tools
+ (NSString *)localizedLabel:(NSString *)label {
if (label != nil) {
return CFBridgingRelease(ABAddressBookCopyLocalizedLabel((__bridge CFStringRef)(label)));
}
return @"";
return [CNLabeledValue localizedStringForLabel:label];
}
return @"";
}
+ (BOOL)contactHasValidSipDomain:(Contact *)contact {
if (contact == nil)
return NO;
// Check if one of the contact' sip URI matches the expected SIP filter
NSString *domain = LinphoneManager.instance.contactFilter;
@ -317,60 +293,127 @@ void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info, void
return ret;
}
- (int)removeContact:(Contact *)contact {
// Remove contact from book
@synchronized(_addressBookMap) {
if (contact.person && ABRecordGetRecordID(contact.person) != kABRecordInvalidID) {
CFErrorRef error = NULL;
ABAddressBookRemoveRecord(addressBook, contact.person, (CFErrorRef *)&error);
if (error != NULL) {
LOGE(@"Remove contact %p: Fail(%@)", contact, [(__bridge NSError *)error localizedDescription]);
} else {
LOGI(@"Remove contact %p: Success!", contact);
}
contact = NULL;
// Save address book
error = NULL;
ABAddressBookSave(addressBook, (CFErrorRef *)&error);
- (BOOL)deleteContact:(Contact *)contact {
return [self deleteCNContact:contact.person];
}
// TODO: stop reloading the whole address book but just clear the removed entries!
[self loadData];
- (CNContact *)getCNContactFromContact:(Contact *)acontact {
NSArray *keysToFetch = @[
CNContactEmailAddressesKey, CNContactPhoneNumbersKey,
CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPostalAddressesKey,
CNContactIdentifierKey, CNContactInstantMessageAddressesKey,
CNInstantMessageAddressUsernameKey, CNContactImageDataKey
];
CNMutableContact *mCNContact =
[[store unifiedContactWithIdentifier:acontact.identifier
keysToFetch:keysToFetch
error:nil] mutableCopy];
return mCNContact;
}
if (error != NULL) {
LOGE(@"Save AddressBook: Fail(%@)", [(__bridge NSError *)error localizedDescription]);
} else {
LOGI(@"Save AddressBook: Success!");
}
return error ? -1 : 0;
}
return -2;
- (BOOL)deleteCNContact:(CNContact *)contact {
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
[saveRequest deleteContact:[contact mutableCopy]];
@try {
BOOL success = [store executeSaveRequest:saveRequest error:nil];
NSLog(@"Success %d", success);
if(success)
[self fetchContactsInBackGroundThread];
} @catch (NSException *exception) {
NSLog(@"description = %@", [exception description]);
return FALSE;
}
return TRUE;
}
- (BOOL)deleteAllContacts {
NSArray *keys = @[ CNContactPhoneNumbersKey ];
NSString *containerId = store.defaultContainerIdentifier;
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
NSError *error;
NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate
keysToFetch:keys
error:&error];
if (error) {
NSLog(@"error fetching contacts %@", error);
return FALSE;
} else {
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
for (CNContact *contact in cnContacts) {
[saveRequest deleteContact:[contact mutableCopy]];
}
@try {
NSLog(@"Success %d", [store executeSaveRequest:saveRequest error:nil]);
} @catch (NSException *exception) {
NSLog(@"description = %@", [exception description]);
return FALSE;
}
NSLog(@"Deleted contacts %lu", (unsigned long)cnContacts.count);
}
return TRUE;
}
- (BOOL)saveContact:(Contact *)contact {
@synchronized(_addressBookMap) {
CFErrorRef error = NULL;
if (ABRecordGetRecordID(contact.person) == kABRecordInvalidID) {
if (ABAddressBookAddRecord(addressBook, contact.person, (CFErrorRef *)&error)) {
LOGI(@"Add contact %p: Success!", contact.person);
} else {
LOGE(@"Add contact %p: Fail(%@)", contact.person, [(__bridge NSError *)error localizedDescription]);
return FALSE;
}
}
// Save address book
error = NULL;
if (ABAddressBookSave(addressBook, &error)) {
LOGI(@"Save AddressBook: Success!");
} else {
LOGE(@"Save AddressBook: Fail(%@)", [(__bridge NSError *)error localizedDescription]);
return FALSE;
}
[self reload];
return error == NULL;
}
return [self saveCNContact:contact.person contact:contact];
}
- (BOOL)saveCNContact:(CNContact *)cNContact contact:(Contact *)contact {
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
NSArray *keysToFetch = @[
CNContactEmailAddressesKey, CNContactPhoneNumbersKey,
CNContactInstantMessageAddressesKey, CNInstantMessageAddressUsernameKey,
CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPostalAddressesKey,
CNContactIdentifierKey, CNContactImageDataKey, CNContactNicknameKey
];
CNMutableContact *mCNContact =
[[store unifiedContactWithIdentifier:contact.identifier
keysToFetch:keysToFetch
error:nil] mutableCopy];
if(mCNContact == NULL){
[saveRequest addContact:[cNContact mutableCopy] toContainerWithIdentifier:nil];
}else{
[mCNContact setGivenName:contact.firstName];
[mCNContact setFamilyName:contact.lastName];
[mCNContact setNickname:contact.displayName];
[mCNContact setPhoneNumbers:contact.person.phoneNumbers];
[mCNContact setEmailAddresses:contact.person.emailAddresses];
[mCNContact
setInstantMessageAddresses:contact.person.instantMessageAddresses];
[mCNContact setImageData:UIImageJPEGRepresentation(contact.avatar, 0.9f)];
[saveRequest updateContact:mCNContact];
}
NSError *saveError;
@try {
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]);
return FALSE;
}
[self fetchContactsInBackGroundThread];
return TRUE;
}
-(void)updateFriend:(Contact*) contact{
bctbx_list_t *phonesList = linphone_friend_get_phone_numbers(contact.friend);
for (NSString *phone in contact.phones) {
if(!(bctbx_list_find(phonesList, [phone UTF8String]))){
linphone_friend_edit(contact.friend);
linphone_friend_add_phone_number(contact.friend, [phone UTF8String]);
linphone_friend_enable_subscribes(contact.friend, TRUE);
linphone_friend_done(contact.friend);
}
}
BOOL enabled = [LinphoneManager.instance lpConfigBoolForKey:@"use_rls_presence"];
const MSList *lists = linphone_core_get_friends_lists(LC);
while (lists) {
linphone_friend_list_enable_subscriptions(lists->data, FALSE);
linphone_friend_list_enable_subscriptions(lists->data, enabled);
linphone_friend_list_update_subscriptions(lists->data);
lists = lists->next;
}
}
@end

View file

@ -454,48 +454,53 @@
}
+ (LinphoneAddress *)normalizeSipOrPhoneAddress:(NSString *)value {
if (!value) {
return NULL;
}
LinphoneProxyConfig *cfg = linphone_core_get_default_proxy_config(LC);
const char * normvalue;
if (linphone_proxy_config_is_phone_number(cfg, value.UTF8String)) {
normvalue = linphone_proxy_config_normalize_phone_number(cfg, value.UTF8String);
} else {
normvalue = value.UTF8String;
}
LinphoneAddress *addr = linphone_proxy_config_normalize_sip_uri(cfg, normvalue);
// first try to find a friend with the given address
Contact *c = [FastAddressBook getContactWithAddress:addr];
if (c && c.friend) {
LinphoneFriend *f = c.friend;
const LinphonePresenceModel *m =
f ? linphone_friend_get_presence_model_for_uri_or_tel(f, value.UTF8String) : NULL;
const char *contact = m ? linphone_presence_model_get_contact(m) : NULL;
if (contact) {
LinphoneAddress *contact_addr = linphone_address_new(contact);
if (contact_addr) {
linphone_address_destroy(addr);
return contact_addr;
}
}
}
if (!value || [value isEqualToString:@""]) {
return NULL;
}
LinphoneProxyConfig *cfg = linphone_core_get_default_proxy_config(LC);
const char *normvalue;
if (linphone_proxy_config_is_phone_number(cfg, value.UTF8String)) {
normvalue =
linphone_proxy_config_normalize_phone_number(cfg, value.UTF8String);
} else {
normvalue = value.UTF8String;
}
LinphoneAddress *addr =
linphone_proxy_config_normalize_sip_uri(cfg, normvalue);
// first try to find a friend with the given address
Contact *c = [FastAddressBook getContactWithAddress:addr];
// since user wants to escape plus, we assume it expects to have phone numbers by default
if (addr) {
if (cfg && (linphone_proxy_config_get_dial_escape_plus(cfg))) {
if (linphone_proxy_config_is_phone_number(cfg, normvalue)) {
linphone_address_set_username(addr, normvalue);
}
} else {
if (linphone_proxy_config_is_phone_number(cfg, value.UTF8String)) {
linphone_address_set_username(addr, value.UTF8String);
}
}
}
if (c && c.friend) {
LinphoneFriend *f = c.friend;
const LinphonePresenceModel *m =
f ? linphone_friend_get_presence_model_for_uri_or_tel(f,
value.UTF8String)
: NULL;
const char *contact = m ? linphone_presence_model_get_contact(m) : NULL;
if (contact) {
LinphoneAddress *contact_addr = linphone_address_new(contact);
if (contact_addr) {
linphone_address_destroy(addr);
return contact_addr;
}
}
}
return addr;
// since user wants to escape plus, we assume it expects to have phone
// numbers by default
if (addr) {
if (cfg && (linphone_proxy_config_get_dial_escape_plus(cfg))) {
if (linphone_proxy_config_is_phone_number(cfg, normvalue)) {
linphone_address_set_username(addr, normvalue);
}
} else {
if (linphone_proxy_config_is_phone_number(cfg, value.UTF8String)) {
linphone_address_set_username(addr, value.UTF8String);
}
}
}
return addr;
}
@end

View file

@ -48,13 +48,11 @@ max_calls=3
real_early_media=1
[net]
download_bw=380
edge_bw=10
edge_ping_time=10
firewall_policy=ice
mtu=1300
stun_server=stun.linphone.org
upload_bw=380
[rtp]
audio_jitt_comp=60
@ -93,5 +91,5 @@ capture=1
display=1
enabled=1
show_local=0
size=qvga
size=vga

View file

@ -21,6 +21,10 @@ publish_presence=0
password_length=-1
username_length=-1
[net]
download_bw=0
upload_bw=0
[sip]
sip_random_port=0
#whether SIP passwords must be encrypted in configuration storage file

View file

@ -22,13 +22,11 @@ file_transfer_server_url=https://www.linphone.org:444/lft.php
max_calls=3
[net]
download_bw=512
edge_bw=10
edge_ping_time=10
firewall_policy=ice
mtu=1300
stun_server=stun.linphone.org
upload_bw=512
[rtp]
audio_jitt_comp=60

View file

@ -202,6 +202,16 @@
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>
<dict>
<key>Key</key>
<string>codec2_preference</string>
<key>Title</key>
<string>codec2</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>DefaultValue</key>
<false/>
</dict>
<dict>
<key>Key</key>
<string>audio_advanced_group</string>

View file

@ -127,8 +127,7 @@
linphone_address_set_header(testAddr, "X-Create-Account", "yes");
linphone_address_set_transport(testAddr, LinphoneTransportTcp);
linphone_address_set_port(testAddr, 0);
LinphoneProxyConfig *testProxy = linphone_core_create_proxy_config(LC);
LinphoneProxyConfig *testProxy = linphone_core_create_proxy_config(lc);
linphone_proxy_config_set_identity_address(testProxy, testAddr);
linphone_proxy_config_set_server_addr(testProxy, [self accountProxyRoute].UTF8String);
linphone_proxy_config_set_route(testProxy, [self accountProxyRoute].UTF8String);
@ -151,7 +150,7 @@
linphone_core_set_file_transfer_server(lc, "https://www.linphone.org:444/lft.php");
// reload address book to prepend proxy config domain to contacts' phone number
[[[LinphoneManager instance] fastAddressBook] reload];
[[[LinphoneManager instance] fastAddressBook] fetchContactsInBackGroundThread];
[self waitForRegistration];
[[LinphoneManager instance] lpConfigSetInt:NO forKey:@"animations_preference"];

View file

@ -53,7 +53,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>3</string>
<string>9</string>
<key>ITSAppUsesNonExemptEncryption</key>
<true/>
<key>ITSEncryptionExportComplianceCode</key>

View file

@ -29,8 +29,6 @@
228697C411AC29B800E9E0CA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 228697C311AC29B800E9E0CA /* CFNetwork.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
22968A5F12F875C600588287 /* UISpeakerButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 22968A5E12F875C600588287 /* UISpeakerButton.m */; };
22AA8B0113D83F6300B30535 /* UICamSwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = 22AA8B0013D83F6300B30535 /* UICamSwitch.m */; };
22B5EFA310CE50BD00777D97 /* AddressBookUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22B5EFA210CE50BD00777D97 /* AddressBookUI.framework */; };
22B5F03510CE6B2F00777D97 /* AddressBook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22B5F03410CE6B2F00777D97 /* AddressBook.framework */; };
22C755601317E59C007BC101 /* UIBluetoothButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 22C7555F1317E59C007BC101 /* UIBluetoothButton.m */; };
22D1B68112A3E0BE001AE361 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 22D1B68012A3E0BE001AE361 /* libresolv.dylib */; };
22E0A822111C44E100B04932 /* AboutView.m in Sources */ = {isa = PBXBuildFile; fileRef = 22E0A81C111C44E100B04932 /* AboutView.m */; };
@ -41,6 +39,7 @@
244523BE1E8D3A6C0037A187 /* chat_unsecure.png in Resources */ = {isa = PBXBuildFile; fileRef = 244523BC1E8D3A6C0037A187 /* chat_unsecure.png */; };
24A3459E1D95797700881A5C /* UIShopTableCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 24A3459D1D95797700881A5C /* UIShopTableCell.xib */; };
24A345A61D95798A00881A5C /* UIShopTableCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 24A345A51D95798A00881A5C /* UIShopTableCell.m */; };
24E1C7C01F9A235600D3F981 /* Contacts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 24E1C7B91F9A235500D3F981 /* Contacts.framework */; };
288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; };
340751971506459A00B89C47 /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 340751961506459A00B89C47 /* CoreTelephony.framework */; };
340751E7150F38FD00B89C47 /* UIVideoButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 340751E6150F38FD00B89C47 /* UIVideoButton.m */; };
@ -987,6 +986,7 @@
24A3459D1D95797700881A5C /* UIShopTableCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UIShopTableCell.xib; sourceTree = "<group>"; };
24A345A51D95798A00881A5C /* UIShopTableCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIShopTableCell.m; sourceTree = "<group>"; };
24A345A71D95799900881A5C /* UIShopTableCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIShopTableCell.h; sourceTree = "<group>"; };
24E1C7B91F9A235500D3F981 /* Contacts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Contacts.framework; path = System/Library/Frameworks/Contacts.framework; sourceTree = SDKROOT; };
288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
32CA4F630368D1EE00C91783 /* linphone_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linphone_Prefix.pch; sourceTree = "<group>"; };
@ -1920,6 +1920,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
24E1C7C01F9A235600D3F981 /* Contacts.framework in Frameworks */,
8C5BCED61EB3859300A9AAEF /* mediastreamer_voip.framework in Frameworks */,
8C2595DF1DEDCC8E007A6424 /* CallKit.framework in Frameworks */,
8C5BCED81EB3859300A9AAEF /* mssilk.framework in Frameworks */,
@ -1935,8 +1936,6 @@
6334DDFA1BBAC97C00631900 /* libsqlite3.dylib in Frameworks */,
152F22361B15E889008C0621 /* libxml2.dylib in Frameworks */,
570742671D5A63DB004B9C84 /* StoreKit.framework in Frameworks */,
22B5F03510CE6B2F00777D97 /* AddressBook.framework in Frameworks */,
22B5EFA310CE50BD00777D97 /* AddressBookUI.framework in Frameworks */,
22405EEE1600B4E400B92522 /* AssetsLibrary.framework in Frameworks */,
2274402F106F335E006EC466 /* AudioToolbox.framework in Frameworks */,
224567C2107B968500F10948 /* AVFoundation.framework in Frameworks */,
@ -2299,6 +2298,7 @@
8C1A1F7C1FA331D40064BE00 /* libsoci_sqlite3.a */,
8CD0B3C81FA2357B008FEB16 /* libsqlite3.a */,
8CD0B3BE1FA22CBA008FEB16 /* libsoci_core.a */,
24E1C7B91F9A235500D3F981 /* Contacts.framework */,
8C3EAA191EB8D9C300B732B6 /* linphonetester.framework */,
8C5BCEC61EB3859200A9AAEF /* bctoolbox-tester.framework */,
8C3EA9EF1EB8A78C00B732B6 /* msx264.framework */,
@ -4657,15 +4657,10 @@
);
INFOPLIST_FILE = "linphone-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(BUILT_PRODUCTS_DIR)",
"$(SRCROOT)/liblinphone-sdk/apple-darwin/lib",
"$(SRCROOT)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
);
LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)";
LINK_WITH_STANDARD_LIBRARIES = YES;
ORDER_FILE = "";
OTHER_CFLAGS = "-DBCTBX_LOG_DOMAIN=\\\"ios\\\"";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone;
PRODUCT_NAME = linphone;
@ -4760,15 +4755,10 @@
);
INFOPLIST_FILE = "linphone-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(BUILT_PRODUCTS_DIR)",
"$(SRCROOT)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
"$(SRCROOT)/liblinphone-sdk/apple-darwin/lib",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
);
LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)";
LINK_WITH_STANDARD_LIBRARIES = YES;
ORDER_FILE = "";
OTHER_CFLAGS = "-DBCTBX_LOG_DOMAIN=\\\"ios\\\"";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone;
PRODUCT_NAME = linphone;
@ -4863,15 +4853,10 @@
);
INFOPLIST_FILE = "linphone-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(BUILT_PRODUCTS_DIR)",
"$(SRCROOT)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
"$(SRCROOT)/liblinphone-sdk/apple-darwin/lib",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
);
LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)";
LINK_WITH_STANDARD_LIBRARIES = YES;
ORDER_FILE = "";
OTHER_CFLAGS = "-DBCTBX_LOG_DOMAIN=\\\"ios\\\"";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone;
PRODUCT_NAME = linphone;
@ -4966,15 +4951,10 @@
);
INFOPLIST_FILE = "linphone-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(BUILT_PRODUCTS_DIR)",
"$(SRCROOT)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
"$(SRCROOT)/liblinphone-sdk/apple-darwin/lib",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
);
LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)";
LINK_WITH_STANDARD_LIBRARIES = YES;
ORDER_FILE = "";
OTHER_CFLAGS = "-DBCTBX_LOG_DOMAIN=\\\"ios\\\"";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone;
PRODUCT_NAME = linphone;
@ -5284,11 +5264,7 @@
);
INFOPLIST_FILE = "LiblinphoneTester/LinphoneTester-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.belledonne-communications.tester.liblinphoneTester";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -5339,11 +5315,7 @@
);
INFOPLIST_FILE = "LiblinphoneTester/LinphoneTester-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = "com.belledonne-communications.tester.liblinphoneTester";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
@ -5394,11 +5366,7 @@
);
INFOPLIST_FILE = "LiblinphoneTester/LinphoneTester-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = "com.belledonne-communications.tester.liblinphoneTester";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
@ -5449,11 +5417,7 @@
);
INFOPLIST_FILE = "LiblinphoneTester/LinphoneTester-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib",
"$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins",
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = "com.belledonne-communications.tester.liblinphoneTester";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";

@ -1 +1 @@
Subproject commit d2fd296e8c8ba84c9f192dbb7b59e22e9080a8f6
Subproject commit 91196256ce3aed92870e2291558cc796b9c7f4d4