mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-30 16:22:39 +00:00
1 - The contacts are now cached in the filesystem : it should improve the behaviour at could start
2 - the contact updates are now managed since the last sync so it should also improve the contact book
This commit is contained in:
parent
574c340d3e
commit
5371dcea35
9 changed files with 322 additions and 36 deletions
|
@ -22,6 +22,9 @@
|
||||||
// warn when there is a contacts list refresh
|
// warn when there is a contacts list refresh
|
||||||
extern NSString *const kContactManagerContactsListRefreshNotification;
|
extern NSString *const kContactManagerContactsListRefreshNotification;
|
||||||
|
|
||||||
|
// the phonenumber has been internationalized
|
||||||
|
extern NSString *const kContactsDidInternationalizeNotification;
|
||||||
|
|
||||||
@interface ContactManager : NSObject {
|
@interface ContactManager : NSObject {
|
||||||
dispatch_queue_t processingQueue;
|
dispatch_queue_t processingQueue;
|
||||||
NSMutableDictionary* matrixIDBy3PID;
|
NSMutableDictionary* matrixIDBy3PID;
|
||||||
|
@ -34,6 +37,9 @@ extern NSString *const kContactManagerContactsListRefreshNotification;
|
||||||
// delete contacts info
|
// delete contacts info
|
||||||
- (void)reset;
|
- (void)reset;
|
||||||
|
|
||||||
|
// refresh the international phonenumber of the contacts
|
||||||
|
- (void)internationalizePhoneNumbers:(NSString*)countryCode;
|
||||||
|
|
||||||
// refresh self.contacts
|
// refresh self.contacts
|
||||||
- (void)fullRefresh;
|
- (void)fullRefresh;
|
||||||
|
|
||||||
|
|
|
@ -27,13 +27,16 @@
|
||||||
// warn when there is a contacts list refresh
|
// warn when there is a contacts list refresh
|
||||||
NSString *const kContactManagerContactsListRefreshNotification = @"kContactManagerContactsListRefreshNotification";
|
NSString *const kContactManagerContactsListRefreshNotification = @"kContactManagerContactsListRefreshNotification";
|
||||||
|
|
||||||
|
// the phonenumber has been internationalized
|
||||||
|
NSString *const kContactsDidInternationalizeNotification = @"kContactsDidInternationalizeNotification";
|
||||||
|
|
||||||
// get the 3PIDS in one requests
|
// get the 3PIDS in one requests
|
||||||
//#define CONTACTS_3PIDS_SYNC 1
|
//#define CONTACTS_3PIDS_SYNC 1
|
||||||
// else checks the matrix IDs for each displayed contact
|
// else checks the matrix IDs for each displayed contact
|
||||||
|
|
||||||
@interface ContactManager() {
|
@interface ContactManager() {
|
||||||
NSDate *lastSyncDate;
|
NSDate *lastSyncDate;
|
||||||
NSMutableArray* deviceContactsList;
|
NSMutableDictionary* deviceContactByContactID;
|
||||||
|
|
||||||
//
|
//
|
||||||
NSMutableArray* pending3PIDs;
|
NSMutableArray* pending3PIDs;
|
||||||
|
@ -93,10 +96,11 @@ static ContactManager* sharedContactManager = nil;
|
||||||
|
|
||||||
// delete contacts info
|
// delete contacts info
|
||||||
- (void)reset {
|
- (void)reset {
|
||||||
|
|
||||||
contacts = nil;
|
contacts = nil;
|
||||||
|
|
||||||
lastSyncDate = nil;
|
lastSyncDate = nil;
|
||||||
deviceContactsList = nil;
|
deviceContactByContactID = nil;
|
||||||
matrixContactByMatrixUserID = nil;
|
matrixContactByMatrixUserID = nil;
|
||||||
if (hasStatusObserver) {
|
if (hasStatusObserver) {
|
||||||
[[MatrixSDKHandler sharedHandler] removeObserver:self forKeyPath:@"status"];
|
[[MatrixSDKHandler sharedHandler] removeObserver:self forKeyPath:@"status"];
|
||||||
|
@ -104,11 +108,24 @@ static ContactManager* sharedContactManager = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
[self saveMatrixIDsDict];
|
[self saveMatrixIDsDict];
|
||||||
|
[self saveDeviceContacts];
|
||||||
|
[self saveContactBookInfo];
|
||||||
|
|
||||||
// warn of the contacts list update
|
// warn of the contacts list update
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:kContactManagerContactsListRefreshNotification object:nil userInfo:nil];
|
[[NSNotificationCenter defaultCenter] postNotificationName:kContactManagerContactsListRefreshNotification object:nil userInfo:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// refresh the international phonenumber of the contacts
|
||||||
|
- (void)internationalizePhoneNumbers:(NSString*)countryCode {
|
||||||
|
NSArray* contactsSnapshot = self.contacts;
|
||||||
|
|
||||||
|
for(MXCContact* contact in contactsSnapshot) {
|
||||||
|
[contact internationalizePhonenumbers:countryCode];
|
||||||
|
}
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:kContactsDidInternationalizeNotification object:nil userInfo:nil];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)fullRefresh {
|
- (void)fullRefresh {
|
||||||
|
|
||||||
// check if the user allowed to sync local contacts
|
// check if the user allowed to sync local contacts
|
||||||
|
@ -162,7 +179,23 @@ static ContactManager* sharedContactManager = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch_async(processingQueue, ^{
|
dispatch_async(processingQueue, ^{
|
||||||
NSMutableArray* contactsList = [[NSMutableArray alloc] init];
|
|
||||||
|
// in case of cold start
|
||||||
|
// get the info from the file system
|
||||||
|
if (!lastSyncDate) {
|
||||||
|
// load cached contacts
|
||||||
|
[self loadDeviceContacts];
|
||||||
|
[self loadContactBookInfo];
|
||||||
|
|
||||||
|
// no local contact -> assume that the last sync date is useless
|
||||||
|
if (deviceContactByContactID.count == 0) {
|
||||||
|
lastSyncDate = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL contactBookUpdate = NO;
|
||||||
|
|
||||||
|
NSMutableArray* deletedContactIDs = [[deviceContactByContactID allKeys] mutableCopy];
|
||||||
|
|
||||||
// can list tocal contacts
|
// can list tocal contacts
|
||||||
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
|
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
|
||||||
|
@ -176,8 +209,28 @@ static ContactManager* sharedContactManager = nil;
|
||||||
CFIndex peopleCount = CFArrayGetCount(people);
|
CFIndex peopleCount = CFArrayGetCount(people);
|
||||||
|
|
||||||
for (index = 0; index < peopleCount; index++) {
|
for (index = 0; index < peopleCount; index++) {
|
||||||
|
|
||||||
contactRecord = (ABRecordRef)CFArrayGetValueAtIndex(people, index);
|
contactRecord = (ABRecordRef)CFArrayGetValueAtIndex(people, index);
|
||||||
[contactsList addObject:[[MXCContact alloc] initWithABRecord:contactRecord]];
|
|
||||||
|
NSString* contactID = [MXCContact contactID:contactRecord];
|
||||||
|
|
||||||
|
// the contact still exists
|
||||||
|
[deletedContactIDs removeObject:contactID];
|
||||||
|
|
||||||
|
if (lastSyncDate) {
|
||||||
|
// ignore unchanged contacts since the previous sync
|
||||||
|
CFDateRef lastModifDate = ABRecordCopyValue(contactRecord, kABPersonModificationDateProperty);
|
||||||
|
if (kCFCompareGreaterThan != CFDateCompare (lastModifDate, (__bridge CFDateRef)lastSyncDate, nil))
|
||||||
|
{
|
||||||
|
CFRelease(lastModifDate);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
CFRelease(lastModifDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
contactBookUpdate = YES;
|
||||||
|
// update the contact
|
||||||
|
[deviceContactByContactID setValue:[[MXCContact alloc] initWithABRecord:contactRecord] forKey:contactID];
|
||||||
}
|
}
|
||||||
|
|
||||||
CFRelease(people);
|
CFRelease(people);
|
||||||
|
@ -188,14 +241,28 @@ static ContactManager* sharedContactManager = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceContactsList = contactsList;
|
// some contacts have been deleted
|
||||||
|
for (NSString* contactID in deletedContactIDs) {
|
||||||
|
contactBookUpdate = YES;
|
||||||
|
[deviceContactByContactID removeObjectForKey:contactID];
|
||||||
|
}
|
||||||
|
|
||||||
|
// something has been modified in the device contact book
|
||||||
|
if (contactBookUpdate) {
|
||||||
|
[self saveDeviceContacts];
|
||||||
|
}
|
||||||
|
|
||||||
|
lastSyncDate = [NSDate date];
|
||||||
|
[self saveContactBookInfo];
|
||||||
|
|
||||||
|
NSMutableArray* deviceContacts = [[deviceContactByContactID allValues] mutableCopy];
|
||||||
|
|
||||||
if (mxHandler.mxSession) {
|
if (mxHandler.mxSession) {
|
||||||
[self manage3PIDS];
|
[self manage3PIDS];
|
||||||
} else {
|
} else {
|
||||||
// display what you could have read
|
// display what you could have read
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
contacts = deviceContactsList;
|
contacts = deviceContacts;
|
||||||
|
|
||||||
hasStatusObserver = YES;
|
hasStatusObserver = YES;
|
||||||
// wait that the mxSession is ready
|
// wait that the mxSession is ready
|
||||||
|
@ -213,17 +280,10 @@ static ContactManager* sharedContactManager = nil;
|
||||||
dispatch_async(processingQueue, ^{
|
dispatch_async(processingQueue, ^{
|
||||||
NSMutableArray* tmpContacts = nil;
|
NSMutableArray* tmpContacts = nil;
|
||||||
|
|
||||||
// initial sync
|
// update with the known dict 3PID -> matrix ID
|
||||||
if (!lastSyncDate) {
|
[self updateMatrixIDDeviceContacts];
|
||||||
// display the current device contacts
|
|
||||||
tmpContacts = deviceContactsList;
|
tmpContacts = [[deviceContactByContactID allValues] mutableCopy];
|
||||||
} else {
|
|
||||||
// update with the known dict 3PID -> matrix ID
|
|
||||||
[self updateMatrixIDDeviceContactsList];
|
|
||||||
|
|
||||||
tmpContacts = [deviceContactsList mutableCopy];
|
|
||||||
}
|
|
||||||
lastSyncDate = [NSDate date];
|
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
// stored self.contacts in the right thread
|
// stored self.contacts in the right thread
|
||||||
|
@ -268,9 +328,12 @@ static ContactManager* sharedContactManager = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) updateMatrixIDDeviceContactsList {
|
- (void) updateMatrixIDDeviceContacts {
|
||||||
|
|
||||||
|
NSArray* deviceContacts = [deviceContactByContactID allValues];
|
||||||
|
|
||||||
// update the contacts info
|
// update the contacts info
|
||||||
for(MXCContact* contact in deviceContactsList) {
|
for(MXCContact* contact in deviceContacts) {
|
||||||
[self updateContactMatrixIDs:contact];
|
[self updateContactMatrixIDs:contact];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -523,6 +586,8 @@ static ContactManager* sharedContactManager = nil;
|
||||||
#pragma mark - file caches
|
#pragma mark - file caches
|
||||||
|
|
||||||
static NSString *matrixIDsDictFile = @"matrixIDsDict";
|
static NSString *matrixIDsDictFile = @"matrixIDsDict";
|
||||||
|
static NSString *localContactsFile = @"localContacts";
|
||||||
|
static NSString *contactsBookInfoFile = @"contacts";
|
||||||
|
|
||||||
- (void)saveMatrixIDsDict
|
- (void)saveMatrixIDsDict
|
||||||
{
|
{
|
||||||
|
@ -579,5 +644,107 @@ static NSString *matrixIDsDictFile = @"matrixIDsDict";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) saveDeviceContacts {
|
||||||
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||||
|
NSString *documentsDirectory = [paths objectAtIndex:0];
|
||||||
|
NSString *dataFilePath = [documentsDirectory stringByAppendingPathComponent:localContactsFile];
|
||||||
|
|
||||||
|
if (deviceContactByContactID && (deviceContactByContactID.count > 0))
|
||||||
|
{
|
||||||
|
NSMutableData *theData = [NSMutableData data];
|
||||||
|
NSKeyedArchiver *encoder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:theData];
|
||||||
|
|
||||||
|
[encoder encodeObject:deviceContactByContactID forKey:@"deviceContactByContactID"];
|
||||||
|
|
||||||
|
[encoder finishEncoding];
|
||||||
|
|
||||||
|
[theData writeToFile:dataFilePath atomically:YES];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSFileManager *fileManager = [[NSFileManager alloc] init];
|
||||||
|
[fileManager removeItemAtPath:dataFilePath error:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) loadDeviceContacts {
|
||||||
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||||
|
NSString *documentsDirectory = [paths objectAtIndex:0];
|
||||||
|
NSString *dataFilePath = [documentsDirectory stringByAppendingPathComponent:localContactsFile];
|
||||||
|
|
||||||
|
NSFileManager *fileManager = [[NSFileManager alloc] init];
|
||||||
|
|
||||||
|
if ([fileManager fileExistsAtPath:dataFilePath])
|
||||||
|
{
|
||||||
|
// the file content could be corrupted
|
||||||
|
@try {
|
||||||
|
NSData* filecontent = [NSData dataWithContentsOfFile:dataFilePath options:(NSDataReadingMappedAlways | NSDataReadingUncached) error:nil];
|
||||||
|
|
||||||
|
NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:filecontent];
|
||||||
|
|
||||||
|
id object = [decoder decodeObjectForKey:@"deviceContactByContactID"];
|
||||||
|
|
||||||
|
if ([object isKindOfClass:[NSDictionary class]]) {
|
||||||
|
deviceContactByContactID = [object mutableCopy];
|
||||||
|
}
|
||||||
|
|
||||||
|
[decoder finishDecoding];
|
||||||
|
} @catch (NSException *exception) {
|
||||||
|
lastSyncDate = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!deviceContactByContactID) {
|
||||||
|
deviceContactByContactID = [[NSMutableDictionary alloc] init];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) saveContactBookInfo {
|
||||||
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||||
|
NSString *documentsDirectory = [paths objectAtIndex:0];
|
||||||
|
NSString *dataFilePath = [documentsDirectory stringByAppendingPathComponent:contactsBookInfoFile];
|
||||||
|
|
||||||
|
if (lastSyncDate)
|
||||||
|
{
|
||||||
|
NSMutableData *theData = [NSMutableData data];
|
||||||
|
NSKeyedArchiver *encoder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:theData];
|
||||||
|
|
||||||
|
[encoder encodeObject:lastSyncDate forKey:@"lastSyncDate"];
|
||||||
|
|
||||||
|
[encoder finishEncoding];
|
||||||
|
|
||||||
|
[theData writeToFile:dataFilePath atomically:YES];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSFileManager *fileManager = [[NSFileManager alloc] init];
|
||||||
|
[fileManager removeItemAtPath:dataFilePath error:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) loadContactBookInfo {
|
||||||
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||||
|
NSString *documentsDirectory = [paths objectAtIndex:0];
|
||||||
|
NSString *dataFilePath = [documentsDirectory stringByAppendingPathComponent:contactsBookInfoFile];
|
||||||
|
|
||||||
|
NSFileManager *fileManager = [[NSFileManager alloc] init];
|
||||||
|
|
||||||
|
if ([fileManager fileExistsAtPath:dataFilePath])
|
||||||
|
{
|
||||||
|
// the file content could be corrupted
|
||||||
|
@try {
|
||||||
|
NSData* filecontent = [NSData dataWithContentsOfFile:dataFilePath options:(NSDataReadingMappedAlways | NSDataReadingUncached) error:nil];
|
||||||
|
|
||||||
|
NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:filecontent];
|
||||||
|
|
||||||
|
lastSyncDate = [decoder decodeObjectForKey:@"lastSyncDate"];
|
||||||
|
|
||||||
|
[decoder finishDecoding];
|
||||||
|
} @catch (NSException *exception) {
|
||||||
|
lastSyncDate = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -24,7 +24,7 @@ extern NSString *const kMXCContactMatrixIdentifierUpdateNotification;
|
||||||
// the contactID is provided in parameter
|
// the contactID is provided in parameter
|
||||||
extern NSString *const kMXCContactThumbnailUpdateNotification;
|
extern NSString *const kMXCContactThumbnailUpdateNotification;
|
||||||
|
|
||||||
@interface MXCContact : NSObject
|
@interface MXCContact : NSObject<NSCoding>
|
||||||
|
|
||||||
// unique identifier
|
// unique identifier
|
||||||
@property (nonatomic, readonly) NSString * contactID;
|
@property (nonatomic, readonly) NSString * contactID;
|
||||||
|
@ -42,6 +42,9 @@ extern NSString *const kMXCContactThumbnailUpdateNotification;
|
||||||
// array of matrix identifiers
|
// array of matrix identifiers
|
||||||
@property (nonatomic, readonly) NSArray* matrixIdentifiers;
|
@property (nonatomic, readonly) NSArray* matrixIdentifiers;
|
||||||
|
|
||||||
|
// return the contact ID from native phonebook record
|
||||||
|
+ (NSString*)contactID:(ABRecordRef)record;
|
||||||
|
|
||||||
// create a contact from a local contact
|
// create a contact from a local contact
|
||||||
- (id)initWithABRecord:(ABRecordRef)record;
|
- (id)initWithABRecord:(ABRecordRef)record;
|
||||||
|
|
||||||
|
@ -57,4 +60,7 @@ extern NSString *const kMXCContactThumbnailUpdateNotification;
|
||||||
// check if the patterns can match with this contact
|
// check if the patterns can match with this contact
|
||||||
- (BOOL) matchedWithPatterns:(NSArray*)patterns;
|
- (BOOL) matchedWithPatterns:(NSArray*)patterns;
|
||||||
|
|
||||||
|
// internationalize the contact phonenumbers
|
||||||
|
- (void)internationalizePhonenumbers:(NSString*)countryCode;
|
||||||
|
|
||||||
@end
|
@end
|
|
@ -38,12 +38,16 @@ NSString *const kMXCContactThumbnailUpdateNotification = @"kMXCContactThumbnailU
|
||||||
|
|
||||||
@implementation MXCContact
|
@implementation MXCContact
|
||||||
|
|
||||||
|
+ (NSString*)contactID:(ABRecordRef)record {
|
||||||
|
return [NSString stringWithFormat:@"%d", ABRecordGetRecordID(record)];
|
||||||
|
}
|
||||||
|
|
||||||
- (id) initWithABRecord:(ABRecordRef)record {
|
- (id) initWithABRecord:(ABRecordRef)record {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
if (self) {
|
if (self) {
|
||||||
// compute a contact ID
|
// compute a contact ID
|
||||||
_contactID = [NSString stringWithFormat:@"%d", ABRecordGetRecordID(record)];
|
_contactID = [MXCContact contactID:record];
|
||||||
|
|
||||||
// use the contact book display name
|
// use the contact book display name
|
||||||
_displayName = (__bridge NSString*) ABRecordCopyCompositeName(record);
|
_displayName = (__bridge NSString*) ABRecordCopyCompositeName(record);
|
||||||
|
@ -238,6 +242,15 @@ NSString *const kMXCContactThumbnailUpdateNotification = @"kMXCContactThumbnailU
|
||||||
return matched;
|
return matched;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// internationalize the contact phonenumbers
|
||||||
|
- (void)internationalizePhonenumbers:(NSString*)countryCode {
|
||||||
|
for(MXCPhoneNumber* phonenumber in _phoneNumbers) {
|
||||||
|
[phonenumber internationalize:countryCode];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - getter/setter
|
||||||
|
|
||||||
- (BOOL) isMatrixContact {
|
- (BOOL) isMatrixContact {
|
||||||
return (nil != dummyField);
|
return (nil != dummyField);
|
||||||
}
|
}
|
||||||
|
@ -322,4 +335,35 @@ NSString *const kMXCContactThumbnailUpdateNotification = @"kMXCContactThumbnailU
|
||||||
return [self thumbnailWithPreferedSize:CGSizeMake(256, 256)];
|
return [self thumbnailWithPreferedSize:CGSizeMake(256, 256)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark NSCoding
|
||||||
|
|
||||||
|
- (id)initWithCoder:(NSCoder *)coder
|
||||||
|
{
|
||||||
|
_contactID = [coder decodeObjectForKey:@"contactID"];
|
||||||
|
_displayName = [coder decodeObjectForKey:@"displayName"];
|
||||||
|
|
||||||
|
_phoneNumbers = [coder decodeObjectForKey:@"phoneNumbers"];
|
||||||
|
_emailAddresses = [coder decodeObjectForKey:@"emailAddresses"];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)encodeWithCoder:(NSCoder *)coder {
|
||||||
|
|
||||||
|
[coder encodeObject:_contactID forKey:@"contactID"];
|
||||||
|
[coder encodeObject:_displayName forKey:@"displayName"];
|
||||||
|
|
||||||
|
if (_phoneNumbers) {
|
||||||
|
[coder encodeObject:_phoneNumbers forKey:@"phoneNumbers"];
|
||||||
|
} else {
|
||||||
|
[coder setNilValueForKey:@"phoneNumbers"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_emailAddresses) {
|
||||||
|
[coder encodeObject:_emailAddresses forKey:@"emailAddresses"];
|
||||||
|
} else {
|
||||||
|
[coder setNilValueForKey:@"emailAddresses"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
@interface MXCContactField : NSObject
|
@interface MXCContactField : NSObject<NSCoding>
|
||||||
|
|
||||||
// contact ID where the email has been found
|
// contact ID where the email has been found
|
||||||
@property (nonatomic, readonly) NSString *contactID;
|
@property (nonatomic, readonly) NSString *contactID;
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
@implementation MXCContactField
|
@implementation MXCContactField
|
||||||
|
|
||||||
- (void) fieldInit {
|
- (void)initFields {
|
||||||
// init members
|
// init members
|
||||||
_contactID = nil;
|
_contactID = nil;
|
||||||
_matrixID = nil;
|
_matrixID = nil;
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
if (self) {
|
if (self) {
|
||||||
[self fieldInit];
|
[self initFields];
|
||||||
_contactID = contactID;
|
_contactID = contactID;
|
||||||
_matrixID = matrixID;
|
_matrixID = matrixID;
|
||||||
}
|
}
|
||||||
|
@ -160,5 +160,22 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark NSCoding
|
||||||
|
|
||||||
|
- (id)initWithCoder:(NSCoder *)coder
|
||||||
|
{
|
||||||
|
if (self) {
|
||||||
|
[self initFields];
|
||||||
|
_contactID = [coder decodeObjectForKey:@"contactID"];
|
||||||
|
_matrixID = [coder decodeObjectForKey:@"matrixID"];
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)encodeWithCoder:(NSCoder *)coder {
|
||||||
|
[coder encodeObject:_contactID forKey:@"contactID"];
|
||||||
|
[coder encodeObject:_matrixID forKey:@"matrixID"];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -69,5 +69,24 @@
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
#pragma mark NSCoding
|
||||||
|
|
||||||
|
- (id)initWithCoder:(NSCoder *)coder {
|
||||||
|
self = [super initWithCoder:coder];
|
||||||
|
|
||||||
|
if (self) {
|
||||||
|
_type = [coder decodeObjectForKey:@"type"];
|
||||||
|
_emailAddress = [coder decodeObjectForKey:@"emailAddress"];
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)encodeWithCoder:(NSCoder *)coder {
|
||||||
|
[super encodeWithCoder:coder];
|
||||||
|
|
||||||
|
[coder encodeObject:_type forKey:@"type"];
|
||||||
|
[coder encodeObject:_emailAddress forKey:@"emailAddress"];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -22,9 +22,12 @@
|
||||||
// phonenumber info
|
// phonenumber info
|
||||||
@property (nonatomic, readonly) NSString *type;
|
@property (nonatomic, readonly) NSString *type;
|
||||||
@property (nonatomic, readonly) NSString *textNumber;
|
@property (nonatomic, readonly) NSString *textNumber;
|
||||||
|
@property (nonatomic, readonly) NSString *internationalPhoneNumber;
|
||||||
|
|
||||||
- (id)initWithTextNumber:(NSString*)textNumber type:(NSString*)aType contactID:(NSString*)aContactID matrixID:(NSString*)matrixID;
|
- (id)initWithTextNumber:(NSString*)textNumber type:(NSString*)aType contactID:(NSString*)aContactID matrixID:(NSString*)matrixID;
|
||||||
|
|
||||||
|
- (void)internationalize:(NSString*)countryCode;
|
||||||
|
|
||||||
- (BOOL)matchedWithPatterns:(NSArray*)patterns;
|
- (BOOL)matchedWithPatterns:(NSArray*)patterns;
|
||||||
|
|
||||||
@end
|
@end
|
|
@ -16,10 +16,8 @@
|
||||||
|
|
||||||
#import "MXCPhoneNumber.h"
|
#import "MXCPhoneNumber.h"
|
||||||
|
|
||||||
@interface MXCPhoneNumber() {
|
@interface MXCPhoneNumber ()
|
||||||
// for search purpose
|
@property (nonatomic, readonly) NSString *cleanedPhonenumber;
|
||||||
NSString* cleanedPhonenumber;
|
|
||||||
}
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation MXCPhoneNumber
|
@implementation MXCPhoneNumber
|
||||||
|
@ -28,9 +26,10 @@
|
||||||
self = [super initWithContactID:aContactID matrixID:matrixID];
|
self = [super initWithContactID:aContactID matrixID:matrixID];
|
||||||
|
|
||||||
if (self) {
|
if (self) {
|
||||||
_type = aType;
|
_type = aType ? aType : @"";
|
||||||
_textNumber = aTextNumber;
|
_textNumber = aTextNumber ? aTextNumber : @"" ;
|
||||||
cleanedPhonenumber = nil;
|
_cleanedPhonenumber = [MXCPhoneNumber cleanPhonenumber:_textNumber];
|
||||||
|
_internationalPhoneNumber = _cleanedPhonenumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -68,13 +67,9 @@
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cleanedPhonenumber) {
|
|
||||||
cleanedPhonenumber = [MXCPhoneNumber cleanPhonenumber:_textNumber];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (patterns.count > 0) {
|
if (patterns.count > 0) {
|
||||||
for(NSString *pattern in patterns) {
|
for(NSString *pattern in patterns) {
|
||||||
if (([_textNumber rangeOfString:pattern].location == NSNotFound) && ([cleanedPhonenumber rangeOfString:pattern].location == NSNotFound)) {
|
if (([_textNumber rangeOfString:pattern].location == NSNotFound) && ([_cleanedPhonenumber rangeOfString:pattern].location == NSNotFound)) {
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,4 +78,33 @@
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)internationalize:(NSString*)countryCode {
|
||||||
|
// need to plug to libphonenumber
|
||||||
|
_internationalPhoneNumber = _cleanedPhonenumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark NSCoding
|
||||||
|
|
||||||
|
- (id)initWithCoder:(NSCoder *)coder {
|
||||||
|
self = [super initWithCoder:coder];
|
||||||
|
|
||||||
|
if (self) {
|
||||||
|
_type = [coder decodeObjectForKey:@"type"];
|
||||||
|
_textNumber = [coder decodeObjectForKey:@"textNumber"];
|
||||||
|
_cleanedPhonenumber = [coder decodeObjectForKey:@"cleanedPhonenumber"];
|
||||||
|
_internationalPhoneNumber = [coder decodeObjectForKey:@"internationalPhoneNumber"];
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)encodeWithCoder:(NSCoder *)coder {
|
||||||
|
[super encodeWithCoder:coder];
|
||||||
|
|
||||||
|
[coder encodeObject:_type forKey:@"type"];
|
||||||
|
[coder encodeObject:_textNumber forKey:@"textNumber"];
|
||||||
|
[coder encodeObject:_cleanedPhonenumber forKey:@"cleanedPhonenumber"];
|
||||||
|
[coder encodeObject:_internationalPhoneNumber forKey:@"internationalPhoneNumber"];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
Loading…
Reference in a new issue