2

我已经阅读了使用的联系方式CNContact.framework,如下

let contactStore = CNContactStore()
let keys = [CNContactEmailAddressesKey,
            CNContactPhoneNumbersKey,
            CNContactFormatter.descriptorForRequiredKeys(for: .fullName),
            CNContactThumbnailImageDataKey] as! [CNKeyDescriptor]

// The container means
// that the source the contacts from, such as Exchange and iCloud
var allContainers: [CNContainer] = []
do {
     allContainers = try contactStore.containers(matching: nil)

     // Loop the containers
     for container in allContainers {
          let fetchPredicate = CNContact.predicateForContactsInContainer(withIdentifier: container.identifier)
          do {
               let containerResults = try contactStore.unifiedContacts(matching: fetchPredicate, keysToFetch: keys)

               for contact in containerResults {
                     // iterating over contact
               }

               print("Saving into core data completed")

             } catch {
               print("Error fetching results for container")
             }
      }


   } catch {
       print("Error fetching containers")
   }
}

在上面的代码中,我一次读取了所有的联系人。假设我有 10000 个联系人,所有 10K 联系人将立即加载到内存中。有什么方法可以让我通过提供offsetand来获取联系人limit

假设我想从中获取联系人0-100,然后101-200...

提前致谢。

4

2 回答 2

1

我一直面临同样的问题,我开始研究以下功能enumerateContacts(with:usingBlock:)。根据文档,此方法对您的用例很有趣,因为它“可用于获取所有联系人,而无需一次将所有联系人保存在内存中,因为这很昂贵”。

当提取谓词匹配时,将调用该块,并且如果我是正确的,则每个联系人一一返回,但一次一个,避免在“旧”电话上处理大型联系人数据库时可能发生的内存饱和。

例子:

var listOfContacts = [CNContact]()
var i = 0
do {
   try store.enumerateContacts(with: fetchRequest, usingBlock: { (contact, cursor) in
   listOfContacts.append(contact)
   if i % 100 == 0 {
     cursor.pointee = true // Stop the enumerate
     // do something with the contacts present in listOfContacts
     // first iteration will contain 101 contacts ;-)
     // once done, just set pointee to false to resume the enumeration where you left it
     listOfContacts.removeAll() // clear the array to free some memory
     cursor.pointee = false
   }
   )}
} catch {
   NSLog("Error: \(error.localizedDescription)")
}

苹果文档:https ://developer.apple.com/documentation/contacts/cncontactstore/1402849-enumeratecontacts

于 2019-02-19T05:38:35.760 回答
1

只要打电话enumerateContacts(with:usingBlock:)。它一次只给你一个联系人,所以你可以自由地对他们做你喜欢的事;它为stop您的块提供了一个参数,以便您可以随时停止接收联系人。

例如,您可以第一次调用它,读取 100 个联系人,然后停止。然后你第二次调用它,跳过前 100 个联系人(即返回以便继续循环),阅读下 100 个联系人,然后停止。等等。

于 2019-02-18T03:03:45.187 回答