2

how can I remove duplicate Contact from my table view when tap OK alert button?

Here's my findDuplicateContacts()

@objc fileprivate func findDuplicateContacts() {
    let keys = [CNContactIdentifierKey as CNKeyDescriptor, CNContactFormatter.descriptorForRequiredKeys(for: .fullName)]
    let request = CNContactFetchRequest(keysToFetch: keys)
    var contactsByName = [String: [CNContact]]()

    do {
        try self.contactStore.enumerateContacts(with: request) { contact, stop in
            guard let name = CNContactFormatter.string(from: contact, style: .fullName) else { return }
            contactsByName[name] = (contactsByName[name] ?? []) + [contact]   // or in Swift 4, `contactsByName[name, default: []].append(contact)`

        }
    } catch let err {
        print("error:", err)
    }

    let duplicates = contactsByName.filter { $1.count > 1 }
    let alert = UIAlertController(title: "Alert", message: "Number of duplicates: \(duplicates.count)", preferredStyle: UIAlertControllerStyle.alert)
    alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: {(action:UIAlertAction!) in
        //HERE I WANT TO REMOVE DUPLICATES
        print("you have pressed the ok button")
    }))
    alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.default, handler: nil))
    self.present(alert, animated: true, completion: nil)
    print(duplicates)
    self.tableView.reloadData()

}

Thanks in advance for reply

Fabio
  • 5,432
  • 4
  • 22
  • 24

1 Answers1

2

You should use CNSaveRequest class func delete(_ contact: CNMutableContact) method, executing with func execute(_ saveRequest: CNSaveRequest) method of CNContactStore class

This example removes all other contacts and keeps only one (position 0) but you can add a method to determine which contact is more complete and keep that one

Full Code

alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: {(action:UIAlertAction!) in
            print("you have pressed the ok button")
            var arrayOfContactsRequests : [CNSaveRequest] = []
            for dict in duplicates {
                for (index,contact) in dict.value.enumerated() {
                    if(index != 0) {
                        let saveRequest = CNSaveRequest()
                        saveRequest.delete(contact.mutableCopy() as! CNMutableContact)
                        arrayOfContactsRequests.append(saveRequest)
                    }
                }
            }
            debugPrint(duplicates)
            for request in arrayOfContactsRequests {
                do{
                try self.contactStore.execute(request)
                }
                catch let err {
                    print("error:", err)
                }
            }
        }))

This answer was possible with help of this answer How to convert CNContact to CNMutableContact?

Reinier Melian
  • 20,519
  • 3
  • 38
  • 55
  • 1
    Great! It work perfect!!! Thx @Reinier Melian! Any suggestion to how I can determine wich contact is more complete? Or to merge duplicate? Thx, you’re great! – Fabio Apr 17 '18 at 11:40
  • I think you can check which fields have each contact in order ro determine completeness, @Fabio can you upvote my answer too ;)? – Reinier Melian Apr 17 '18 at 11:43