mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 19:18:06 +00:00
Merge branch 'master' into dev_group_chat
This commit is contained in:
commit
054df9ac24
39 changed files with 1375 additions and 1278 deletions
15
CHANGELOG.md
15
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
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -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>
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -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"/>
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@
|
|||
} else if (_cancelButton.hidden == NO) {
|
||||
[self onCancelClick:event];
|
||||
} else {
|
||||
[super onResendClick:event];
|
||||
[super onResend];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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"];
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>3</string>
|
||||
<string>9</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<true/>
|
||||
<key>ITSEncryptionExportComplianceCode</key>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Loading…
Add table
Reference in a new issue