如何像其他应用程序一样快速阅读地址簿(如Viber,Whatsapp ......)

ant*_*ntf 3 iphone client-server addressbook ios

我正在编写一个应用程序,我需要阅读地址簿数据来搜索一些感兴趣的联系人,类似于现在许多应用程序所做的事情(如Viber,Whatsapp,Tango ......).我需要进行匹配,因此我将数据发送到服务器并回复客户端哪些联系人在其设备上安装了相同的应用程序.

我的想法的逻辑或机制没有问题,我的问题是速度!我能够做我想要的但是这个过程需要27秒才能完成,iPhone4上有500个联系人.如果我们尝试Viber或Whatsapp(或任何类似的应用程序),在相同的设备上,该过程只需不到5秒.

我的方法很简单,我做一个for循环并读取所有内容.我怎么能做同样的事情,但比其他应用程序更快?

这是我使用的代码:

    //variable definitions
    ABAddressBookRef addressBook = ABAddressBookCreate();
    CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
    CFMutableArrayRef peopleMutable = CFArrayCreateMutableCopy(kCFAllocatorDefault, CFArrayGetCount(people), people);

    //sort the contents of the Mutable Array
    CFArraySortValues(peopleMutable, CFRangeMake(0, CFArrayGetCount(peopleMutable)), (CFComparatorFunction) ABPersonComparePeopleByName, (void*) ABPersonGetSortOrdering());

    //read the Address Book
    NSString *fullName, *number;
    ABRecordRef record = ABPersonCreate();
    ABMutableMultiValueRef multi;
    int contactID;
    int nameCount=0;//used to count the names in the string to send to server
    NSMutableString *strNamesToSend = [[NSMutableString alloc] init];

    for(CFIndex i=0; i< CFArrayGetCount(people); i++)
    {
        record = CFArrayGetValueAtIndex(people, i);
        multi = ABRecordCopyValue(record, kABPersonPhoneProperty);

        //Contact ID
        contactID = (int)ABRecordGetRecordID(record);

        //Full Name
        fullName = [NSString stringWithFormat:@"%@ %@", (NSString *)ABRecordCopyValue(record, kABPersonFirstNameProperty), (NSString *)ABRecordCopyValue(record, kABPersonLastNameProperty)];
        fullName = [fullName stringByReplacingOccurrencesOfString:@" (null)" withString:@""];

        //fill data into AddressBook Table
        if(dbOpen == SQLITE_OK)
        {
            //pure sqlite3 work to save the names in my app
        }

        //Get multiple numbers from each user (if any)
        for(CFIndex j=0; j<ABMultiValueGetCount(multi); j++)
        {
            number = (NSString *)ABMultiValueCopyValueAtIndex(multi, j);

            nameCount++;

            //fill data into AllNumbers Table
            if(dbOpen == SQLITE_OK)
            {
                 //another sqlite3 work to save the numbers
            }
        }

        //send to the server every 29 numbers so we don't send all the 500 numbers at once
        if(nameCount > 29)
        {
            //send to server
        }
Run Code Online (Sandbox Code Playgroud)

jni*_*nic 5

您是否尝试过分析代码?分析器应该能够快速识别代码的缓慢部分.

从一个非常简短的检查,我注意到你在每次迭代时计算数组大小而不是一次.将它移出你的循环:

int count = CFArrayGetCount(people);
for (CFIndex i = 0; i < count; i++)
Run Code Online (Sandbox Code Playgroud)

您没有详细说明您正在进行的SQL调用,但是您正在检查的事实SQLITE_OK意味着您每次都要通过循环打开数据库.如果是这种情况,您应该将此调用移到循环之外,而不是每次都打开数据库.

我注意到nameCount没有被重置,这意味着一旦它达到29,你的if案例将每次都被命中,导致大量的网络请求.

  • 哇,这真是一个强大的工具.我尝试过Time Profiler,虽然我不熟悉探测器的东西,但我看到有5或6个项目消耗了大量的时间,并且所有内容都有`sqlite3`!看起来我做得不好的是保存文档应用程序文件夹中的信息,这现在给我的洞察力,可能其他应用程序不存储这些信息(我存储的名称和所有联系人的数字地址簿).真的@jnic非常感谢这个提示,它可能解决了我的整个问题:)我将在我的程序中进行更改并发布结果. (2认同)