Цель c алгоритмом импорта адресной книги со многими контактами

Мое приложение читает Iphone AddressBook и для каждого контакта получает электронную почту и номера телефонов. После этого процесса я сохраняю эту информацию в своей базе данных и создаю объект, который храню в NSMutableArray для следующей цели. Я выполняю эту операцию только при первом запуске приложения пользователем. Когда у меня небольшая адресная книга ( < 500 контактов), это работает как чудо, и у меня разумное время ожидания (около 1 минуты), но с большим количеством контактов ( > 2000) у меня чрезмерное время ожидания и плохая производительность (около 3,4 минуты). Хотя эта задача выполняется в фоновом потоке, существует какой-либо способ оптимизировать этот этап импорта (возможно, импорт нескольких контактов одновременно?).

Это мой код для запуска процесса импорта:

-(void)importaContatti:(int32_t)lastIDContatto {

    [self beginBackgroundUpdateTask:&importContattiTaskIdentifier];
    ABAddressBookRef addressBook;    

    if ([[UIDevice currentDevice].systemVersion floatValue] >= 6.0) {        
        addressBook = ABAddressBookCreateWithOptions(NULL, NULL);        
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);
            ABAddressBookRequestAccessWithCompletion(addressBook,
                                             ^(bool granted, CFErrorRef error){
                                                 dispatch_semaphore_signal(sema);
                                             });

            dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
   } else {        
      addressBook = ABAddressBookCreate();
   }

   CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
   CFIndex nPeople      = ABAddressBookGetPersonCount(addressBook);

   if(nPeople == 0) {
      [[Database getIstance]insertBGPhoneData:@"importContatti" val:@"1"];
      CFRelease(addressBook);
      [self endBackgroundUpdateTask:&importContattiTaskIdentifier];
      return;
   }

   for ( int i = 0; i < nPeople; i++ ) {        
       ABRecordRef ref  = CFArrayGetValueAtIndex( allPeople, i );
       int32_t idIphone = ABRecordGetRecordID(ref);
       if(idIphone <= lastIDContatto) {
           continue;
       }        
       Contatto *c = [Contatto buildContattoFromRubricaIphone:&ref];        
       CFRelease(ref);        
       c = NULL;        
       [[Database getIstance]insertBGPhoneData:@"lastImportContatto" val:[NSString stringWithFormat:@"%d", idIphone ]];

   }

   [[Database getIstance]insertBGPhoneData:@"importContatti" val:@"1"];
   if(allPeople) {
       CFRelease(allPeople);
   }

  [self endBackgroundUpdateTask:&importContattiTaskIdentifier];    
} 

И это код для процесса импорта:

+(Contatto *)buildContattoFromRubricaIphone:(ABRecordRef *)ref {
    int32_t idIphone    = ABRecordGetRecordID(*ref);    
    Contatto *c         = [Contatto create];    
    CFStringRef nome    = ABRecordCopyValue(*ref, kABPersonFirstNameProperty);
    CFStringRef cognome = ABRecordCopyValue(*ref, kABPersonLastNameProperty);
    NSString *alias     = [[Utils getIstance]buildAlias:(__bridge NSString *)nome cognome:(__bridge NSString *)cognome];

    c.rubrica2 = [Rubrica2 build:0 idIphone:idIphone alias:alias img:NULL stato:ATTIVO jidPreferito:0 mergedWith:0 imgUpdated:0 personalStatus:0 xmppStatus:@"" xmppMood:NESSUNO xmppDisponibilita:@""];
    if(nome) {        
        CFRelease(nome);
    }

    if(cognome) {
        CFRelease(cognome);
    }

    [c.rubrica2 save];

    Rubrica_TEL *telForAlias   = NULL;
    Rubrica_MAIL *mailForAlias = NULL;

    for(NSString *numeroTelefono in [Contatto getNumeriContattoFromRubricaIphone:ref]) {

        Rubrica_TEL *tel = [Rubrica_TEL build:0 idRubrica:c.rubrica2.ID telefono:numeroTelefono tipo:0 stato:ATTIVO prevMerged:0];

        [tel saveWithNotification:false];

        if(telForAlias == NULL) {
            telForAlias = tel;
        }

        [c add:tel];
    }

    for(NSString *stringMail in [Contatto getEmailFromRubricaIphone:ref]) {

        Rubrica_MAIL *mail = [Rubrica_MAIL build:0 rubricaID:c.rubrica2.ID mailID:stringMail mailAlias:alias];

        [mail saveWithNotification:false];

        if(mailForAlias == NULL) {
           mailForAlias = mail;
        }

        [c add:mail];
    }


    if([c.rubrica2.alias length] == 0) {

        if(telForAlias != NULL) {
            c.rubrica2.alias = telForAlias.telefono;
        } else if(mailForAlias != NULL) {
            c.rubrica2.alias = mailForAlias.mail;
        }

        if([c.rubrica2.alias length] > 0) {
            [c.rubrica2 save];
        }
    }

return c;
}

С этим методом я получаю телефон от контакта адресной книги (электронная почта подобна):

+(NSMutableArray *)getNumeriContattoFromRubricaIphone:(ABRecordRef *)ref {
    NSMutableArray *result = [[NSMutableArray alloc]init];
    ABMultiValueRef *phones = ABRecordCopyValue(*ref, kABPersonPhoneProperty);


    for(CFIndex j = 0; j < ABMultiValueGetCount(phones); j++) {
        CFStringRef phoneNumberRef = ABMultiValueCopyValueAtIndex(phones, j);
        NSString *phoneNumber = (__bridge NSString *)phoneNumberRef;
        if(phoneNumber != NULL) {
            phoneNumber = [[Utils getIstance]formatE164:phoneNumber];
            [result addObject:phoneNumber];
        }

        if(phoneNumberRef) {
            CFRelease(phoneNumberRef);
        }

    }

    if(phones) {
        CFRelease(phones);
    }

    return result;
}

0 ответов

Другие вопросы по тегам