簡體   English   中英

通過字母組獲取聯系人

[英]Fetching contacts by alphabetical groups

我已經將所有的表格視圖設置為使用聯系人框架來獲取聯系人。 當前,我具有以下表格視圖:

在此處輸入圖片說明

我正在使用CNContactStore獲取聯系人。我能夠從聯系人中檢索所有想要的數據。

我創建了以下結構,其中包含一個ExpandableNames數組,其中每個ExpandableNames包含一個isExpanded布爾值和一個FavoritableContact數組。

struct ExpandableNames{
    var isExpanded: Bool
    var contacts: [FavoritableContact]
}

struct FavoritableContact {
    let contact: CNContact
    var hasFavorited: Bool
}

這樣,我聲明並初始化了以下數組:

var favoritableContacts = [FavoritableContact]()

以及:

var twoDimensionalArray = [ExpandableNames]()

初始化數組后,我創建了一個函數來獲取聯系人。

    private func fetchContacts(){

            let store = CNContactStore()

            store.requestAccess(for: (.contacts)) { (granted, err) in
                if let err = err{
                    print("Failed to request access",err)
                    return
                }

                if granted {
                    print("Access granted")
                     let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey]
                    let fetchRequest = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])
                    var favoritableContacts = [FavoritableContact]()

                    fetchRequest.sortOrder = CNContactSortOrder.userDefault

                    do {
                        try store.enumerateContacts(with: fetchRequest, usingBlock: { ( contact, error) -> Void in
                            favoritableContacts.append(FavoritableContact(contact: contact, hasFavorited: false))
                        })

                        let names = ExpandableNames(isExpanded: true, contacts: favoritableContacts)
                        self.twoDimensionalArray = [names]



                        DispatchQueue.main.async {
                            self.tableView.reloadData()
                        }
                    }
                    catch let error as NSError {
                        print(error.localizedDescription)
                    }


                }else{
                    print("Access denied")
                }
            }       

}

考慮到這一點,我是否可以分組獲取這些聯系人。 當我說組時,我的意思是從ContactsUI中按字母順序獲取聯系人,如下所示:

在此處輸入圖片說明

我嘗試了其他方法,但是我一直碰壁,我需要考慮以下事實:標准英語字母可能不是用戶首選的設備語言,變音符號,符號,數字等等。 因此,如果我可以從contactsUI檢索它,那就太好了。

感謝大伙們!

注意 :如果您需要更多詳細信息,請告訴我!

解決方案SWIFT 4

我能夠使用UILocalizedIndexedCollat​​ion類在rmaddy的幫助下找到解決方案。

以下代碼代表我的ConctactsVC:

import UIKit
import Contacts

class ContactsVC: UITableViewController {

    let cellID = "cellID"

    var contacts = [Contact]()
    var contactsWithSections = [[Contact]]()
    let collation = UILocalizedIndexedCollation.current() // create a locale collation object, by which we can get section index titles of current locale. (locale = local contry/language)
    var sectionTitles = [String]()

    private func fetchContacts(){

        let store = CNContactStore()

        store.requestAccess(for: (.contacts)) { (granted, err) in
            if let err = err{
                print("Failed to request access",err)
                return
            }

            if granted {
                print("Access granted")
                let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey]
                let fetchRequest = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])

                fetchRequest.sortOrder = CNContactSortOrder.userDefault

                do {
                    try store.enumerateContacts(with: fetchRequest, usingBlock: { ( contact, error) -> Void in

                        guard let phoneNumber = contact.phoneNumbers.first?.value.stringValue else {return}
                        self.contacts.append(Contact(givenName: contact.givenName, familyName: contact.familyName, mobile: phoneNumber))

                    })

                    for index in self.contacts.indices{

                        print(self.contacts[index].givenName)
                        print(self.contacts[index].familyName)
                        print(self.contacts[index].mobile)
                    }

                    self.setUpCollation()

                    DispatchQueue.main.async {
                        self.tableView.reloadData()
                    }
                }
                catch let error as NSError {
                    print(error.localizedDescription)
                }


            }else{
                print("Access denied")
            }
        }

    }

    override func viewDidLoad() {
        super.viewDidLoad()



        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(dimissContactsVC))
        navigationItem.title = "Contacts"
        navigationController?.navigationBar.prefersLargeTitles = true

        //Changing section index color
        self.tableView.sectionIndexColor = UIColor.red


        // need to register a custom cell
        tableView.register(ContactsCell.self, forCellReuseIdentifier: cellID)


         fetchContacts()

        //Test

