Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何从没有筛选器的设备检索所有CNContactStore_Ios_Swift_Cncontact - Fatal编程技术网

Ios 如何从没有筛选器的设备检索所有CNContactStore

Ios 如何从没有筛选器的设备检索所有CNContactStore,ios,swift,cncontact,Ios,Swift,Cncontact,我正在尝试插入var联系人:[CNContact]=[] var store=CNContactStore()但是我没有找到这个作业的正确代码,我找到了这个函数,我需要给它一个名称 func findContactsWithName(name: String) { AppDelegate.sharedDelegate().checkAccessStatus({ (accessGranted) -> Void in if accessGranted {

我正在尝试插入
var联系人:[CNContact]=[]
var store=CNContactStore()
但是我没有找到这个作业的正确代码,我找到了这个函数,我需要给它一个名称

func findContactsWithName(name: String) {
    AppDelegate.sharedDelegate().checkAccessStatus({ (accessGranted) -> Void in
        if accessGranted {
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                do {
                    let predicate: NSPredicate = CNContact.predicateForContactsMatchingName(name)
                    let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactBirthdayKey, CNContactViewController.descriptorForRequiredKeys()]
                    self.contacts = try self.store.unifiedContactsMatchingPredicate(predicate, keysToFetch:keysToFetch)


                    self.tableView.reloadData()
                }
                catch {
                    print("Unable to refetch the selected contact.")
                }
            })
        }
    })
}

我想插入所有的记录,而不仅仅是一个名字相等的记录,更新

根据OP的评论,请尝试使用以下基于CNContactFetchRequest的API来检索所有不带过滤器的联系人。我在后台线程上运行此命令,以减少任何可能的问题—大量联系人

func findContactsOnBackgroundThread ( completionHandler:(contacts:[CNContact]?)->()) {

        dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in

            let keysToFetch = [CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName),CNContactPhoneNumbersKey] //CNContactIdentifierKey
            let fetchRequest = CNContactFetchRequest( keysToFetch: keysToFetch)
            var contacts = [CNContact]()
            CNContact.localizedStringForKey(CNLabelPhoneNumberiPhone)

            fetchRequest.mutableObjects = false
            fetchRequest.unifyResults = true
            fetchRequest.sortOrder = .UserDefault

            let contactStoreID = CNContactStore().defaultContainerIdentifier()
            print("\(contactStoreID)")


            do {

                try CNContactStore().enumerateContactsWithFetchRequest(fetchRequest) { (contact, stop) -> Void in
                    //do something with contact
                    if contact.phoneNumbers.count > 0 {
                        contacts.append(contact)
                    }

                }
            } catch let e as NSError {
                print(e.localizedDescription)
            }

            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                completionHandler(contacts: contacts)

            })
        })
    }
一般来说,在使用类时,您通常会将谓词设置为nil以检索所有联系人,而不是像代码中所描述的那样

注意

如果要使用现有API,我建议将谓词设置为true:

 NSPredicate(value: true)
这将使所有联系人返回。如果这不起作用,考虑切换到CNCtTractFutChestAPI API来枚举联系人。在这种情况下,您可以将谓词设置为nil以获取所有联系人(使用cnconctfetchrequest)

以下是修改现有方法的方式:

func findContacts()->[CNContact] {
        AppDelegate.sharedDelegate().checkAccessStatus({ (accessGranted) -> Void in
            if accessGranted {
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    do {
                        let predicate: NSPredicate = NSPredicate(value: true)
                        let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactBirthdayKey, CNContactViewController.descriptorForRequiredKeys()]
                        self.contacts = try self.store.unifiedContactsMatchingPredicate(predicate, keysToFetch:keysToFetch)


                        self.tableView.reloadData()
                    }
                    catch {
                        print("Unable to refetch the selected contact.")
                    }
                })
            }
        })
    }
以及使用:

let contacts = findContacts()
苹果有一个更简单的例子:

let store = CNContactStore()
let contacts = try store.unifiedContactsMatchingPredicate(CNContact.predicateForContactsMatchingName("Appleseed"), keysToFetch:[CNContactGivenNameKey, CNContactFamilyNameKey])
对于您的用例,您可以尝试这样修改Apple示例:

//Use the reference to look up additional keys constants that you may want to fetch
let store = CNContactStore()
let contacts = try store.unifiedContactsMatchingPredicate(NSPredicate(value: true), keysToFetch:[CNContactGivenNameKey, CNContactFamilyNameKey])

修改了Tommie C对XCode 8和Swift 3.0的回答

