iosswift3cncontactstorecontacts-framework

Merge duplicate CNCONTACT array swift 3 contacts framework


I did find duplicate contacts list from this method , now i'm stuck in merging the duplicates, any idea how i can do this.

I fetched duplicate using this code Referenced from previous question.

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 }

Solution

  • If you followed my previous answer for fetching duplicates list after you can use this code to merge duplicates.

    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
    
        }
    }
    

    This approach will take quite a memory so I suggest, use this approach as a reference.