//        let contact1 = Contact(name: "Anuska", mobile: "123434")
//
//        let contact2 = Contact(name: "Anuj Sinha", mobile: "2321234")
//
//        let contact3 = Contact(name: "Maria", mobile: "343434")
//
//        let contact4 = Contact(name: "Jacob", mobile: "34454545")
//
//        let contact5 = Contact(name: "Macculam", mobile: "455656")
//
//        let contact6 = Contact(name: "Sophia", mobile: "4567890")
//
//        self.contacts = [contact1, contact2, contact3, contact4, contact5, contact6]


    }

    override func viewWillAppear(_ animated: Bool) {
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }

    @objc func setUpCollation(){
        let (arrayContacts, arrayTitles) = collation.partitionObjects(array: self.contacts, collationStringSelector: #selector(getter: Contact.givenName))
        self.contactsWithSections = arrayContacts as! [[Contact]]
        self.sectionTitles = arrayTitles

        print(contactsWithSections.count)
        print(sectionTitles.count)
    }

    @objc func dimissContactsVC(){
        dismiss(animated: true, completion: nil)
    }


    override func numberOfSections(in tableView: UITableView) -> Int {
        return sectionTitles.count
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return contactsWithSections[section].count

    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //let cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath) as! ContactsCell
        let cell = ContactsCell(style: .subtitle, reuseIdentifier: cellID)

        cell.link = self // custom delegation

        let contact = contactsWithSections[indexPath.section][indexPath.row]
        cell.selectionStyle = .default
        cell.textLabel?.text = contact.givenName + " " + contact.familyName
        cell.detailTextLabel?.text = contact.mobile

        return cell
    }

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return sectionTitles[section]
    }

    //Changing color for the Letters in the section titles
    override func tableView(_ tableView: UITableView, willDisplayHeaderView view:UIView, forSection: Int) {
        if let headerTitle = view as? UITableViewHeaderFooterView {
            headerTitle.textLabel?.textColor = UIColor.red
        }
    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 44
    }

    override func sectionIndexTitles(for tableView: UITableView) -> [String]? {
        return sectionTitles
    }

}

extension UILocalizedIndexedCollation {
    //func for partition array in sections
    func partitionObjects(array:[AnyObject], collationStringSelector:Selector) -> ([AnyObject], [String]) {
        var unsortedSections = [[AnyObject]]()

        //1. Create a array to hold the data for each section
        for _ in self.sectionTitles {
            unsortedSections.append([]) //appending an empty array
        }
        //2. Put each objects into a section
        for item in array {
            let index:Int = self.section(for: item, collationStringSelector:collationStringSelector)
            unsortedSections[index].append(item)
        }
        //3. sorting the array of each sections
        var sectionTitles = [String]()
        var sections = [AnyObject]()
        for index in 0 ..< unsortedSections.count { if unsortedSections[index].count > 0 {
            sectionTitles.append(self.sectionTitles[index])
            sections.append(self.sortedArray(from: unsortedSections[index], collationStringSelector: collationStringSelector) as AnyObject)
            }
        }
        return (sections, sectionTitles)
    }
}

我還有一個名為Contact的模型文件:

@objc class Contact : NSObject {
    @objc var givenName: String!
    @objc var familyName: String!
    @objc var mobile: String!

    init(givenName: String, familyName: String, mobile: String) {
        self.givenName = givenName
        self.familyName = familyName
        self.mobile = mobile
    }
}

圖片:

在此處輸入圖片說明

我設法解決了這個問題。

//keys with fetching properties
NSArray *keys = @[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactEmailAddressesKey];
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys];

//Order contacts by Surname.
request.sortOrder = CNContactSortOrderFamilyName;

--OR YOU CAN--

//Order contacts by Name.
request.sortOrder = CNContactSortOrderGivenName;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM