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
-
Hello!
I'm currently trying to implement a small script to explicitly set/change a single contact's group. I'm not sure how to use the API.
Reading through http://omz-software.com/pythonista/docs/ios/contacts.html, I find ways to get all groups or those specific to a user, but I do not find information on how to set or change a user's group.
Did anyone already successfully implement this functionality?
Kind regards,
Hendrik
-
Python
introspection
to the rescue...import contacts print(dir(contacts.get_all_groups()[-1])) # dir(the last Group in Contacts)
Group has three methods
add_member()
,get_members()
, andremove_member()
. -
Thank you, this is exactly the pointer I need..
-
A quick follow-up question on groups: I try to move a locally created contact to a group that is supposed to reside on a CardDAV-server.
Is there any way to distinguish between the individual accounts the groups belong to? I ask, because I can iterate over my iCloud-stored groups, but the CardDAV-stored group seems to be missing.
I will try and find my way in reverse (find a user, that is stored in the CardDAV-group and inspect the attributes), but maybe there is already some advice on how to speed up my learning here...
-
My Pythonista 3 does not have these methods😥
>>> import contacts >>> p = contacts.find('foo')[0] >>> g = contacts.Group() >>> g.name = 'foobar ' >>> g = contacts.add_group(g) >>> contacts.add_member(p,g) Traceback (most recent call last): File "<string>", line 1, in <module> AttributeError: module 'contacts' has no attribute 'add_member' >>> print(dir(contacts.get_all_groups())[-1])
sort
Where have they gone?
-
@osamu small errors
import contacts p = contacts.find('foo')[0] g = contacts.Group() g.name = 'foobar ' contacts.add_group(g) g.add_member(p) contacts.save()
If after multiple tests, you get multiple groups named "foobar", you can remove them via
import contacts for g in contacts.get_all_groups(): print(g.name) if 'foobar' in g.name: contacts.remove_group(g) contacts.save()
-
I got the point. add_member() is a method of object Group().
Thanks! -
@cvp one more question.
What is the attribute of People() that stores 'date' field? -
@osamu you need to use ObjectiveC to get dates infos, like
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) for contact in predicate_contacts: if len(contact.dates()) == 0: continue name = str(contact.givenName()) + '|' + str(contact.middleName()) + '|' + str(contact.familyName()) print(name) for date in contact.dates(): print(date) # CNLabeledValue d = date.value() print(d) # NSDateComponents print(date.label(),':',d.year(),d.month(),d.day())
-
@cvp Thanks! You know everything!
Oh, that's very challenging... -
@osamu said:
You know everything!
Sincerely, not at all but I'm retired thus I have a lot of time to spend by searching, trying, bugging 😂
-
@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]