implement fast address book lookup

This commit is contained in:
Jehan Monnier 2011-05-30 17:25:06 +02:00
parent 3a9326a9eb
commit 566cfbd491
6 changed files with 349 additions and 202 deletions

View file

@ -0,0 +1,41 @@
/* FastAddressBook.h
*
* Copyright (C) 2011 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <Foundation/Foundation.h>
#import <AddressBook/AddressBook.h>
@interface Contact : NSObject {
ABRecordRef record;
NSString* numberType;
}
-(id) initWithRecord:(ABRecordRef) record ofType:(NSString*) type;
@property (nonatomic, readonly) ABRecordRef record;
@property (nonatomic, readonly) NSString* numberType;
@end
@interface FastAddressBook : NSObject {
NSMutableDictionary* mAddressBookMap;
}
-(Contact*) getMatchingRecord:(NSString*) number ;
+(NSString*) appendCountryCodeIfPossible:(NSString*) number ;
+(NSString*) normalizePhoneNumber:(NSString*) number ;
-(id) init ;
@end

View file

@ -0,0 +1,98 @@
/* FastAddressBook.h
*
* Copyright (C) 2011 Belledonne Comunications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "FastAddressBook.h"
@implementation FastAddressBook
-(Contact*) getMatchingRecord:(NSString*) number {
@synchronized (mAddressBookMap){
return (Contact*) [mAddressBookMap objectForKey:number];
}
}
+(NSString*) appendCountryCodeIfPossible:(NSString*) number {
if (![number hasPrefix:@"+"] && ![number hasPrefix:@"00"]) {
NSString* lCountryCode = [[NSUserDefaults standardUserDefaults] stringForKey:@"countrycode_preference"];
if (lCountryCode && [lCountryCode length]>0) {
//append country code
return [lCountryCode stringByAppendingString:number];
}
}
return number;
}
+(NSString*) normalizePhoneNumber:(NSString*) number {
NSString* lNormalizedNumber = [(NSString*)number stringByReplacingOccurrencesOfString:@" " withString:@""];
lNormalizedNumber = [lNormalizedNumber stringByReplacingOccurrencesOfString:@"(" withString:@""];
lNormalizedNumber = [lNormalizedNumber stringByReplacingOccurrencesOfString:@")" withString:@""];
lNormalizedNumber = [lNormalizedNumber stringByReplacingOccurrencesOfString:@"-" withString:@""];
lNormalizedNumber = [FastAddressBook appendCountryCodeIfPossible:lNormalizedNumber];
return lNormalizedNumber;
}
void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context) {
NSMutableDictionary* lAddressBookMap = (NSMutableDictionary*)context;
@synchronized (lAddressBookMap) {
[lAddressBookMap removeAllObjects];
NSArray *lContacts = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
for (id lPerson in lContacts) {
ABMutableMultiValueRef lPhoneNumbers = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonPhoneProperty);
for ( int i=0; i<ABMultiValueGetCount(lPhoneNumbers); i++) {
CFStringRef lValue = ABMultiValueCopyValueAtIndex(lPhoneNumbers,i);
CFStringRef lLabel = ABMultiValueCopyLabelAtIndex(lPhoneNumbers,i);
CFStringRef lLocalizedLabel = ABAddressBookCopyLocalizedLabel(lLabel);
NSString* lNormalizedKey = [FastAddressBook normalizePhoneNumber:(NSString*)lValue];
Contact* lContact = [[Contact alloc] initWithRecord:lPerson ofType:(NSString *)lLocalizedLabel];
[lAddressBookMap setObject:lContact forKey:lNormalizedKey];
CFRelease(lValue);
CFRelease(lLabel);
CFRelease(lLocalizedLabel);
}
CFRelease(lPhoneNumbers);
}
CFRelease(lContacts);
}
}
-(FastAddressBook*) init {
if ((self = [super init])) {
mAddressBookMap = [[NSMutableDictionary alloc] init];
ABAddressBookRef lAddressBook = ABAddressBookCreate();
ABAddressBookRegisterExternalChangeCallback (lAddressBook,sync_address_book,mAddressBookMap);
sync_address_book(lAddressBook,nil,mAddressBookMap);
}
return self;
}
@end
@implementation Contact
@synthesize record;
@synthesize numberType;
-(id) initWithRecord:(ABRecordRef) aRecord ofType:(NSString*) type {
if ((self = [super init])) {
record=CFRetain(aRecord);
numberType= [type retain];
}
return self;
}
- (void)dealloc {
[super dealloc];
CFRelease(record);
[numberType release];
}
@end

View file

@ -27,7 +27,7 @@ typedef enum _Connectivity {
wwan
,none
} Connectivity;
@class FastAddressBook;
@interface LinphoneManager : NSObject {
@private
SCNetworkReachabilityContext proxyReachabilityContext;
@ -41,6 +41,7 @@ typedef enum _Connectivity {
UIViewController* mCurrentViewController;
Connectivity connectivity;
FastAddressBook* mFastAddressBook;
}
+(LinphoneManager*) instance;
@ -60,3 +61,5 @@ typedef enum _Connectivity {
@property (nonatomic, retain) id<LinphoneUIRegistrationDelegate> registrationDelegate;
@property Connectivity connectivity;
@end

View file

@ -25,9 +25,7 @@
#include <netdb.h>
#import <AVFoundation/AVAudioSession.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AddressBook/AddressBook.h>
#import "FastAddressBook.h"
static LinphoneCore* theLinphoneCore=nil;
static LinphoneManager* theLinphoneManager=nil;
@ -40,12 +38,19 @@ extern void libmsamr_init();
@synthesize registrationDelegate;
@synthesize connectivity;
-(id) init {
if ((self= [super init])) {
mFastAddressBook = [[FastAddressBook alloc] init];
}
return self;
}
+(LinphoneManager*) instance {
if (theLinphoneManager==nil) {
theLinphoneManager = [LinphoneManager alloc];
theLinphoneManager = [[LinphoneManager alloc] init];
}
return theLinphoneManager;
}
-(NSString*) appendCountryCodeIfPossible:(NSString*) number {
if (![number hasPrefix:@"+"] && ![number hasPrefix:@"00"]) {
NSString* lCountryCode = [[NSUserDefaults standardUserDefaults] stringForKey:@"countrycode_preference"];
@ -58,41 +63,24 @@ extern void libmsamr_init();
}
-(NSString*) getDisplayNameFromAddressBook:(NSString*) number andUpdateCallLog:(LinphoneCallLog*)log {
ABAddressBookRef lAddressBook = ABAddressBookCreate();
NSArray *lContacts = (NSArray *)ABAddressBookCopyArrayOfAllPeople(lAddressBook);
for (id lContact in lContacts) {
ABMutableMultiValueRef lPhoneNumbers = ABRecordCopyValue((ABRecordRef)lContact, kABPersonPhoneProperty);
for ( int i=0; i<ABMultiValueGetCount(lPhoneNumbers); i++) {
CFStringRef lLabel = ABMultiValueCopyLabelAtIndex(lPhoneNumbers,i);
CFStringRef lValue = ABMultiValueCopyValueAtIndex(lPhoneNumbers,i);
CFStringRef lLocalizedLabel = ABAddressBookCopyLocalizedLabel(lLabel);
NSString* lNormalizedNumber = [(NSString*)lValue stringByReplacingOccurrencesOfString:@" " withString:@""];
lNormalizedNumber = [lNormalizedNumber stringByReplacingOccurrencesOfString:@"(" withString:@""];
lNormalizedNumber = [lNormalizedNumber stringByReplacingOccurrencesOfString:@")" withString:@""];
lNormalizedNumber = [lNormalizedNumber stringByReplacingOccurrencesOfString:@"-" withString:@""];
lNormalizedNumber = [self appendCountryCodeIfPossible:lNormalizedNumber];
number = [self appendCountryCodeIfPossible:number];
if([lNormalizedNumber isEqualToString:number]) {
CFStringRef lDisplayName = ABRecordCopyCompositeName(lContact);
if (log) {
//add phone type
char ltmpString[256];
CFStringRef lFormatedString = CFStringCreateWithFormat(NULL,NULL,CFSTR("phone_type:%@;"),lLocalizedLabel);
CFStringGetCString(lFormatedString, ltmpString,sizeof(ltmpString), kCFStringEncodingUTF8);
linphone_call_log_set_ref_key(log, ltmpString);
CFRelease(lFormatedString);
}
return (NSString*)lDisplayName;
}
CFRelease(lLabel);
CFRelease(lValue);
CFRelease(lLocalizedLabel);
}
//1 normalize
NSString* lNormalizedNumber = [FastAddressBook normalizePhoneNumber:number];
Contact* lContact = [mFastAddressBook getMatchingRecord:lNormalizedNumber];
if (lContact) {
CFStringRef lDisplayName = ABRecordCopyCompositeName(lContact.record);
if (log) {
//add phone type
char ltmpString[256];
CFStringRef lFormatedString = CFStringCreateWithFormat(NULL,NULL,CFSTR("phone_type:%@;"),lContact.numberType);
CFStringGetCString(lFormatedString, ltmpString,sizeof(ltmpString), kCFStringEncodingUTF8);
linphone_call_log_set_ref_key(log, ltmpString);
CFRelease(lFormatedString);
}
return (NSString*)lDisplayName;
}
//[number release];
return nil;
}
-(void) updateCallWithAddressBookData:(LinphoneCall*) call {
@ -443,6 +431,7 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach
const char* proxy = [proxyAddress cStringUsingEncoding:[NSString defaultCStringEncoding]];
NSString* prefix = [[NSUserDefaults standardUserDefaults] stringForKey:@"prefix_preference"];
bool substitute_plus_by_00 = [[NSUserDefaults standardUserDefaults] boolForKey:@"substitute_+_by_00_preference"];
//possible valid config detected
LinphoneProxyConfig* proxyCfg;
proxyCfg = linphone_proxy_config_new();
@ -467,7 +456,7 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach
if ([prefix length]>0) {
linphone_proxy_config_set_dial_prefix(proxyCfg, [prefix cStringUsingEncoding:[NSString defaultCStringEncoding]]);
}
linphone_proxy_config_set_dial_escape_plus(proxyCfg,TRUE);
linphone_proxy_config_set_dial_escape_plus(proxyCfg,substitute_plus_by_00);
linphone_core_add_proxy_config(theLinphoneCore,proxyCfg);
//set to default proxy

View file

@ -2,199 +2,218 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>StringsTable</key>
<string>Root</string>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>Type</key>
<string>PSGroupSpecifier</string>
<key>Title</key>
<string>SIP account</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>Title</key>
<string>User name</string>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
<key>DefaultValue</key>
<string></string>
<key>IsSecure</key>
<false/>
<key>Key</key>
<string>username_preference</string>
<key>DefaultValue</key>
<string></string>
<key>IsSecure</key>
<false/>
<key>KeyboardType</key>
<string>Alphabet</string>
<key>Title</key>
<string>User name</string>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
</dict>
<dict>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
</dict>
<dict>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>Title</key>
<string>Password</string>
<key>DefaultValue</key>
<string></string>
<key>IsSecure</key>
<true/>
<key>Key</key>
<string>password_preference</string>
<key>DefaultValue</key>
<string></string>
<key>IsSecure</key>
<true/>
<key>KeyboardType</key>
<string>Alphabet</string>
<key>Title</key>
<string>Password</string>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
</dict>
<dict>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
</dict>
<dict>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>Title</key>
<string>Domain</string>
<key>DefaultValue</key>
<string></string>
<key>IsSecure</key>
<false/>
<key>Key</key>
<string>domain_preference</string>
<key>DefaultValue</key>
<string></string>
<key>IsSecure</key>
<false/>
<key>KeyboardType</key>
<string>URL</string>
<key>Title</key>
<string>Domain</string>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
</dict>
<dict>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
</dict>
<dict>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>Title</key>
<string>Proxy</string>
<key>DefaultValue</key>
<string></string>
<key>IsSecure</key>
<false/>
<key>Key</key>
<string>proxy_preference</string>
<key>DefaultValue</key>
<string></string>
<key>IsSecure</key>
<false/>
<key>KeyboardType</key>
<string>URL</string>
<key>Title</key>
<string>Proxy</string>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
</dict>
<dict>
<key>DefaultValue</key>
<false/>
<key>Key</key>
<string>outbound_proxy_preference</string>
<key>Title</key>
<string>Outbound proxy</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>
<dict>
<key>Title</key>
<string>Codecs</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>DefaultValue</key>
<true/>
<key>Key</key>
<string>speex_16k_preference</string>
<key>Title</key>
<string>Speex 16Khz</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>
<dict>
<key>DefaultValue</key>
<true/>
<key>Key</key>
<string>speex_8k_preference</string>
<key>Title</key>
<string>Speex 8Khz</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>
<dict>
<key>DefaultValue</key>
<true/>
<key>Key</key>
<string>gsm_8k_preference</string>
<key>Title</key>
<string>GSM</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>
<dict>
<key>DefaultValue</key>
<true/>
<key>Key</key>
<string>ilbc_preference</string>
<key>Title</key>
<string>ILBC</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>
<dict>
<key>DefaultValue</key>
<true/>
<key>Key</key>
<string>pcmu_preference</string>
<key>Title</key>
<string>PCMU</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>
<dict>
<key>DefaultValue</key>
<true/>
<key>Key</key>
<string>pcma_preference</string>
<key>Title</key>
<string>PCMA</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>
<dict>
<key>Title</key>
<string>Advanced</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>DefaultValue</key>
<false/>
<key>Key</key>
<string>debugenable_preference</string>
<key>Title</key>
<string>Debug</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>
<dict>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
</dict>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>Outbound proxy</string>
<key>Key</key>
<string>outbound_proxy_preference</string>
<key>DefaultValue</key>
<false/>
</dict>
<dict>
<key>Type</key>
<string>PSGroupSpecifier</string>
<key>Title</key>
<string>Codecs</string>
</dict>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>Speex 16Khz</string>
<key>Key</key>
<string>speex_16k_preference</string>
<key>DefaultValue</key>
<true/>
</dict>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>Speex 8Khz</string>
<key>Key</key>
<string>speex_8k_preference</string>
<key>DefaultValue</key>
<true/>
</dict>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>GSM</string>
<key>Key</key>
<string>gsm_8k_preference</string>
<key>DefaultValue</key>
<true/>
</dict>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>ILBC</string>
<key>Key</key>
<string>ilbc_preference</string>
<key>DefaultValue</key>
<true/>
</dict>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>PCMU</string>
<key>Key</key>
<string>pcmu_preference</string>
<key>DefaultValue</key>
<true/>
</dict>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>PCMA</string>
<key>Key</key>
<string>pcma_preference</string>
<key>DefaultValue</key>
<true/>
</dict>
<dict>
<key>Type</key>
<string>PSGroupSpecifier</string>
<key>Title</key>
<string>Advanced</string>
</dict>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>Debug</string>
<key>Key</key>
<string>debugenable_preference</string>
<key>DefaultValue</key>
<false/>
</dict>
<dict>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>Title</key>
<string>Prefix</string>
<key>Key</key>
<string>prefix_preference</string>
<key>DefaultValue</key>
<string></string>
<key>IsSecure</key>
<false/>
<key>Key</key>
<string>prefix_preference</string>
<key>KeyboardType</key>
<string>NumberPad</string>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
<key>Title</key>
<string>Prefix</string>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
</dict>
<dict>
<key>DefaultValue</key>
<false/>
<key>Key</key>
<string>substitute_+_by_00_preference</string>
<key>Title</key>
<string>Substitue + by 00</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>
<dict>
<key>DefaultValue</key>
<string>udp</string>
<key>Key</key>
<string>transport_preference</string>
<key>Title</key>
<string>Transport</string>
<key>Titles</key>
<array>
<string>udp</string>
<string>tcp</string>
</array>
<key>Type</key>
<string>PSMultiValueSpecifier</string>
<key>Values</key>
@ -202,28 +221,19 @@
<string>udp</string>
<string>tcp</string>
</array>
<key>Titles</key>
<array>
<string>udp</string>
<string>tcp</string>
</array>
<key>Title</key>
<string>Transport</string>
<key>Key</key>
<string>transport_preference</string>
<key>DefaultValue</key>
<string>udp</string>
</dict>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>Background mode</string>
<key>Key</key>
<string>backgroundmode_preference</string>
<key>DefaultValue</key>
<false/>
<key>Key</key>
<string>backgroundmode_preference</string>
<key>Title</key>
<string>Background mode</string>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
</dict>
</array>
<key>StringsTable</key>
<string>Root</string>
</dict>
</plist>

View file

@ -35,6 +35,7 @@
223148E41178A08200637D6A /* libilbc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 223148E31178A08200637D6A /* libilbc.a */; };
223148E61178A09900637D6A /* libmsilbc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 223148E51178A09900637D6A /* libmsilbc.a */; };
2237D4091084D7A9001383EE /* oldphone-mono.wav in Resources */ = {isa = PBXBuildFile; fileRef = 2237D4081084D7A9001383EE /* oldphone-mono.wav */; };
223963171393CFAF001DE689 /* FastAddressBook.m in Sources */ = {isa = PBXBuildFile; fileRef = 223963161393CFAF001DE689 /* FastAddressBook.m */; };
2242D91610D66BF300E9963F /* in_call.png in Resources */ = {isa = PBXBuildFile; fileRef = 2242D91410D66BF300E9963F /* in_call.png */; };
2242D91710D66BF300E9963F /* out_call.png in Resources */ = {isa = PBXBuildFile; fileRef = 2242D91510D66BF300E9963F /* out_call.png */; };
2242D91A10D66C2100E9963F /* mic_active.png in Resources */ = {isa = PBXBuildFile; fileRef = 2242D91810D66C2100E9963F /* mic_active.png */; };
@ -257,6 +258,8 @@
223148E31178A08200637D6A /* libilbc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libilbc.a; path = "liblinphone-sdk/apple-darwin/lib/libilbc.a"; sourceTree = "<group>"; };
223148E51178A09900637D6A /* libmsilbc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmsilbc.a; path = "liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins/libmsilbc.a"; sourceTree = "<group>"; };
2237D4081084D7A9001383EE /* oldphone-mono.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = "oldphone-mono.wav"; path = "liblinphone-sdk/apple-darwin/share/sounds/linphone/rings/oldphone-mono.wav"; sourceTree = "<group>"; };
223963151393CFAE001DE689 /* FastAddressBook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FastAddressBook.h; sourceTree = "<group>"; };
223963161393CFAF001DE689 /* FastAddressBook.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FastAddressBook.m; sourceTree = "<group>"; };
2242D91410D66BF300E9963F /* in_call.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = in_call.png; path = Resources/in_call.png; sourceTree = "<group>"; };
2242D91510D66BF300E9963F /* out_call.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = out_call.png; path = Resources/out_call.png; sourceTree = "<group>"; };
2242D91810D66C2100E9963F /* mic_active.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = mic_active.png; path = "liblinphone-sdk/apple-darwin/share/pixmaps/linphone/mic_active.png"; sourceTree = "<group>"; };
@ -687,6 +690,8 @@
22C7555F1317E59C007BC101 /* UIBluetoothButton.m */,
22BB1A67132FF16A005CD7AA /* UIEraseButton.h */,
22BB1A68132FF16A005CD7AA /* UIEraseButton.m */,
223963151393CFAE001DE689 /* FastAddressBook.h */,
223963161393CFAF001DE689 /* FastAddressBook.m */,
);
path = LinphoneUI;
sourceTree = "<group>";
@ -998,6 +1003,7 @@
2218A92512FBE1340088A667 /* FirstLoginViewController.m in Sources */,
22C755601317E59C007BC101 /* UIBluetoothButton.m in Sources */,
22BB1A69132FF16A005CD7AA /* UIEraseButton.m in Sources */,
223963171393CFAF001DE689 /* FastAddressBook.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};