Developer Area

Changeset 389 for apps

Show
Ignore:
Timestamp:
06/11/09 10:52:53 (5 years ago)
Author:
henri
Message:

Refactored and added support for de-duplication of addressbook entries

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • apps/iphone/superbook/trunk/Classes/DotTelABMapper.m

    r382 r389  
    2828 
    2929#import "DotTelABMapper.h" 
     30 
     31// Define initialization and assignment of any ABMultiValue field that contains CFStringRefs 
     32// Saves a lot of typing 
     33#define SETNAPTR_INITIALIZATION NSError *err; \ 
     34                                                                CFErrorRef cferr = (CFErrorRef)err; \ 
     35                                                                NSString *service; \ 
     36                                                                service = [[rec serviceTypeArray] objectAtIndex:0]; \ 
     37                                                                NSString *lih; \ 
     38                                                                if ([[rec lihArray] count] == 0) \ 
     39                                                                        lih = @""; \ 
     40                                                                else \ 
     41                                                                        lih = [[rec lihArray] objectAtIndex:0]; \ 
     42                                                                ABMultiValueRef allexisting; \ 
     43                                                                ABMutableMultiValueRef allupdated; \ 
     44                                                                CFStringRef abLabel; \ 
     45                                                                CFStringRef abValue 
     46 
     47#define SETNAPTR_ASSIGN(kValType)       BOOL exists = NO; \ 
     48                                                                        for (CFIndex i = 0; i < ABMultiValueGetCount(allupdated); i++) { \ 
     49                                                                                CFStringRef aVal = (CFStringRef)ABMultiValueCopyValueAtIndex(allupdated, i); \ 
     50                                                                                if (aVal) { \ 
     51                                                                                        if (CFStringCompare(abValue, aVal, 0) == kCFCompareEqualTo) { \ 
     52                                                                                                exists = YES; \ 
     53                                                                                                CFRelease(aVal); \ 
     54                                                                                                break; \ 
     55                                                                                        } \ 
     56                                                                                        CFRelease(aVal); \ 
     57                                                                                } \ 
     58                                                                        } \ 
     59                                                                        if (!exists) { \ 
     60                                                                                ABMultiValueAddValueAndLabel(allupdated, abValue, abLabel, NULL); \ 
     61                                                                                BOOL res = ABRecordSetValue(abRecord, kValType, allupdated, &cferr); \ 
     62                                                                                if (res) [updatedProperties addObject:[NSNumber numberWithInt:kValType]]; \ 
     63                                                                        } \ 
     64                                                                        CFRelease(allupdated); \ 
     65                                                                        return NULL 
    3066 
    3167@interface DotTelABMapper (PrivateMethods) 
     
    213249 
    214250- (NSError *)setNaptrPhone:(RecordNaptr *)rec { 
    215         // ==== Begin initialization ====  
    216         NSError *err; 
    217         CFErrorRef cferr = (CFErrorRef)err; 
    218          
    219         NSString *lih; 
    220         if ([[rec lihArray] count] == 0)  
    221                 lih = @""; 
    222         else 
    223                 lih = [[rec lihArray] objectAtIndex:0]; 
    224  
    225         ABMultiValueRef allexisting;            // All existing entries of this type 
    226         ABMutableMultiValueRef allupdated;      // All updated entries of this type 
    227         CFStringRef abLabel;                            // Label 
    228         CFStringRef abValue;                            // Value 
    229         // ==== End initialization ====  
     251        SETNAPTR_INITIALIZATION; 
    230252         
    231253        // ==== Begin parsing ====  
     
    251273        // ==== End parsing ====  
    252274         
    253         // ==== Begin assignment ====  
    254         ABMultiValueAddValueAndLabel(allupdated, abValue, abLabel, NULL); 
    255         BOOL res = ABRecordSetValue(abRecord, kABPersonPhoneProperty, allupdated, &cferr); 
    256         if (res) { 
    257                 [updatedProperties addObject:[NSNumber numberWithInt:kABPersonPhoneProperty]]; 
    258         } 
    259         CFRelease(allupdated); 
    260         return NULL; 
     275        SETNAPTR_ASSIGN(kABPersonPhoneProperty); 
    261276} 
    262277 
    263278- (NSError *)setNaptrFax:(RecordNaptr *)rec { 
    264         // ==== Begin initialization ====  
    265         NSError *err; 
    266         CFErrorRef cferr = (CFErrorRef)err; 
    267          
    268         NSString *lih; 
    269         if ([[rec lihArray] count] == 0)  
    270                 lih = @""; 
    271         else 
    272                 lih = [[rec lihArray] objectAtIndex:0]; 
    273          
    274         ABMultiValueRef allexisting;            // All existing entries of this type 
    275         ABMutableMultiValueRef allupdated;      // All updated entries of this type 
    276         CFStringRef abLabel;                            // Label 
    277         CFStringRef abValue;                            // Value 
    278         // ==== End initialization ====  
     279        SETNAPTR_INITIALIZATION; 
    279280         
    280281        // ==== Begin parsing ====  
     
    296297        // ==== End parsing ====  
    297298         
    298         // ==== Begin assignment ====  
    299         ABMultiValueAddValueAndLabel(allupdated, abValue, abLabel, NULL); 
    300         BOOL res = ABRecordSetValue(abRecord, kABPersonPhoneProperty, allupdated, &cferr); 
    301         if (res) { 
    302                 [updatedProperties addObject:[NSNumber numberWithInt:kABPersonPhoneProperty]]; 
    303         } 
    304         CFRelease(allupdated); 
    305         return NULL; 
     299        SETNAPTR_ASSIGN(kABPersonPhoneProperty); 
    306300} 
    307301 
    308302- (NSError *)setNaptrEmail:(RecordNaptr *)rec { 
    309         // ==== Begin initialization ====  
    310         NSError *err; 
    311         CFErrorRef cferr = (CFErrorRef)err; 
    312          
    313         NSString *lih; 
    314         if ([[rec lihArray] count] == 0)  
    315                 lih = @""; 
    316         else 
    317                 lih = [[rec lihArray] objectAtIndex:0]; 
    318          
    319         ABMultiValueRef allexisting;            // All existing entries of this type 
    320         ABMutableMultiValueRef allupdated;      // All updated entries of this type 
    321         CFStringRef abLabel;                            // Label 
    322         CFStringRef abValue;                            // Value 
    323         // ==== End initialization ====  
     303        SETNAPTR_INITIALIZATION; 
    324304         
    325305        // ==== Begin parsing ====  
     
    343323        // ==== End parsing ====  
    344324         
    345         // ==== Begin assignment ====  
    346         ABMultiValueAddValueAndLabel(allupdated, abValue, abLabel, NULL); 
    347         BOOL res = ABRecordSetValue(abRecord, kABPersonEmailProperty, allupdated, &cferr); 
    348         if (res) { 
    349                 [updatedProperties addObject:[NSNumber numberWithInt:kABPersonEmailProperty]]; 
    350         } 
    351         CFRelease(allupdated); 
    352         return NULL; 
     325        SETNAPTR_ASSIGN(kABPersonEmailProperty); 
    353326} 
    354327 
    355328- (NSError *)setNaptrUrl:(RecordNaptr *)rec { 
    356         // ==== Begin initialization ====  
    357         NSError *err; 
    358         CFErrorRef cferr = (CFErrorRef)err; 
    359          
    360         NSString *lih; 
    361         if ([[rec lihArray] count] == 0)  
    362                 lih = @""; 
    363         else 
    364                 lih = [[rec lihArray] objectAtIndex:0]; 
    365          
    366         ABMultiValueRef allexisting;            // All existing entries of this type 
    367         ABMutableMultiValueRef allupdated;      // All updated entries of this type 
    368         CFStringRef abLabel;                            // Label 
    369         CFStringRef abValue;                            // Value 
    370         // ==== End initialization ====  
     329        SETNAPTR_INITIALIZATION; 
    371330         
    372331        // ==== Begin parsing ====  
     
    391350        // ==== End parsing ====  
    392351         
    393         // ==== Begin assignment ====  
    394         ABMultiValueAddValueAndLabel(allupdated, abValue, abLabel, NULL); 
    395         BOOL res = ABRecordSetValue(abRecord, kABPersonURLProperty, allupdated, &cferr); 
    396         if (res) { 
    397                 [updatedProperties addObject:[NSNumber numberWithInt:kABPersonURLProperty]]; 
    398         } 
    399         CFRelease(allupdated); 
    400         return NULL; 
     352        SETNAPTR_ASSIGN(kABPersonURLProperty); 
    401353} 
    402354 
    403355- (NSError *)setNaptrUrlOther:(RecordNaptr *)rec { 
    404         // ==== Begin initialization ====  
    405         NSError *err; 
    406         CFErrorRef cferr = (CFErrorRef)err; 
    407          
    408         NSString *service = [[rec serviceTypeArray] objectAtIndex:0]; 
    409         NSString *lih; 
    410         if ([[rec lihArray] count] == 0)  
    411                 lih = @""; 
    412         else 
    413                 lih = [[rec lihArray] objectAtIndex:0]; 
    414          
    415         ABMultiValueRef allexisting;            // All existing entries of this type 
    416         ABMutableMultiValueRef allupdated;      // All updated entries of this type 
    417         CFStringRef abLabel;                            // Label 
    418         CFStringRef abValue;                            // Value 
    419         // ==== End initialization ====  
     356        SETNAPTR_INITIALIZATION; 
    420357         
    421358        // ==== Begin parsing ====  
     
    441378        // ==== End parsing ====  
    442379         
    443         // ==== Begin assignment ====  
    444         ABMultiValueAddValueAndLabel(allupdated, abValue, abLabel, NULL); 
    445         BOOL res = ABRecordSetValue(abRecord, kABPersonURLProperty, allupdated, &cferr); 
    446         if (res) { 
    447                 [updatedProperties addObject:[NSNumber numberWithInt:kABPersonURLProperty]]; 
    448         } 
    449         CFRelease(allupdated); 
    450         return NULL; 
     380        SETNAPTR_ASSIGN(kABPersonURLProperty); 
    451381} 
    452382 
    453383- (NSError *)setNaptrIM:(RecordNaptr *)rec { 
    454         // ==== Begin initialization ====  
    455         NSError *err; 
    456         CFErrorRef cferr = (CFErrorRef)err; 
    457          
    458         NSString *service = [[rec serviceTypeArray] objectAtIndex:0]; 
    459         NSString *lih; 
    460         if ([[rec lihArray] count] == 0)  
    461                 lih = @""; 
    462         else 
    463                 lih = [[rec lihArray] objectAtIndex:0]; 
    464          
    465         ABMultiValueRef allexisting;            // All existing entries of this type 
    466         ABMutableMultiValueRef allupdated;      // All updated entries of this type 
     384        // NOTE: The simulator does NOT support IM fields. It silently discards them. 
     385        // IM fields are dictionaries, not strings. They need special handling. 
     386        SETNAPTR_INITIALIZATION; 
     387 
    467388        CFMutableDictionaryRef anIM = (CFMutableDictionaryRef)[NSMutableDictionary dictionaryWithCapacity:2];   // IM dictionary 
    468         CFStringRef abLabel;                            // Label 
    469         CFStringRef abValue;                    // Username Value 
    470         // ==== End initialization ====  
    471          
     389 
    472390        // ==== Begin parsing ====  
    473391        allexisting = ABRecordCopyValue(abRecord, kABPersonInstantMessageProperty); 
     
    508426        // ==== End parsing ====  
    509427         
    510         // ==== Begin assignment ====  
    511         ABMultiValueAddValueAndLabel(allupdated, anIM, abLabel, NULL); 
    512         BOOL res = ABRecordSetValue(abRecord, kABPersonInstantMessageProperty, allupdated, &cferr); 
    513         if (res) { 
    514                 [updatedProperties addObject:[NSNumber numberWithInt:kABPersonInstantMessageProperty]]; 
     428        // ==== Begin assignment ==== 
     429        // Check if an IM with the same service type and label already exists. If so, we replace it. 
     430        // This is different behavior than phone numbers and urls (i.e. CFStringRefs) 
     431        // Note that we only replace the first one of the same type and label 
     432        CFIndex existingIMServiceIndex = kCFNotFound; 
     433        for (CFIndex i = 0; i < ABMultiValueGetCount(allupdated); i++) { 
     434                CFDictionaryRef existingIM = (CFDictionaryRef)ABMultiValueCopyValueAtIndex(allupdated, i); 
     435                if (existingIM) { 
     436                        if (CFDictionaryGetValue(anIM, kABPersonInstantMessageServiceKey) == CFDictionaryGetValue(existingIM, kABPersonInstantMessageServiceKey)) { 
     437                                // Found a matching IM service type 
     438                                CFStringRef existingLabel = (CFStringRef)ABMultiValueCopyLabelAtIndex(allupdated, i); 
     439                                if (existingLabel) { 
     440                                        if (CFStringCompare(abLabel, existingLabel, 0) == kCFCompareEqualTo) { 
     441                                                // Found a matching label on top of the matching IM service type 
     442                                                ABMultiValueReplaceValueAtIndex(allupdated, anIM, i); 
     443                                                existingIMServiceIndex = i; 
     444                                                CFRelease(existingLabel); 
     445                                                CFRelease(existingIM); 
     446                                                break; 
     447                                        } else { 
     448                                                // There was a label but it didn't match, don't replace anything 
     449                                                CFRelease(existingLabel); 
     450                                        } 
     451                                } else { 
     452                                        // No label, but the service type matches. Let's replace and update the label 
     453                                        ABMultiValueReplaceValueAtIndex(allupdated, anIM, i); 
     454                                        ABMultiValueReplaceLabelAtIndex(allupdated, abLabel, i); 
     455                                        existingIMServiceIndex = i; 
     456                                        CFRelease(existingIM); 
     457                                        break;                                   
     458                                } 
     459                        } 
     460                        // At this point, the IM service type didn't match. Keep looping to look for a possible match 
     461                        CFRelease(existingIM); 
     462                } 
     463        } 
     464        if (existingIMServiceIndex == kCFNotFound) { 
     465                // Didn't find a matching IM service type and label 
     466                ABMultiValueAddValueAndLabel(allupdated, anIM, abLabel, NULL); 
     467                BOOL res = ABRecordSetValue(abRecord, kABPersonInstantMessageProperty, allupdated, &cferr); 
     468                if (res) { 
     469                        [updatedProperties addObject:[NSNumber numberWithInt:kABPersonInstantMessageProperty]]; 
     470                } 
     471                 
    515472        } 
    516473        CFRelease(allupdated); 
Telnic
Search This Site
Partners
Neustar
ICANN
Main site | WHOIS | Sell .tel | FAQ | Archived Site | About Telnic | Contact Us