Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Contacts API - Group Modification
-
@cvp Could you give me an example to assign values?
-
@osamu said:
Could you give me an example to assign values?
Sorry, I don't understand: assign values to what?
-
Like setting a person's first name, last name, email address, mobile phone number, country, etc?
Reading a value vs. writing a value. -
@osamu thanks @ccc for his help
Here, a sample to create a contact with his photo
# https://forum.omz-software.com/topic/2734/contacts-module-access-profile-picture/4 from objc_util import * import photos # Load classes we need from Contacts.framework: NSBundle.bundleWithPath_('/System/Library/Frameworks/Contacts.framework').load() def main(): CNContactStore = ObjCClass('CNContactStore').alloc().init().autorelease() Containers = CNContactStore.containersMatchingPredicate_error_(None,None) for Container in Containers: containerId = Container.identifier() break # get first container all_assets =photos.get_assets() asset = photos.pick_asset(assets=all_assets) img_data_bytes = asset.get_image_data().getvalue() CNMutableContact = ObjCClass('CNMutableContact').alloc().init() CNMutableContact.firstName = 'aaTest' # just to be the first CNMutableContact.imageData = img_data_bytes #CNMutableContact.phoneNumbers = ['123','456'] print(dir(CNMutableContact)) #return CNSaveRequest = ObjCClass('CNSaveRequest').new().autorelease() CNSaveRequest.addContact_toContainerWithIdentifier_(CNMutableContact, containerId) CNContactStore.executeSaveRequest_error_(CNSaveRequest, None) if __name__ == '__main__': main()
-
@cvp Sorry, I’d like to know how to assign values to ‘date’ field of contact person.
-
You should take a look at the CNMutableContact created here, and you may be able to figure it out.
There should be an attributes
dates
, which according to the objc docs is an array of CNLabeledValue objects, where the value is an NSDate.You can create NSDate using
dateobj=ObjCClass('NSDate').dateWithTimeIntervalSince1970_(time.mktime(time.strptime('2017-06-18', '%Y-%m-%d'))) CNLabeledValue=ObjCClass('CNLabeledValue') value=CNLabeledValue.alloc().init() value.label='birthday' value.value=dateobj Then you ought to be able to use CNMutableContact.dates=[value]
-
As I didn't know which field you want to set, I let a print(dir(CNMutableContact)) in my script, so you could find your-self the name of the field..
But now, as @JonB did the job, all is good so -
@JonB CNLabeledValue has to be initialized differently
CNLabeledValue=ObjCClass('CNLabeledValue') value=CNLabeledValue.alloc() value.initWithLabel_value_('birthday',dateobj)
But date has to be a NSDateComponents
The app was terminated due to an Objective-C exception. Details below: 2021-02-02 23:04:50.219269 Labeled value <CNLabeledValue: 0x283090580: identifier=87E927A0-ED12-4AC9-89A8-EE6CCC75441D, label=birthday, value=2017-06-17 22:00:00 +0000, iOSLegacyIdentifier=-1> value 2017-06-17 22:00:00 +0000 has incorrect type __NSTaggedDate. It should be NSDateComponents.
-
That works
dateComponents = ObjCClass('NSDateComponents').alloc().init() dateComponents.day = 4 dateComponents.month = 5 dateComponents.year = 2017 CNLabeledValue=ObjCClass('CNLabeledValue') value=CNLabeledValue.alloc() value.initWithLabel_value_('birthday',dateComponents) print(dir(CNLabeledValue)) CNMutableContact.dates=[value]
-
-
Now I’m trying to modify and save ‘dates’ field of an existing contact. Though the following script doesn’t spit errors but nothing happens to the contact. Could anybody help?
from objc_util import * # ObjectiveC contacts CNContactStore = ObjCClass('CNContactStore').alloc().init() CNContact = ObjCClass('CNContact') Containers = CNContactStore.containersMatchingPredicate_error_(None,None) for Container in Containers: id = Container.identifier() predicate = CNContact.predicateForContactsInContainerWithIdentifier_(id) # keys not exactly like in Apple doc predicate_contacts = CNContactStore.unifiedContactsMatchingPredicate_keysToFetch_error_(predicate, ['familyName', 'givenName', 'middleName', 'dates'], None) ''' print('First name: ', end='') first_name = input() print('Last name: ', end='') last_name = input() ''' first_name = 'Ludwig' last_name = 'Beethoven' for contact in predicate_contacts: if first_name == str(contact.givenName()) and last_name == str(contact.familyName()): break CNMutableContact = contact.mutableCopy() dateComponents = ObjCClass('NSDateComponents').alloc().init() label = 'passing' dateComponents.day = 26 dateComponents.month = 3 dateComponents.year = 1827 ''' print('Label: ', end='') label = input() print(label.capitalize()+' year: ', end='') dateComponents.year = int(input()) print(label.capitalize()+' month: ', end='') dateComponents.month = int(input()) print(label.capitalize()+' day: ', end='') dateComponents.day = int(input()) ''' CNLabeledValue=ObjCClass('CNLabeledValue') value=CNLabeledValue.alloc() value.initWithLabel_value_(label, dateComponents) CNMutableContact.dates=[value] CNSaveRequest = ObjCClass('CNSaveRequest').new().autorelease() CNSaveRequest.updateContainer_(CNMutableContact) CNContactStore.executeSaveRequest_error_(CNSaveRequest, None) ```
-
@osamu this works
# https://forum.omz-software.com/topic/2734/contacts-module-access-profile-picture/4 from objc_util import * import photos import time # Load classes we need from Contacts.framework: NSBundle.bundleWithPath_('/System/Library/Frameworks/Contacts.framework').load() def main(): CNContactStore = ObjCClass('CNContactStore').alloc().init().autorelease() Containers = CNContactStore.containersMatchingPredicate_error_(None,None) for Container in Containers: containerId = Container.identifier() break # get first container all_assets =photos.get_assets() asset = photos.pick_asset(assets=all_assets) img_data_bytes = asset.get_image_data().getvalue() CNMutableContact = ObjCClass('CNMutableContact').alloc().init() CNMutableContact.firstName = 'aaTest' # just to be the first CNMutableContact.imageData = img_data_bytes #CNMutableContact.phoneNumbers = ['123','456'] #print(dir(CNMutableContact)) #return dateComponents = ObjCClass('NSDateComponents').alloc().init() dateComponents.day = 4 dateComponents.month = 5 dateComponents.year = 2017 CNLabeledValue=ObjCClass('CNLabeledValue') value=CNLabeledValue.alloc() value.initWithLabel_value_('passing',dateComponents) print(dir(CNLabeledValue)) CNMutableContact.dates=[value] CNSaveRequest = ObjCClass('CNSaveRequest').new().autorelease() CNSaveRequest.addContact_toContainerWithIdentifier_(CNMutableContact, containerId) CNContactStore.executeSaveRequest_error_(CNSaveRequest, None) if __name__ == '__main__': main()
-
Wrong: CNSaveRequest.updateContainer_(CNMutableContact)
Correct: CNSaveRequest.updateContact(CNMutableContact)Console:
First name: Ludwig
Last name: Beethoven
Label: passing
Passing year: 1827
Passing month: 3
Passing day: 26Final code:
from objc_util import * # ObjectiveC contacts CNContactStore = ObjCClass('CNContactStore').alloc().init() CNContact = ObjCClass('CNContact') Containers = CNContactStore.containersMatchingPredicate_error_(None,None) for Container in Containers: id = Container.identifier() predicate = CNContact.predicateForContactsInContainerWithIdentifier_(id) # keys not exactly like in Apple doc predicate_contacts = CNContactStore.unifiedContactsMatchingPredicate_keysToFetch_error_(predicate, ['familyName', 'givenName', 'middleName', 'dates'], None) print('First name: ', end='') first_name = input() print('Last name: ', end='') last_name = input() for contact in predicate_contacts: if first_name == str(contact.givenName()) and last_name == str(contact.familyName()): break CNMutableContact = contact.mutableCopy() dateComponents = ObjCClass('NSDateComponents').alloc().init() print('Label: ', end='') label = input() print(label.capitalize()+' year: ', end='') dateComponents.year = int(input()) print(label.capitalize()+' month: ', end='') dateComponents.month = int(input()) print(label.capitalize()+' day: ', end='') dateComponents.day = int(input()) CNLabeledValue=ObjCClass('CNLabeledValue') value=CNLabeledValue.alloc() value.initWithLabel_value_(label, dateComponents) CNMutableContact.dates=[value] CNSaveRequest = ObjCClass('CNSaveRequest').new().autorelease() CNSaveRequest.updateContact(CNMutableContact) CNContactStore.executeSaveRequest_error_(CNSaveRequest, None)
I couldn’t attach the capture 😣
-
@osamu you can also see this
# add a date field with custom label to an existing contact # of course extensible to all fields from objc_util import * def main(): CNContactStore = ObjCClass('CNContactStore').alloc().init().autorelease() # get a particular contact contact_name = 'aaTest' date_label = 'my own label' date_ymd = '20200201' CNContact = ObjCClass('CNContact') predicate = CNContact.predicateForContactsMatchingName_(contact_name) predicate_contacts = CNContactStore.unifiedContactsMatchingPredicate_keysToFetch_error_(predicate, ['dates'], None) for contact in predicate_contacts: # Create a CNMutableContact by copy of an existing contact CNMutableContact = ObjCClass('CNMutableContact').alloc().init() CNMutableContact = contact.mutableCopy() # Create a date NSDateComponents = ObjCClass('NSDateComponents').alloc().init() NSDateComponents.setDay_ (int(date_ymd[6:8])) NSDateComponents.setMonth_(int(date_ymd[4:6])) NSDateComponents.setYear_ (int(date_ymd[0:4])) # create a custom label CNLabeledValue = ObjCClass('CNLabeledValue').alloc() CNLabeledValue.initWithLabel_value_(date_label, NSDateComponents) # create a date with custom label CNMutableContact.setDates_(ns([CNLabeledValue])) # save modified contact CNSaveRequest = ObjCClass('CNSaveRequest').new().autorelease() CNSaveRequest.updateContact_(CNMutableContact) CNContactStore.executeSaveRequest_error_(CNSaveRequest, None) if __name__ == '__main__': main()
-
Got it. For loop was no use.
-
@osamu 👍
-
-
Thanks ❣️🙏
-
@osamu do you have his phone number ? 😂
-
Well, call him up and ask him to write Symphony No.10? 😂