func findContactsOnBackgroundThread ( completionHandler:@escaping (_ contacts:[CNContact]?)->()) {

    DispatchQueue.global(qos: .userInitiated).async(execute: { () -> Void in

        let keysToFetch = [CNContactFormatter.descriptorForRequiredKeys(for: .fullName),CNContactPhoneNumbersKey] as [Any] //CNContactIdentifierKey
        let fetchRequest = CNContactFetchRequest( keysToFetch: keysToFetch as! [CNKeyDescriptor])
        var contacts = [CNContact]()
        CNContact.localizedString(forKey: CNLabelPhoneNumberiPhone)

        if #available(iOS 10.0, *) {
            fetchRequest.mutableObjects = false
        } else {
            // Fallback on earlier versions
        }
        fetchRequest.unifyResults = true
        fetchRequest.sortOrder = .userDefault

        let contactStoreID = CNContactStore().defaultContainerIdentifier()
        print("\(contactStoreID)")


        do {

            try CNContactStore().enumerateContacts(with: fetchRequest) { (contact, stop) -> Void in
                //do something with contact
                if contact.phoneNumbers.count > 0 {
                    contacts.append(contact)
                }

            }
        } catch let e as NSError {
            print(e.localizedDescription)
        }

        DispatchQueue.main.async(execute: { () -> Void in
            completionHandler(contacts)

        })
    })
} 

override func viewDidLoad() {
    findContactsOnBackgroundThread { (contacts) in
            self.contactsList = contacts
            self.tableView.reloadData()
        }
}
///要获取的默认密钥描述符
public var defaultFetchKeys:[String]=[CNContactGivenNameKey,
CNContactFamilyNameKey,
CNContactPhoneNumbersKey,
CNContactImageDataAvailableKey,
CNContactThumbnailImageDataKey]
/**
从用户的设备获取联系人
-参数sortOrder:应使用的排序顺序。默认无。
-返回:联系人列表
*/
public func fetchContacts(带有排序顺序:CNContactSortOrder=.givenName,
qos:DispatchQoS.QoSClass=.background)->Promise
{
返回承诺{盖章
DispatchQueue.global(qos:qos).async{
let store=CNContactStore()
变量触点=[触点]()
///用于解析和格式化数字的`PhoneNumberKit`对象(昂贵!)
设phoneNumberKit=phoneNumberKit()
let request=CNContactFetchRequest(keystefetch:self.defaultFetchKeys作为[CNKeyDescriptor])
request.sortOrder=sortOrder
request.unifyResults=true
做{
尝试存储。枚举联系人(with:request){contact,u
如果let user=Contact(Contact:Contact,kit:phoneNumberKit){
contacts.append(用户)
}
}
DispatchQueue.main.async{
密封(触点)
}
}抓住{
DispatchQueue.main.async{
密封。拒绝(错误)
}
}
}
}
}

我也在使用
PhoneNumberKit
来标准化所有数字,并
PromiseKit
来链接我的请求,但你几乎可以根据需要进行调整。

由于未捕获的异常“CNInvalidPredicateException”,我正在终止应用程序,原因:“谓词TRUEPREDICATE不是有效的联系人predicat@shaharnakash-请参阅提供的CNContactFetchRequest示例。请让我知道这在您的情况下是否有效?C现在可以了,我按照您的建议使用let fetchRequest=CNContactFetchRequest(keystefetch:keystefetch),现在一切都很完美:)嘿,Tommie!我刚刚用我的朋友iPhone运行了这段代码,我们只获得了整个联系人的10%。你知道这是什么原因吗?或者,无论来源如何,我们如何才能收到完整的联系人列表?@RoiMulia-我不确定您何时何地调用此代码,但请注意,在窗口事件等位置调用后台线程可能会导致Apple框架使用的竞争线程出现问题。我会尝试从viewDidLoad或在某些操作上调用代码,但请记住线程可能会导致争用条件。另外,请确保使用统一联系人设置。。。也可能是其他的事情,没有更多的背景我就说不出来。如果这些建议对您有帮助,请告诉我。您好,下面的代码行将给出您的姓名、姓氏、生日。**如果要检索联系人的所有详细信息,请使用keystefetch=[CNContactGivenNameKey、CNContactFamilyNameKey、CNContactBirthdayKey、CNContactViewController.descriptorForRequiredKeys()]**如何获取?。
/// The default key descriptors to fetch
public var defaultFetchKeys: [String] = [CNContactGivenNameKey,
                                         CNContactFamilyNameKey,
                                         CNContactPhoneNumbersKey,
                                         CNContactImageDataAvailableKey,
                                         CNContactThumbnailImageDataKey]

/**
     Fetch contacts from the user's device

     - parameter sortOrder: The sort order that should be used. Default none.
     - returns: A list of contacts
     */
    public func fetchContacts(withSortOrder sortOrder: CNContactSortOrder = .givenName,
                              qos: DispatchQoS.QoSClass = .background) -> Promise<[Contact]>
    {

        return Promise { seal in

            DispatchQueue.global(qos: qos).async {

                let store = CNContactStore()
                var contacts = [Contact]()

                /// A `PhoneNumberKit` object used to parse and format numbers (expensive!)
                let phoneNumberKit = PhoneNumberKit()

                let request = CNContactFetchRequest(keysToFetch: self.defaultFetchKeys as [CNKeyDescriptor])
                request.sortOrder = sortOrder
                request.unifyResults = true

                do {

                    try store.enumerateContacts(with: request) { contact, _ in

                        if let user = Contact(contact: contact, kit: phoneNumberKit) {
                            contacts.append(user)
                        }

                    }

                    DispatchQueue.main.async {
                        seal.fulfill(contacts)
                    }

                } catch {

                    DispatchQueue.main.async {
                        seal.reject(error)
                    }

                }

            }

        }

    }