【问题标题】:Merge duplicate CNCONTACT array swift 3 contacts framework合并重复的 CNCONTACT 数组 swift 3 联系人框架
【发布时间】:2017-09-02 19:22:40
【问题描述】:

我确实从这个方法中找到了重复的联系人列表,现在我被困在合并重复项中,不知道我该怎么做。

我使用从上一个问题引用的此代码获取了重复项。

let formatter = CNContactFormatter()
formatter.style = .fullName

let keys = [CNContactIdentifierKey as CNKeyDescriptor, CNContactFormatter.descriptorForRequiredKeys(for: .fullName)]
let request = CNContactFetchRequest(keysToFetch: keys)
var contactsByName = [String: [CNContact]]()
try! self.store.enumerateContacts(with: request) { contact, stop in
    guard let name = formatter.string(from: contact) else { return }
    contactsByName[name] = (contactsByName[name] ?? []) + [contact]   // or in Swift 4, `contactsByName[name, default: []].append(contact)`
}
let duplicates = contactsByName.filter { $1.count > 1 }

【问题讨论】:

    标签: ios swift3 cncontactstore contacts-framework


    【解决方案1】:

    如果您在使用此代码合并重复项之后按照我之前的回答获取重复项列表。

    func mergeAllDuplicates() -> CNContact {
    
        let duplicates: [Array<CNContact>] = //Array of Duplicates Contacts
    
        for item in duplicates {
    
            // CNCONTACT PROPERTIES
    
            var namePrefix: [String] = [String]()
            var givenName: [String] = [String]()
            var middleName: [String] = [String]()
            var familyName: [String] = [String]()
            var previousFamilyName: [String] = [String]()
            var nameSuffix: [String] = [String]()
            var nickname: [String] = [String]()
            var organizationName: [String] = [String]()
            var departmentName: [String] = [String]()
            var jobTitle: [String] = [String]()
            var phoneNumbers: [CNPhoneNumber] = [CNPhoneNumber]()
            var emailAddresses: [NSString] = [NSString]()
            var postalAddresses: [CNPostalAddress] = [CNPostalAddress]()
            var urlAddresses: [NSString] = [NSString]()
    
            var contactRelations: [CNContactRelation] = [CNContactRelation]()
            var socialProfiles: [CNSocialProfile] = [CNSocialProfile]()
            var instantMessageAddresses: [CNInstantMessageAddress] = [CNInstantMessageAddress]()
    
            // Filter
            for items in item {
                namePrefix.append(items.namePrefix)
                givenName.append(items.givenName)
                middleName.append(items.middleName)
                familyName.append(items.familyName)
                previousFamilyName.append(items.previousFamilyName)
                nameSuffix.append(items.nameSuffix)
                nickname.append(items.nickname)
                organizationName.append(items.organizationName)
                departmentName.append(items.departmentName)
                jobTitle.append(items.jobTitle)
    
                for number in items.phoneNumbers {
                    phoneNumbers.append(number.value)
                }
                for email in items.emailAddresses {
                    emailAddresses.append(email.value)
                }
                for postal in items.postalAddresses {
                    postalAddresses.append(postal.value)
                }
                for url in items.urlAddresses {
                    urlAddresses.append(url.value)
                }
                for relation in items.contactRelations {
                    contactRelations.append(relation.value)
                }
                for social in items.socialProfiles {
                    socialProfiles.append(social.value)
                }
                for message in items.instantMessageAddresses {
                    instantMessageAddresses.append(message.value)
                }
    
            }
    
            let newContact = CNMutableContact()
            newContact.namePrefix = Array(Set(namePrefix))[0]
            newContact.givenName = Array(Set(givenName))[0]
            newContact.middleName = Array(Set(middleName))[0]
            newContact.familyName = Array(Set(familyName))[0]
            newContact.previousFamilyName = Array(Set(previousFamilyName))[0]
            newContact.nameSuffix = Array(Set(nameSuffix))[0]
            newContact.nickname = Array(Set(nickname))[0]
            newContact.organizationName = Array(Set(namePrefix))[0]
            newContact.departmentName = Array(Set(namePrefix))[0]
            newContact.jobTitle = Array(Set(namePrefix))[0]
            for item in Array(Set(phoneNumbers)) {
                newContact.phoneNumbers.append(CNLabeledValue(label: CNLabelHome, value: item))
            }
            for item in Array(Set(emailAddresses)) {
                newContact.emailAddresses.append(CNLabeledValue(label: CNLabelHome, value: item))
            }
            for item in Array(Set(postalAddresses)) {
                newContact.postalAddresses.append(CNLabeledValue(label: CNLabelHome, value: item))
            }
            for item in Array(Set(urlAddresses)) {
                newContact.urlAddresses.append(CNLabeledValue(label: CNLabelHome, value: item))
            }
            for item in Array(Set(contactRelations)) {
                newContact.contactRelations.append(CNLabeledValue(label: CNLabelHome, value: item))
            }
            for item in Array(Set(socialProfiles)) {
                newContact.socialProfiles.append(CNLabeledValue(label: CNLabelHome, value: item))
            }
            for item in Array(Set(instantMessageAddresses)) {
                newContact.instantMessageAddresses.append(CNLabeledValue(label: CNLabelHome, value: item))
            }
    
            return newContact
    
        }
    }
    

    这种方法会占用大量内存,所以我建议,以这种方法作为参考。

    【讨论】:

    • 谢谢,我试试。
    【解决方案2】:

    我稍微修改了一下。也许它有帮助..

    extension Array where Element == String {
    
        var bestElement: String? {
            var options: [String : Int] = [:]
    
            for element in self {
                if let result = options[element] {
                    options[element] = result + 1
                } else {
                    options[element] = 1
                }
            }
    
            return options.sorted { $0.1 > $1.1 }.first?.key
        }
    }
    
    
    static func merge(duplicates: [CNContact]) -> CNContact {
        // EMPTY CNCONTACT PROPERTIES
        var givenName: [String] = []
        var familyName: [String] = []
        var organizationName: [String] = []
        var notes: [String] = []
    
        var phoneNumbers: [CNLabeledValue<CNPhoneNumber>] = []
        var emailAddresses: [CNLabeledValue<NSString>] = []
        var postalAddresses: [CNLabeledValue<CNPostalAddress>] = []
        var urlAddresses: [CNLabeledValue<NSString>] = []
    
        // COLLECT VALUES
        for contact in duplicates {
            givenName.append(contact.givenName)
            familyName.append(contact.familyName)
            organizationName.append(contact.organizationName)
            notes.append(contact.note)
    
            contact.phoneNumbers.forEach { phoneNumbers.append($0) }
            contact.emailAddresses.forEach { emailAddresses.append($0) }
            contact.postalAddresses.forEach { postalAddresses.append($0) }
            contact.urlAddresses.forEach { urlAddresses.append($0) }
        }
    
        // MERGE TO NEW CONTACT
        let newContact = CNMutableContact()
        newContact.givenName = givenName.bestElement ?? ""
        newContact.familyName = familyName.bestElement ?? ""
        newContact.organizationName = organizationName.bestElement ?? ""
        newContact.note = notes.joined(separator: "\n")
    
        newContact.phoneNumbers = phoneNumbers
        newContact.emailAddresses = emailAddresses
        newContact.postalAddresses = postalAddresses
        newContact.urlAddresses = urlAddresses
    
        return newContact
    }
    

    【讨论】:

      【解决方案3】:

      阅读你的函数时我问自己两件事。

      1. newContact.phoneNumbers:您似乎附加了 2 个联系人的所有号码。如果 2 个重复的联系人具有相同的号码,那么 newContact 将在其列表中具有相同的号码两次,对吧?

      2. 感觉您正在创建的 newContact 正在丢失大量信息。像昵称或前缀(医生等)。

      无论如何感谢这个紧凑的代码:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多