Skip to content

Commit ac7c382

Browse files
authored
Merge pull request #497 from loopandlearn/no-duplicate-contact
Fix issue with duplicate contact
2 parents 08ad867 + 4976582 commit ac7c382

File tree

1 file changed

+41
-13
lines changed

1 file changed

+41
-13
lines changed

LoopFollow/Contact/ContactImageUpdater.swift

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,26 +44,54 @@ class ContactImageUpdater {
4444
continue
4545
}
4646

47-
let predicate = CNContact.predicateForContacts(matchingName: contactName)
48-
let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactImageDataKey] as [CNKeyDescriptor]
49-
5047
do {
51-
let contacts = try self.contactStore.unifiedContacts(matching: predicate, keysToFetch: keysToFetch)
48+
let keysToFetch = [
49+
CNContactIdentifierKey as CNKeyDescriptor,
50+
CNContactGivenNameKey as CNKeyDescriptor,
51+
CNContactImageDataKey as CNKeyDescriptor,
52+
]
53+
54+
var allMatchingContacts: [CNContact] = []
55+
let containers = try self.contactStore.containers(matching: nil)
56+
57+
// Run fast check first
58+
let namePredicate = CNContact.predicateForContacts(matchingName: contactName)
59+
let nameContacts = try self.contactStore.unifiedContacts(matching: namePredicate, keysToFetch: keysToFetch)
60+
let matchingNameContacts = nameContacts.filter { $0.givenName == contactName }
61+
allMatchingContacts.append(contentsOf: matchingNameContacts)
62+
63+
// If it fails, make heavy iteration by containers
64+
if allMatchingContacts.isEmpty {
65+
for container in containers {
66+
let containerPredicate = CNContact.predicateForContactsInContainer(withIdentifier: container.identifier)
67+
let containerContacts = try self.contactStore.unifiedContacts(matching: containerPredicate, keysToFetch: keysToFetch)
68+
let matchingContacts = containerContacts.filter { $0.givenName == contactName }
69+
for contact in matchingContacts {
70+
if !allMatchingContacts.contains(where: { $0.identifier == contact.identifier }) {
71+
allMatchingContacts.append(contact)
72+
}
73+
}
74+
}
75+
}
5276

53-
if let contact = contacts.first, let mutableContact = contact.mutableCopy() as? CNMutableContact {
54-
mutableContact.imageData = imageData
55-
let saveRequest = CNSaveRequest()
56-
saveRequest.update(mutableContact)
57-
try self.contactStore.execute(saveRequest)
58-
print("Contact image updated successfully for \(contactName).")
77+
let saveRequest = CNSaveRequest()
78+
79+
if let existingContact = allMatchingContacts.first {
80+
if let mutableContact = existingContact.mutableCopy() as? CNMutableContact {
81+
mutableContact.imageData = imageData
82+
saveRequest.update(mutableContact)
83+
try self.contactStore.execute(saveRequest)
84+
LogManager.shared.log(category: .contact, message: "Contact image updated successfully for \(contactName).")
85+
}
5986
} else {
87+
// Use default container
88+
let defaultContainer = self.contactStore.defaultContainerIdentifier()
6089
let newContact = CNMutableContact()
6190
newContact.givenName = contactName
6291
newContact.imageData = imageData
63-
let saveRequest = CNSaveRequest()
64-
saveRequest.add(newContact, toContainerWithIdentifier: nil)
92+
saveRequest.add(newContact, toContainerWithIdentifier: defaultContainer)
6593
try self.contactStore.execute(saveRequest)
66-
print("New contact created with updated image for \(contactName).")
94+
LogManager.shared.log(category: .contact, message: "New contact created with updated image for \(contactName).")
6795
}
6896
} catch {
6997
LogManager.shared.log(category: .contact, message: "Failed to update or create contact for \(contactName): \(error)")

0 commit comments

Comments
 (0)