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